Bootstrap version 4

Bootstrap Version 4
This commit is contained in:
Francesco Malagrino
2018-02-06 19:17:39 +00:00
parent 88a1e61560
commit f1fdc89d7d
4696 changed files with 309296 additions and 0 deletions
+217
View File
@@ -0,0 +1,217 @@
/* FileSaver.js
* A saveAs() FileSaver implementation.
* 2013-01-23
*
* By Eli Grey, http://eligrey.com
* License: X11/MIT
* See LICENSE.md
*/
/*global self */
/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
plusplus: true */
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
var saveAs = saveAs
|| (navigator.msSaveBlob && navigator.msSaveBlob.bind(navigator))
|| (function(view) {
"use strict";
var
doc = view.document
// only get URL when necessary in case BlobBuilder.js hasn't overridden it yet
, get_URL = function() {
return view.URL || view.webkitURL || view;
}
, URL = view.URL || view.webkitURL || view
, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
, can_use_save_link = "download" in save_link
, click = function(node) {
var event = doc.createEvent("MouseEvents");
event.initMouseEvent(
"click", true, false, view, 0, 0, 0, 0, 0
, false, false, false, false, 0, null
);
node.dispatchEvent(event);
}
, webkit_req_fs = view.webkitRequestFileSystem
, req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem
, throw_outside = function (ex) {
(view.setImmediate || view.setTimeout)(function() {
throw ex;
}, 0);
}
, force_saveable_type = "application/octet-stream"
, fs_min_size = 0
, deletion_queue = []
, process_deletion_queue = function() {
var i = deletion_queue.length;
while (i--) {
var file = deletion_queue[i];
if (typeof file === "string") { // file is an object URL
URL.revokeObjectURL(file);
} else { // file is a File
file.remove();
}
}
deletion_queue.length = 0; // clear queue
}
, dispatch = function(filesaver, event_types, event) {
event_types = [].concat(event_types);
var i = event_types.length;
while (i--) {
var listener = filesaver["on" + event_types[i]];
if (typeof listener === "function") {
try {
listener.call(filesaver, event || filesaver);
} catch (ex) {
throw_outside(ex);
}
}
}
}
, FileSaver = function(blob, name) {
// First try a.download, then web filesystem, then object URLs
var
filesaver = this
, type = blob.type
, blob_changed = false
, object_url
, target_view
, get_object_url = function() {
var object_url = get_URL().createObjectURL(blob);
deletion_queue.push(object_url);
return object_url;
}
, dispatch_all = function() {
dispatch(filesaver, "writestart progress write writeend".split(" "));
}
// on any filesys errors revert to saving with object URLs
, fs_error = function() {
// don't create more object URLs than needed
if (blob_changed || !object_url) {
object_url = get_object_url(blob);
}
if (target_view) {
target_view.location.href = object_url;
}
filesaver.readyState = filesaver.DONE;
dispatch_all();
}
, abortable = function(func) {
return function() {
if (filesaver.readyState !== filesaver.DONE) {
return func.apply(this, arguments);
}
};
}
, create_if_not_found = {create: true, exclusive: false}
, slice
;
filesaver.readyState = filesaver.INIT;
if (!name) {
name = "download";
}
if (can_use_save_link) {
object_url = get_object_url(blob);
save_link.href = object_url;
save_link.download = name;
click(save_link);
filesaver.readyState = filesaver.DONE;
dispatch_all();
return;
}
// Object and web filesystem URLs have a problem saving in Google Chrome when
// viewed in a tab, so I force save with application/octet-stream
// http://code.google.com/p/chromium/issues/detail?id=91158
if (view.chrome && type && type !== force_saveable_type) {
slice = blob.slice || blob.webkitSlice;
blob = slice.call(blob, 0, blob.size, force_saveable_type);
blob_changed = true;
}
// Since I can't be sure that the guessed media type will trigger a download
// in WebKit, I append .download to the filename.
// https://bugs.webkit.org/show_bug.cgi?id=65440
if (webkit_req_fs && name !== "download") {
name += ".download";
}
if (type === force_saveable_type || webkit_req_fs) {
target_view = view;
} else {
target_view = view.open();
}
if (!req_fs) {
fs_error();
return;
}
fs_min_size += blob.size;
req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) {
fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) {
var save = function() {
dir.getFile(name, create_if_not_found, abortable(function(file) {
file.createWriter(abortable(function(writer) {
writer.onwriteend = function(event) {
target_view.location.href = file.toURL();
deletion_queue.push(file);
filesaver.readyState = filesaver.DONE;
dispatch(filesaver, "writeend", event);
};
writer.onerror = function() {
var error = writer.error;
if (error.code !== error.ABORT_ERR) {
fs_error();
}
};
"writestart progress write abort".split(" ").forEach(function(event) {
writer["on" + event] = filesaver["on" + event];
});
writer.write(blob);
filesaver.abort = function() {
writer.abort();
filesaver.readyState = filesaver.DONE;
};
filesaver.readyState = filesaver.WRITING;
}), fs_error);
}), fs_error);
};
dir.getFile(name, {create: false}, abortable(function(file) {
// delete file if it already exists
file.remove();
save();
}), abortable(function(ex) {
if (ex.code === ex.NOT_FOUND_ERR) {
save();
} else {
fs_error();
}
}));
}), fs_error);
}), fs_error);
}
, FS_proto = FileSaver.prototype
, saveAs = function(blob, name) {
return new FileSaver(blob, name);
}
;
FS_proto.abort = function() {
var filesaver = this;
filesaver.readyState = filesaver.DONE;
dispatch(filesaver, "abort");
};
FS_proto.readyState = FS_proto.INIT = 0;
FS_proto.WRITING = 1;
FS_proto.DONE = 2;
FS_proto.error =
FS_proto.onwritestart =
FS_proto.onprogress =
FS_proto.onwrite =
FS_proto.onabort =
FS_proto.onerror =
FS_proto.onwriteend =
null;
view.addEventListener("unload", process_deletion_queue, false);
return saveAs;
}(self));
Executable
+181
View File
@@ -0,0 +1,181 @@
import $ from 'jquery'
import Util from './util'
/**
* --------------------------------------------------------------------------
* Bootstrap (v4.0.0): alert.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* --------------------------------------------------------------------------
*/
const Alert = (($) => {
/**
* ------------------------------------------------------------------------
* Constants
* ------------------------------------------------------------------------
*/
const NAME = 'alert'
const VERSION = '4.0.0'
const DATA_KEY = 'bs.alert'
const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
const JQUERY_NO_CONFLICT = $.fn[NAME]
const TRANSITION_DURATION = 150
const Selector = {
DISMISS : '[data-dismiss="alert"]'
}
const Event = {
CLOSE : `close${EVENT_KEY}`,
CLOSED : `closed${EVENT_KEY}`,
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
}
const ClassName = {
ALERT : 'alert',
FADE : 'fade',
SHOW : 'show'
}
/**
* ------------------------------------------------------------------------
* Class Definition
* ------------------------------------------------------------------------
*/
class Alert {
constructor(element) {
this._element = element
}
// Getters
static get VERSION() {
return VERSION
}
// Public
close(element) {
element = element || this._element
const rootElement = this._getRootElement(element)
const customEvent = this._triggerCloseEvent(rootElement)
if (customEvent.isDefaultPrevented()) {
return
}
this._removeElement(rootElement)
}
dispose() {
$.removeData(this._element, DATA_KEY)
this._element = null
}
// Private
_getRootElement(element) {
const selector = Util.getSelectorFromElement(element)
let parent = false
if (selector) {
parent = $(selector)[0]
}
if (!parent) {
parent = $(element).closest(`.${ClassName.ALERT}`)[0]
}
return parent
}
_triggerCloseEvent(element) {
const closeEvent = $.Event(Event.CLOSE)
$(element).trigger(closeEvent)
return closeEvent
}
_removeElement(element) {
$(element).removeClass(ClassName.SHOW)
if (!Util.supportsTransitionEnd() ||
!$(element).hasClass(ClassName.FADE)) {
this._destroyElement(element)
return
}
$(element)
.one(Util.TRANSITION_END, (event) => this._destroyElement(element, event))
.emulateTransitionEnd(TRANSITION_DURATION)
}
_destroyElement(element) {
$(element)
.detach()
.trigger(Event.CLOSED)
.remove()
}
// Static
static _jQueryInterface(config) {
return this.each(function () {
const $element = $(this)
let data = $element.data(DATA_KEY)
if (!data) {
data = new Alert(this)
$element.data(DATA_KEY, data)
}
if (config === 'close') {
data[config](this)
}
})
}
static _handleDismiss(alertInstance) {
return function (event) {
if (event) {
event.preventDefault()
}
alertInstance.close(this)
}
}
}
/**
* ------------------------------------------------------------------------
* Data Api implementation
* ------------------------------------------------------------------------
*/
$(document).on(
Event.CLICK_DATA_API,
Selector.DISMISS,
Alert._handleDismiss(new Alert())
)
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
*/
$.fn[NAME] = Alert._jQueryInterface
$.fn[NAME].Constructor = Alert
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Alert._jQueryInterface
}
return Alert
})($)
export default Alert
Executable
+179
View File
@@ -0,0 +1,179 @@
/* Blob.js
* A Blob implementation.
* 2013-06-20
*
* By Eli Grey, http://eligrey.com
* By Devin Samarin, https://github.com/eboyjr
* License: X11/MIT
* See LICENSE.md
*/
/*global self, unescape */
/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
plusplus: true */
/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
if (typeof Blob !== "function" || typeof URL === "undefined")
if (typeof Blob === "function" && typeof webkitURL !== "undefined") var URL = webkitURL;
else var Blob = (function (view) {
"use strict";
var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || view.MSBlobBuilder || (function(view) {
var
get_class = function(object) {
return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
}
, FakeBlobBuilder = function BlobBuilder() {
this.data = [];
}
, FakeBlob = function Blob(data, type, encoding) {
this.data = data;
this.size = data.length;
this.type = type;
this.encoding = encoding;
}
, FBB_proto = FakeBlobBuilder.prototype
, FB_proto = FakeBlob.prototype
, FileReaderSync = view.FileReaderSync
, FileException = function(type) {
this.code = this[this.name = type];
}
, file_ex_codes = (
"NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "
+ "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
).split(" ")
, file_ex_code = file_ex_codes.length
, real_URL = view.URL || view.webkitURL || view
, real_create_object_URL = real_URL.createObjectURL
, real_revoke_object_URL = real_URL.revokeObjectURL
, URL = real_URL
, btoa = view.btoa
, atob = view.atob
, can_apply_typed_arrays = false
, can_apply_typed_arrays_test = function(pass) {
can_apply_typed_arrays = !pass;
}
, ArrayBuffer = view.ArrayBuffer
, Uint8Array = view.Uint8Array
;
FakeBlob.fake = FB_proto.fake = true;
while (file_ex_code--) {
FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
}
try {
if (Uint8Array) {
can_apply_typed_arrays_test.apply(0, new Uint8Array(1));
}
} catch (ex) {}
if (!real_URL.createObjectURL) {
URL = view.URL = {};
}
URL.createObjectURL = function(blob) {
var
type = blob.type
, data_URI_header
;
if (type === null) {
type = "application/octet-stream";
}
if (blob instanceof FakeBlob) {
data_URI_header = "data:" + type;
if (blob.encoding === "base64") {
return data_URI_header + ";base64," + blob.data;
} else if (blob.encoding === "URI") {
return data_URI_header + "," + decodeURIComponent(blob.data);
} if (btoa) {
return data_URI_header + ";base64," + btoa(blob.data);
} else {
return data_URI_header + "," + encodeURIComponent(blob.data);
}
} else if (real_create_object_URL) {
return real_create_object_URL.call(real_URL, blob);
}
};
URL.revokeObjectURL = function(object_URL) {
if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
real_revoke_object_URL.call(real_URL, object_URL);
}
};
FBB_proto.append = function(data/*, endings*/) {
var bb = this.data;
// decode data to a binary string
if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
if (can_apply_typed_arrays) {
bb.push(String.fromCharCode.apply(String, new Uint8Array(data)));
} else {
var
str = ""
, buf = new Uint8Array(data)
, i = 0
, buf_len = buf.length
;
for (; i < buf_len; i++) {
str += String.fromCharCode(buf[i]);
}
}
} else if (get_class(data) === "Blob" || get_class(data) === "File") {
if (FileReaderSync) {
var fr = new FileReaderSync;
bb.push(fr.readAsBinaryString(data));
} else {
// async FileReader won't work as BlobBuilder is sync
throw new FileException("NOT_READABLE_ERR");
}
} else if (data instanceof FakeBlob) {
if (data.encoding === "base64" && atob) {
bb.push(atob(data.data));
} else if (data.encoding === "URI") {
bb.push(decodeURIComponent(data.data));
} else if (data.encoding === "raw") {
bb.push(data.data);
}
} else {
if (typeof data !== "string") {
data += ""; // convert unsupported types to strings
}
// decode UTF-16 to binary string
bb.push(unescape(encodeURIComponent(data)));
}
};
FBB_proto.getBlob = function(type) {
if (!arguments.length) {
type = null;
}
return new FakeBlob(this.data.join(""), type, "raw");
};
FBB_proto.toString = function() {
return "[object BlobBuilder]";
};
FB_proto.slice = function(start, end, type) {
var args = arguments.length;
if (args < 3) {
type = null;
}
return new FakeBlob(
this.data.slice(start, args > 1 ? end : this.data.length)
, type
, this.encoding
);
};
FB_proto.toString = function() {
return "[object Blob]";
};
return FakeBlobBuilder;
}(view));
return function Blob(blobParts, options) {
var type = options ? (options.type || "") : "";
var builder = new BlobBuilder();
if (blobParts) {
for (var i = 0, len = blobParts.length; i < len; i++) {
builder.append(blobParts[i]);
}
}
return builder.getBlob(type);
};
}(self));
+6328
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+7
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+3894
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+7
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Executable
+175
View File
@@ -0,0 +1,175 @@
import $ from 'jquery'
/**
* --------------------------------------------------------------------------
* Bootstrap (v4.0.0): button.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* --------------------------------------------------------------------------
*/
const Button = (($) => {
/**
* ------------------------------------------------------------------------
* Constants
* ------------------------------------------------------------------------
*/
const NAME = 'button'
const VERSION = '4.0.0'
const DATA_KEY = 'bs.button'
const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
const JQUERY_NO_CONFLICT = $.fn[NAME]
const ClassName = {
ACTIVE : 'active',
BUTTON : 'btn',
FOCUS : 'focus'
}
const Selector = {
DATA_TOGGLE_CARROT : '[data-toggle^="button"]',
DATA_TOGGLE : '[data-toggle="buttons"]',
INPUT : 'input',
ACTIVE : '.active',
BUTTON : '.btn'
}
const Event = {
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`,
FOCUS_BLUR_DATA_API : `focus${EVENT_KEY}${DATA_API_KEY} ` +
`blur${EVENT_KEY}${DATA_API_KEY}`
}
/**
* ------------------------------------------------------------------------
* Class Definition
* ------------------------------------------------------------------------
*/
class Button {
constructor(element) {
this._element = element
}
// Getters
static get VERSION() {
return VERSION
}
// Public
toggle() {
let triggerChangeEvent = true
let addAriaPressed = true
const rootElement = $(this._element).closest(
Selector.DATA_TOGGLE
)[0]
if (rootElement) {
const input = $(this._element).find(Selector.INPUT)[0]
if (input) {
if (input.type === 'radio') {
if (input.checked &&
$(this._element).hasClass(ClassName.ACTIVE)) {
triggerChangeEvent = false
} else {
const activeElement = $(rootElement).find(Selector.ACTIVE)[0]
if (activeElement) {
$(activeElement).removeClass(ClassName.ACTIVE)
}
}
}
if (triggerChangeEvent) {
if (input.hasAttribute('disabled') ||
rootElement.hasAttribute('disabled') ||
input.classList.contains('disabled') ||
rootElement.classList.contains('disabled')) {
return
}
input.checked = !$(this._element).hasClass(ClassName.ACTIVE)
$(input).trigger('change')
}
input.focus()
addAriaPressed = false
}
}
if (addAriaPressed) {
this._element.setAttribute('aria-pressed',
!$(this._element).hasClass(ClassName.ACTIVE))
}
if (triggerChangeEvent) {
$(this._element).toggleClass(ClassName.ACTIVE)
}
}
dispose() {
$.removeData(this._element, DATA_KEY)
this._element = null
}
// Static
static _jQueryInterface(config) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
if (!data) {
data = new Button(this)
$(this).data(DATA_KEY, data)
}
if (config === 'toggle') {
data[config]()
}
})
}
}
/**
* ------------------------------------------------------------------------
* Data Api implementation
* ------------------------------------------------------------------------
*/
$(document)
.on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {
event.preventDefault()
let button = event.target
if (!$(button).hasClass(ClassName.BUTTON)) {
button = $(button).closest(Selector.BUTTON)
}
Button._jQueryInterface.call($(button), 'toggle')
})
.on(Event.FOCUS_BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {
const button = $(event.target).closest(Selector.BUTTON)[0]
$(button).toggleClass(ClassName.FOCUS, /^focus(in)?$/.test(event.type))
})
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
*/
$.fn[NAME] = Button._jQueryInterface
$.fn[NAME].Constructor = Button
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Button._jQueryInterface
}
return Button
})($)
export default Button
+108
View File
@@ -0,0 +1,108 @@
/* canvas-toBlob.js
* A canvas.toBlob() implementation.
* 2011-07-13
*
* By Eli Grey, http://eligrey.com and Devin Samarin, https://github.com/eboyjr
* License: X11/MIT
* See LICENSE.md
*/
/*global self */
/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
plusplus: true */
/*! @source http://purl.eligrey.com/github/canvas-toBlob.js/blob/master/canvas-toBlob.js */
(function(view) {
"use strict";
var
Uint8Array = view.Uint8Array
, HTMLCanvasElement = view.HTMLCanvasElement
, is_base64_regex = /\s*;\s*base64\s*(?:;|$)/i
, base64_ranks
, decode_base64 = function(base64) {
var
len = base64.length
, buffer = new Uint8Array(len / 4 * 3 | 0)
, i = 0
, outptr = 0
, last = [0, 0]
, state = 0
, save = 0
, rank
, code
, undef
;
while (len--) {
code = base64.charCodeAt(i++);
rank = base64_ranks[code-43];
if (rank !== 255 && rank !== undef) {
last[1] = last[0];
last[0] = code;
save = (save << 6) | rank;
state++;
if (state === 4) {
buffer[outptr++] = save >>> 16;
if (last[1] !== 61 /* padding character */) {
buffer[outptr++] = save >>> 8;
}
if (last[0] !== 61 /* padding character */) {
buffer[outptr++] = save;
}
state = 0;
}
}
}
// 2/3 chance there's going to be some null bytes at the end, but that
// doesn't really matter with most image formats.
// If it somehow matters for you, truncate the buffer up outptr.
return buffer.buffer;
}
;
if (Uint8Array) {
base64_ranks = new Uint8Array([
62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1
, -1, -1, 0, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25
, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35
, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
]);
}
if (HTMLCanvasElement && !HTMLCanvasElement.prototype.toBlob) {
HTMLCanvasElement.prototype.toBlob = function(callback, type /*, ...args*/) {
if (!type) {
type = "image/png";
} if (this.mozGetAsFile) {
callback(this.mozGetAsFile("canvas", type));
return;
}
var
args = Array.prototype.slice.call(arguments, 1)
, dataURI = this.toDataURL.apply(this, args)
, header_end = dataURI.indexOf(",")
, data = dataURI.substring(header_end + 1)
, is_base64 = is_base64_regex.test(dataURI.substring(0, header_end))
, blob
;
if (Blob.fake) {
// no reason to decode a data: URI that's just going to become a data URI again
blob = new Blob
if (is_base64) {
blob.encoding = "base64";
} else {
blob.encoding = "URI";
}
blob.data = data;
blob.size = data.length;
} else if (Uint8Array) {
if (is_base64) {
blob = new Blob([decode_base64(data)], {type: type});
} else {
blob = new Blob([decodeURIComponent(data)], {type: type});
}
}
callback(blob);
};
}
}(self));
+518
View File
@@ -0,0 +1,518 @@
import $ from 'jquery'
import Util from './util'
/**
* --------------------------------------------------------------------------
* Bootstrap (v4.0.0): carousel.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* --------------------------------------------------------------------------
*/
const Carousel = (($) => {
/**
* ------------------------------------------------------------------------
* Constants
* ------------------------------------------------------------------------
*/
const NAME = 'carousel'
const VERSION = '4.0.0'
const DATA_KEY = 'bs.carousel'
const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
const JQUERY_NO_CONFLICT = $.fn[NAME]
const TRANSITION_DURATION = 600
const ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key
const ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key
const TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch
const Default = {
interval : 5000,
keyboard : true,
slide : false,
pause : 'hover',
wrap : true
}
const DefaultType = {
interval : '(number|boolean)',
keyboard : 'boolean',
slide : '(boolean|string)',
pause : '(string|boolean)',
wrap : 'boolean'
}
const Direction = {
NEXT : 'next',
PREV : 'prev',
LEFT : 'left',
RIGHT : 'right'
}
const Event = {
SLIDE : `slide${EVENT_KEY}`,
SLID : `slid${EVENT_KEY}`,
KEYDOWN : `keydown${EVENT_KEY}`,
MOUSEENTER : `mouseenter${EVENT_KEY}`,
MOUSELEAVE : `mouseleave${EVENT_KEY}`,
TOUCHEND : `touchend${EVENT_KEY}`,
LOAD_DATA_API : `load${EVENT_KEY}${DATA_API_KEY}`,
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
}
const ClassName = {
CAROUSEL : 'carousel',
ACTIVE : 'active',
SLIDE : 'slide',
RIGHT : 'carousel-item-right',
LEFT : 'carousel-item-left',
NEXT : 'carousel-item-next',
PREV : 'carousel-item-prev',
ITEM : 'carousel-item'
}
const Selector = {
ACTIVE : '.active',
ACTIVE_ITEM : '.active.carousel-item',
ITEM : '.carousel-item',
NEXT_PREV : '.carousel-item-next, .carousel-item-prev',
INDICATORS : '.carousel-indicators',
DATA_SLIDE : '[data-slide], [data-slide-to]',
DATA_RIDE : '[data-ride="carousel"]'
}
/**
* ------------------------------------------------------------------------
* Class Definition
* ------------------------------------------------------------------------
*/
class Carousel {
constructor(element, config) {
this._items = null
this._interval = null
this._activeElement = null
this._isPaused = false
this._isSliding = false
this.touchTimeout = null
this._config = this._getConfig(config)
this._element = $(element)[0]
this._indicatorsElement = $(this._element).find(Selector.INDICATORS)[0]
this._addEventListeners()
}
// Getters
static get VERSION() {
return VERSION
}
static get Default() {
return Default
}
// Public
next() {
if (!this._isSliding) {
this._slide(Direction.NEXT)
}
}
nextWhenVisible() {
// Don't call next when the page isn't visible
// or the carousel or its parent isn't visible
if (!document.hidden &&
($(this._element).is(':visible') && $(this._element).css('visibility') !== 'hidden')) {
this.next()
}
}
prev() {
if (!this._isSliding) {
this._slide(Direction.PREV)
}
}
pause(event) {
if (!event) {
this._isPaused = true
}
if ($(this._element).find(Selector.NEXT_PREV)[0] &&
Util.supportsTransitionEnd()) {
Util.triggerTransitionEnd(this._element)
this.cycle(true)
}
clearInterval(this._interval)
this._interval = null
}
cycle(event) {
if (!event) {
this._isPaused = false
}
if (this._interval) {
clearInterval(this._interval)
this._interval = null
}
if (this._config.interval && !this._isPaused) {
this._interval = setInterval(
(document.visibilityState ? this.nextWhenVisible : this.next).bind(this),
this._config.interval
)
}
}
to(index) {
this._activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0]
const activeIndex = this._getItemIndex(this._activeElement)
if (index > this._items.length - 1 || index < 0) {
return
}
if (this._isSliding) {
$(this._element).one(Event.SLID, () => this.to(index))
return
}
if (activeIndex === index) {
this.pause()
this.cycle()
return
}
const direction = index > activeIndex
? Direction.NEXT
: Direction.PREV
this._slide(direction, this._items[index])
}
dispose() {
$(this._element).off(EVENT_KEY)
$.removeData(this._element, DATA_KEY)
this._items = null
this._config = null
this._element = null
this._interval = null
this._isPaused = null
this._isSliding = null
this._activeElement = null
this._indicatorsElement = null
}
// Private
_getConfig(config) {
config = {
...Default,
...config
}
Util.typeCheckConfig(NAME, config, DefaultType)
return config
}
_addEventListeners() {
if (this._config.keyboard) {
$(this._element)
.on(Event.KEYDOWN, (event) => this._keydown(event))
}
if (this._config.pause === 'hover') {
$(this._element)
.on(Event.MOUSEENTER, (event) => this.pause(event))
.on(Event.MOUSELEAVE, (event) => this.cycle(event))
if ('ontouchstart' in document.documentElement) {
// If it's a touch-enabled device, mouseenter/leave are fired as
// part of the mouse compatibility events on first tap - the carousel
// would stop cycling until user tapped out of it;
// here, we listen for touchend, explicitly pause the carousel
// (as if it's the second time we tap on it, mouseenter compat event
// is NOT fired) and after a timeout (to allow for mouse compatibility
// events to fire) we explicitly restart cycling
$(this._element).on(Event.TOUCHEND, () => {
this.pause()
if (this.touchTimeout) {
clearTimeout(this.touchTimeout)
}
this.touchTimeout = setTimeout((event) => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval)
})
}
}
}
_keydown(event) {
if (/input|textarea/i.test(event.target.tagName)) {
return
}
switch (event.which) {
case ARROW_LEFT_KEYCODE:
event.preventDefault()
this.prev()
break
case ARROW_RIGHT_KEYCODE:
event.preventDefault()
this.next()
break
default:
}
}
_getItemIndex(element) {
this._items = $.makeArray($(element).parent().find(Selector.ITEM))
return this._items.indexOf(element)
}
_getItemByDirection(direction, activeElement) {
const isNextDirection = direction === Direction.NEXT
const isPrevDirection = direction === Direction.PREV
const activeIndex = this._getItemIndex(activeElement)
const lastItemIndex = this._items.length - 1
const isGoingToWrap = isPrevDirection && activeIndex === 0 ||
isNextDirection && activeIndex === lastItemIndex
if (isGoingToWrap && !this._config.wrap) {
return activeElement
}
const delta = direction === Direction.PREV ? -1 : 1
const itemIndex = (activeIndex + delta) % this._items.length
return itemIndex === -1
? this._items[this._items.length - 1] : this._items[itemIndex]
}
_triggerSlideEvent(relatedTarget, eventDirectionName) {
const targetIndex = this._getItemIndex(relatedTarget)
const fromIndex = this._getItemIndex($(this._element).find(Selector.ACTIVE_ITEM)[0])
const slideEvent = $.Event(Event.SLIDE, {
relatedTarget,
direction: eventDirectionName,
from: fromIndex,
to: targetIndex
})
$(this._element).trigger(slideEvent)
return slideEvent
}
_setActiveIndicatorElement(element) {
if (this._indicatorsElement) {
$(this._indicatorsElement)
.find(Selector.ACTIVE)
.removeClass(ClassName.ACTIVE)
const nextIndicator = this._indicatorsElement.children[
this._getItemIndex(element)
]
if (nextIndicator) {
$(nextIndicator).addClass(ClassName.ACTIVE)
}
}
}
_slide(direction, element) {
const activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0]
const activeElementIndex = this._getItemIndex(activeElement)
const nextElement = element || activeElement &&
this._getItemByDirection(direction, activeElement)
const nextElementIndex = this._getItemIndex(nextElement)
const isCycling = Boolean(this._interval)
let directionalClassName
let orderClassName
let eventDirectionName
if (direction === Direction.NEXT) {
directionalClassName = ClassName.LEFT
orderClassName = ClassName.NEXT
eventDirectionName = Direction.LEFT
} else {
directionalClassName = ClassName.RIGHT
orderClassName = ClassName.PREV
eventDirectionName = Direction.RIGHT
}
if (nextElement && $(nextElement).hasClass(ClassName.ACTIVE)) {
this._isSliding = false
return
}
const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName)
if (slideEvent.isDefaultPrevented()) {
return
}
if (!activeElement || !nextElement) {
// Some weirdness is happening, so we bail
return
}
this._isSliding = true
if (isCycling) {
this.pause()
}
this._setActiveIndicatorElement(nextElement)
const slidEvent = $.Event(Event.SLID, {
relatedTarget: nextElement,
direction: eventDirectionName,
from: activeElementIndex,
to: nextElementIndex
})
if (Util.supportsTransitionEnd() &&
$(this._element).hasClass(ClassName.SLIDE)) {
$(nextElement).addClass(orderClassName)
Util.reflow(nextElement)
$(activeElement).addClass(directionalClassName)
$(nextElement).addClass(directionalClassName)
$(activeElement)
.one(Util.TRANSITION_END, () => {
$(nextElement)
.removeClass(`${directionalClassName} ${orderClassName}`)
.addClass(ClassName.ACTIVE)
$(activeElement).removeClass(`${ClassName.ACTIVE} ${orderClassName} ${directionalClassName}`)
this._isSliding = false
setTimeout(() => $(this._element).trigger(slidEvent), 0)
})
.emulateTransitionEnd(TRANSITION_DURATION)
} else {
$(activeElement).removeClass(ClassName.ACTIVE)
$(nextElement).addClass(ClassName.ACTIVE)
this._isSliding = false
$(this._element).trigger(slidEvent)
}
if (isCycling) {
this.cycle()
}
}
// Static
static _jQueryInterface(config) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
let _config = {
...Default,
...$(this).data()
}
if (typeof config === 'object') {
_config = {
..._config,
...config
}
}
const action = typeof config === 'string' ? config : _config.slide
if (!data) {
data = new Carousel(this, _config)
$(this).data(DATA_KEY, data)
}
if (typeof config === 'number') {
data.to(config)
} else if (typeof action === 'string') {
if (typeof data[action] === 'undefined') {
throw new TypeError(`No method named "${action}"`)
}
data[action]()
} else if (_config.interval) {
data.pause()
data.cycle()
}
})
}
static _dataApiClickHandler(event) {
const selector = Util.getSelectorFromElement(this)
if (!selector) {
return
}
const target = $(selector)[0]
if (!target || !$(target).hasClass(ClassName.CAROUSEL)) {
return
}
const config = {
...$(target).data(),
...$(this).data()
}
const slideIndex = this.getAttribute('data-slide-to')
if (slideIndex) {
config.interval = false
}
Carousel._jQueryInterface.call($(target), config)
if (slideIndex) {
$(target).data(DATA_KEY).to(slideIndex)
}
event.preventDefault()
}
}
/**
* ------------------------------------------------------------------------
* Data Api implementation
* ------------------------------------------------------------------------
*/
$(document)
.on(Event.CLICK_DATA_API, Selector.DATA_SLIDE, Carousel._dataApiClickHandler)
$(window).on(Event.LOAD_DATA_API, () => {
$(Selector.DATA_RIDE).each(function () {
const $carousel = $(this)
Carousel._jQueryInterface.call($carousel, $carousel.data())
})
})
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
*/
$.fn[NAME] = Carousel._jQueryInterface
$.fn[NAME].Constructor = Carousel
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Carousel._jQueryInterface
}
return Carousel
})($)
export default Carousel
+403
View File
@@ -0,0 +1,403 @@
import $ from 'jquery'
import Util from './util'
/**
* --------------------------------------------------------------------------
* Bootstrap (v4.0.0): collapse.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* --------------------------------------------------------------------------
*/
const Collapse = (($) => {
/**
* ------------------------------------------------------------------------
* Constants
* ------------------------------------------------------------------------
*/
const NAME = 'collapse'
const VERSION = '4.0.0'
const DATA_KEY = 'bs.collapse'
const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
const JQUERY_NO_CONFLICT = $.fn[NAME]
const TRANSITION_DURATION = 600
const Default = {
toggle : true,
parent : ''
}
const DefaultType = {
toggle : 'boolean',
parent : '(string|element)'
}
const Event = {
SHOW : `show${EVENT_KEY}`,
SHOWN : `shown${EVENT_KEY}`,
HIDE : `hide${EVENT_KEY}`,
HIDDEN : `hidden${EVENT_KEY}`,
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
}
const ClassName = {
SHOW : 'show',
COLLAPSE : 'collapse',
COLLAPSING : 'collapsing',
COLLAPSED : 'collapsed'
}
const Dimension = {
WIDTH : 'width',
HEIGHT : 'height'
}
const Selector = {
ACTIVES : '.show, .collapsing',
DATA_TOGGLE : '[data-toggle="collapse"]'
}
/**
* ------------------------------------------------------------------------
* Class Definition
* ------------------------------------------------------------------------
*/
class Collapse {
constructor(element, config) {
this._isTransitioning = false
this._element = element
this._config = this._getConfig(config)
this._triggerArray = $.makeArray($(
`[data-toggle="collapse"][href="#${element.id}"],` +
`[data-toggle="collapse"][data-target="#${element.id}"]`
))
const tabToggles = $(Selector.DATA_TOGGLE)
for (let i = 0; i < tabToggles.length; i++) {
const elem = tabToggles[i]
const selector = Util.getSelectorFromElement(elem)
if (selector !== null && $(selector).filter(element).length > 0) {
this._selector = selector
this._triggerArray.push(elem)
}
}
this._parent = this._config.parent ? this._getParent() : null
if (!this._config.parent) {
this._addAriaAndCollapsedClass(this._element, this._triggerArray)
}
if (this._config.toggle) {
this.toggle()
}
}
// Getters
static get VERSION() {
return VERSION
}
static get Default() {
return Default
}
// Public
toggle() {
if ($(this._element).hasClass(ClassName.SHOW)) {
this.hide()
} else {
this.show()
}
}
show() {
if (this._isTransitioning ||
$(this._element).hasClass(ClassName.SHOW)) {
return
}
let actives
let activesData
if (this._parent) {
actives = $.makeArray(
$(this._parent)
.find(Selector.ACTIVES)
.filter(`[data-parent="${this._config.parent}"]`)
)
if (actives.length === 0) {
actives = null
}
}
if (actives) {
activesData = $(actives).not(this._selector).data(DATA_KEY)
if (activesData && activesData._isTransitioning) {
return
}
}
const startEvent = $.Event(Event.SHOW)
$(this._element).trigger(startEvent)
if (startEvent.isDefaultPrevented()) {
return
}
if (actives) {
Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide')
if (!activesData) {
$(actives).data(DATA_KEY, null)
}
}
const dimension = this._getDimension()
$(this._element)
.removeClass(ClassName.COLLAPSE)
.addClass(ClassName.COLLAPSING)
this._element.style[dimension] = 0
if (this._triggerArray.length > 0) {
$(this._triggerArray)
.removeClass(ClassName.COLLAPSED)
.attr('aria-expanded', true)
}
this.setTransitioning(true)
const complete = () => {
$(this._element)
.removeClass(ClassName.COLLAPSING)
.addClass(ClassName.COLLAPSE)
.addClass(ClassName.SHOW)
this._element.style[dimension] = ''
this.setTransitioning(false)
$(this._element).trigger(Event.SHOWN)
}
if (!Util.supportsTransitionEnd()) {
complete()
return
}
const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)
const scrollSize = `scroll${capitalizedDimension}`
$(this._element)
.one(Util.TRANSITION_END, complete)
.emulateTransitionEnd(TRANSITION_DURATION)
this._element.style[dimension] = `${this._element[scrollSize]}px`
}
hide() {
if (this._isTransitioning ||
!$(this._element).hasClass(ClassName.SHOW)) {
return
}
const startEvent = $.Event(Event.HIDE)
$(this._element).trigger(startEvent)
if (startEvent.isDefaultPrevented()) {
return
}
const dimension = this._getDimension()
this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`
Util.reflow(this._element)
$(this._element)
.addClass(ClassName.COLLAPSING)
.removeClass(ClassName.COLLAPSE)
.removeClass(ClassName.SHOW)
if (this._triggerArray.length > 0) {
for (let i = 0; i < this._triggerArray.length; i++) {
const trigger = this._triggerArray[i]
const selector = Util.getSelectorFromElement(trigger)
if (selector !== null) {
const $elem = $(selector)
if (!$elem.hasClass(ClassName.SHOW)) {
$(trigger).addClass(ClassName.COLLAPSED)
.attr('aria-expanded', false)
}
}
}
}
this.setTransitioning(true)
const complete = () => {
this.setTransitioning(false)
$(this._element)
.removeClass(ClassName.COLLAPSING)
.addClass(ClassName.COLLAPSE)
.trigger(Event.HIDDEN)
}
this._element.style[dimension] = ''
if (!Util.supportsTransitionEnd()) {
complete()
return
}
$(this._element)
.one(Util.TRANSITION_END, complete)
.emulateTransitionEnd(TRANSITION_DURATION)
}
setTransitioning(isTransitioning) {
this._isTransitioning = isTransitioning
}
dispose() {
$.removeData(this._element, DATA_KEY)
this._config = null
this._parent = null
this._element = null
this._triggerArray = null
this._isTransitioning = null
}
// Private
_getConfig(config) {
config = {
...Default,
...config
}
config.toggle = Boolean(config.toggle) // Coerce string values
Util.typeCheckConfig(NAME, config, DefaultType)
return config
}
_getDimension() {
const hasWidth = $(this._element).hasClass(Dimension.WIDTH)
return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT
}
_getParent() {
let parent = null
if (Util.isElement(this._config.parent)) {
parent = this._config.parent
// It's a jQuery object
if (typeof this._config.parent.jquery !== 'undefined') {
parent = this._config.parent[0]
}
} else {
parent = $(this._config.parent)[0]
}
const selector =
`[data-toggle="collapse"][data-parent="${this._config.parent}"]`
$(parent).find(selector).each((i, element) => {
this._addAriaAndCollapsedClass(
Collapse._getTargetFromElement(element),
[element]
)
})
return parent
}
_addAriaAndCollapsedClass(element, triggerArray) {
if (element) {
const isOpen = $(element).hasClass(ClassName.SHOW)
if (triggerArray.length > 0) {
$(triggerArray)
.toggleClass(ClassName.COLLAPSED, !isOpen)
.attr('aria-expanded', isOpen)
}
}
}
// Static
static _getTargetFromElement(element) {
const selector = Util.getSelectorFromElement(element)
return selector ? $(selector)[0] : null
}
static _jQueryInterface(config) {
return this.each(function () {
const $this = $(this)
let data = $this.data(DATA_KEY)
const _config = {
...Default,
...$this.data(),
...typeof config === 'object' && config
}
if (!data && _config.toggle && /show|hide/.test(config)) {
_config.toggle = false
}
if (!data) {
data = new Collapse(this, _config)
$this.data(DATA_KEY, data)
}
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {
throw new TypeError(`No method named "${config}"`)
}
data[config]()
}
})
}
}
/**
* ------------------------------------------------------------------------
* Data Api implementation
* ------------------------------------------------------------------------
*/
$(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
// preventDefault only for <a> elements (which change the URL) not inside the collapsible element
if (event.currentTarget.tagName === 'A') {
event.preventDefault()
}
const $trigger = $(this)
const selector = Util.getSelectorFromElement(this)
$(selector).each(function () {
const $target = $(this)
const data = $target.data(DATA_KEY)
const config = data ? 'toggle' : $trigger.data()
Collapse._jQueryInterface.call($target, config)
})
})
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
*/
$.fn[NAME] = Collapse._jQueryInterface
$.fn[NAME].Constructor = Collapse
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Collapse._jQueryInterface
}
return Collapse
})($)
export default Collapse
Vendored Executable
+25
View File
File diff suppressed because one or more lines are too long
+470
View File
@@ -0,0 +1,470 @@
import $ from 'jquery'
import Popper from 'popper.js'
import Util from './util'
/**
* --------------------------------------------------------------------------
* Bootstrap (v4.0.0): dropdown.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* --------------------------------------------------------------------------
*/
const Dropdown = (($) => {
/**
* ------------------------------------------------------------------------
* Constants
* ------------------------------------------------------------------------
*/
const NAME = 'dropdown'
const VERSION = '4.0.0'
const DATA_KEY = 'bs.dropdown'
const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
const JQUERY_NO_CONFLICT = $.fn[NAME]
const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key
const SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key
const TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key
const ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key
const ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key
const RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse)
const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`)
const Event = {
HIDE : `hide${EVENT_KEY}`,
HIDDEN : `hidden${EVENT_KEY}`,
SHOW : `show${EVENT_KEY}`,
SHOWN : `shown${EVENT_KEY}`,
CLICK : `click${EVENT_KEY}`,
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`,
KEYDOWN_DATA_API : `keydown${EVENT_KEY}${DATA_API_KEY}`,
KEYUP_DATA_API : `keyup${EVENT_KEY}${DATA_API_KEY}`
}
const ClassName = {
DISABLED : 'disabled',
SHOW : 'show',
DROPUP : 'dropup',
DROPRIGHT : 'dropright',
DROPLEFT : 'dropleft',
MENURIGHT : 'dropdown-menu-right',
MENULEFT : 'dropdown-menu-left',
POSITION_STATIC : 'position-static'
}
const Selector = {
DATA_TOGGLE : '[data-toggle="dropdown"]',
FORM_CHILD : '.dropdown form',
MENU : '.dropdown-menu',
NAVBAR_NAV : '.navbar-nav',
VISIBLE_ITEMS : '.dropdown-menu .dropdown-item:not(.disabled)'
}
const AttachmentMap = {
TOP : 'top-start',
TOPEND : 'top-end',
BOTTOM : 'bottom-start',
BOTTOMEND : 'bottom-end',
RIGHT : 'right-start',
RIGHTEND : 'right-end',
LEFT : 'left-start',
LEFTEND : 'left-end'
}
const Default = {
offset : 0,
flip : true,
boundary : 'scrollParent'
}
const DefaultType = {
offset : '(number|string|function)',
flip : 'boolean',
boundary : '(string|element)'
}
/**
* ------------------------------------------------------------------------
* Class Definition
* ------------------------------------------------------------------------
*/
class Dropdown {
constructor(element, config) {
this._element = element
this._popper = null
this._config = this._getConfig(config)
this._menu = this._getMenuElement()
this._inNavbar = this._detectNavbar()
this._addEventListeners()
}
// Getters
static get VERSION() {
return VERSION
}
static get Default() {
return Default
}
static get DefaultType() {
return DefaultType
}
// Public
toggle() {
if (this._element.disabled || $(this._element).hasClass(ClassName.DISABLED)) {
return
}
const parent = Dropdown._getParentFromElement(this._element)
const isActive = $(this._menu).hasClass(ClassName.SHOW)
Dropdown._clearMenus()
if (isActive) {
return
}
const relatedTarget = {
relatedTarget: this._element
}
const showEvent = $.Event(Event.SHOW, relatedTarget)
$(parent).trigger(showEvent)
if (showEvent.isDefaultPrevented()) {
return
}
// Disable totally Popper.js for Dropdown in Navbar
if (!this._inNavbar) {
/**
* Check for Popper dependency
* Popper - https://popper.js.org
*/
if (typeof Popper === 'undefined') {
throw new TypeError('Bootstrap dropdown require Popper.js (https://popper.js.org)')
}
let element = this._element
// For dropup with alignment we use the parent as popper container
if ($(parent).hasClass(ClassName.DROPUP)) {
if ($(this._menu).hasClass(ClassName.MENULEFT) || $(this._menu).hasClass(ClassName.MENURIGHT)) {
element = parent
}
}
// If boundary is not `scrollParent`, then set position to `static`
// to allow the menu to "escape" the scroll parent's boundaries
// https://github.com/twbs/bootstrap/issues/24251
if (this._config.boundary !== 'scrollParent') {
$(parent).addClass(ClassName.POSITION_STATIC)
}
this._popper = new Popper(element, this._menu, this._getPopperConfig())
}
// If this is a touch-enabled device we add extra
// empty mouseover listeners to the body's immediate children;
// only needed because of broken event delegation on iOS
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
if ('ontouchstart' in document.documentElement &&
$(parent).closest(Selector.NAVBAR_NAV).length === 0) {
$('body').children().on('mouseover', null, $.noop)
}
this._element.focus()
this._element.setAttribute('aria-expanded', true)
$(this._menu).toggleClass(ClassName.SHOW)
$(parent)
.toggleClass(ClassName.SHOW)
.trigger($.Event(Event.SHOWN, relatedTarget))
}
dispose() {
$.removeData(this._element, DATA_KEY)
$(this._element).off(EVENT_KEY)
this._element = null
this._menu = null
if (this._popper !== null) {
this._popper.destroy()
this._popper = null
}
}
update() {
this._inNavbar = this._detectNavbar()
if (this._popper !== null) {
this._popper.scheduleUpdate()
}
}
// Private
_addEventListeners() {
$(this._element).on(Event.CLICK, (event) => {
event.preventDefault()
event.stopPropagation()
this.toggle()
})
}
_getConfig(config) {
config = {
...this.constructor.Default,
...$(this._element).data(),
...config
}
Util.typeCheckConfig(
NAME,
config,
this.constructor.DefaultType
)
return config
}
_getMenuElement() {
if (!this._menu) {
const parent = Dropdown._getParentFromElement(this._element)
this._menu = $(parent).find(Selector.MENU)[0]
}
return this._menu
}
_getPlacement() {
const $parentDropdown = $(this._element).parent()
let placement = AttachmentMap.BOTTOM
// Handle dropup
if ($parentDropdown.hasClass(ClassName.DROPUP)) {
placement = AttachmentMap.TOP
if ($(this._menu).hasClass(ClassName.MENURIGHT)) {
placement = AttachmentMap.TOPEND
}
} else if ($parentDropdown.hasClass(ClassName.DROPRIGHT)) {
placement = AttachmentMap.RIGHT
} else if ($parentDropdown.hasClass(ClassName.DROPLEFT)) {
placement = AttachmentMap.LEFT
} else if ($(this._menu).hasClass(ClassName.MENURIGHT)) {
placement = AttachmentMap.BOTTOMEND
}
return placement
}
_detectNavbar() {
return $(this._element).closest('.navbar').length > 0
}
_getPopperConfig() {
const offsetConf = {}
if (typeof this._config.offset === 'function') {
offsetConf.fn = (data) => {
data.offsets = {
...data.offsets,
...this._config.offset(data.offsets) || {}
}
return data
}
} else {
offsetConf.offset = this._config.offset
}
const popperConfig = {
placement: this._getPlacement(),
modifiers: {
offset: offsetConf,
flip: {
enabled: this._config.flip
},
preventOverflow: {
boundariesElement: this._config.boundary
}
}
}
return popperConfig
}
// Static
static _jQueryInterface(config) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _config = typeof config === 'object' ? config : null
if (!data) {
data = new Dropdown(this, _config)
$(this).data(DATA_KEY, data)
}
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {
throw new TypeError(`No method named "${config}"`)
}
data[config]()
}
})
}
static _clearMenus(event) {
if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH ||
event.type === 'keyup' && event.which !== TAB_KEYCODE)) {
return
}
const toggles = $.makeArray($(Selector.DATA_TOGGLE))
for (let i = 0; i < toggles.length; i++) {
const parent = Dropdown._getParentFromElement(toggles[i])
const context = $(toggles[i]).data(DATA_KEY)
const relatedTarget = {
relatedTarget: toggles[i]
}
if (!context) {
continue
}
const dropdownMenu = context._menu
if (!$(parent).hasClass(ClassName.SHOW)) {
continue
}
if (event && (event.type === 'click' &&
/input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) &&
$.contains(parent, event.target)) {
continue
}
const hideEvent = $.Event(Event.HIDE, relatedTarget)
$(parent).trigger(hideEvent)
if (hideEvent.isDefaultPrevented()) {
continue
}
// If this is a touch-enabled device we remove the extra
// empty mouseover listeners we added for iOS support
if ('ontouchstart' in document.documentElement) {
$('body').children().off('mouseover', null, $.noop)
}
toggles[i].setAttribute('aria-expanded', 'false')
$(dropdownMenu).removeClass(ClassName.SHOW)
$(parent)
.removeClass(ClassName.SHOW)
.trigger($.Event(Event.HIDDEN, relatedTarget))
}
}
static _getParentFromElement(element) {
let parent
const selector = Util.getSelectorFromElement(element)
if (selector) {
parent = $(selector)[0]
}
return parent || element.parentNode
}
// eslint-disable-next-line complexity
static _dataApiKeydownHandler(event) {
// If not input/textarea:
// - And not a key in REGEXP_KEYDOWN => not a dropdown command
// If input/textarea:
// - If space key => not a dropdown command
// - If key is other than escape
// - If key is not up or down => not a dropdown command
// - If trigger inside the menu => not a dropdown command
if (/input|textarea/i.test(event.target.tagName)
? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE &&
(event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE ||
$(event.target).closest(Selector.MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {
return
}
event.preventDefault()
event.stopPropagation()
if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
return
}
const parent = Dropdown._getParentFromElement(this)
const isActive = $(parent).hasClass(ClassName.SHOW)
if (!isActive && (event.which !== ESCAPE_KEYCODE || event.which !== SPACE_KEYCODE) ||
isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {
if (event.which === ESCAPE_KEYCODE) {
const toggle = $(parent).find(Selector.DATA_TOGGLE)[0]
$(toggle).trigger('focus')
}
$(this).trigger('click')
return
}
const items = $(parent).find(Selector.VISIBLE_ITEMS).get()
if (items.length === 0) {
return
}
let index = items.indexOf(event.target)
if (event.which === ARROW_UP_KEYCODE && index > 0) { // Up
index--
}
if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // Down
index++
}
if (index < 0) {
index = 0
}
items[index].focus()
}
}
/**
* ------------------------------------------------------------------------
* Data Api implementation
* ------------------------------------------------------------------------
*/
$(document)
.on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler)
.on(Event.KEYDOWN_DATA_API, Selector.MENU, Dropdown._dataApiKeydownHandler)
.on(`${Event.CLICK_DATA_API} ${Event.KEYUP_DATA_API}`, Dropdown._clearMenus)
.on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
event.preventDefault()
event.stopPropagation()
Dropdown._jQueryInterface.call($(this), 'toggle')
})
.on(Event.CLICK_DATA_API, Selector.FORM_CHILD, (e) => {
e.stopPropagation()
})
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
*/
$.fn[NAME] = Dropdown._jQueryInterface
$.fn[NAME].Constructor = Dropdown
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Dropdown._jQueryInterface
}
return Dropdown
})($, Popper)
export default Dropdown
Vendored Executable
+8
View File
@@ -0,0 +1,8 @@
/*
HTML5 Shiv v3.6.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
(function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag();
a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/\w+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x<style>article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}</style>";
c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="<xyz></xyz>";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode||
"undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup main mark meter nav output progress section summary time video",version:"3.6.2",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);if(g)return a.createDocumentFragment();
for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d<h;d++)c.createElement(e[d]);return c}};l.html5=e;q(f)})(this,document);
Executable
+50
View File
@@ -0,0 +1,50 @@
import $ from 'jquery'
import Alert from './alert'
import Button from './button'
import Carousel from './carousel'
import Collapse from './collapse'
import Dropdown from './dropdown'
import Modal from './modal'
import Popover from './popover'
import Scrollspy from './scrollspy'
import Tab from './tab'
import Tooltip from './tooltip'
import Util from './util'
/**
* --------------------------------------------------------------------------
* Bootstrap (v4.0.0-alpha.6): index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* --------------------------------------------------------------------------
*/
(($) => {
if (typeof $ === 'undefined') {
throw new TypeError('Bootstrap\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\'s JavaScript.')
}
const version = $.fn.jquery.split(' ')[0].split('.')
const minMajor = 1
const ltMajor = 2
const minMinor = 9
const minPatch = 1
const maxMajor = 4
if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) {
throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0')
}
})($)
export {
Util,
Alert,
Button,
Carousel,
Collapse,
Dropdown,
Modal,
Popover,
Scrollspy,
Tab,
Tooltip
}
Vendored Executable
+6
View File
File diff suppressed because one or more lines are too long
Vendored Executable
+12
View File
File diff suppressed because one or more lines are too long
+576
View File
@@ -0,0 +1,576 @@
/*
HTML Clean for jQuery
Anthony Johnston
http://www.antix.co.uk
version 1.3.1
$Revision$
requires jQuery http://jquery.com
Use and distibution http://www.opensource.org/licenses/bsd-license.php
2010-04-02 allowedTags/removeTags added (white/black list) thanks to David Wartian (Dwartian)
2010-06-30 replaceStyles added for replacement of bold, italic, super and sub styles on a tag
2012-04-30 allowedAttributes added, an array of attributed allowed on the elements
2013-02-25 now will push non-inline elements up the stack if nested in an inline element
2013-02-25 comment element support added, removed by default, see AllowComments in options
*/
(function ($) {
$.fn.htmlClean = function (options) {
// iterate and html clean each matched element
return this.each(function () {
var $this = $(this);
if (this.value) {
this.value = $.htmlClean(this.value, options);
} else {
this.innerHTML = $.htmlClean(this.innerHTML, options);
}
});
};
// clean the passed html
$.htmlClean = function (html, options) {
options = $.extend({}, $.htmlClean.defaults, options);
var tagsRE = /(<(\/)?(\w+:)?([\w]+)([^>]*)>)|<!--(.*?--)>/gi;
var attrsRE = /([\w\-]+)=(".*?"|'.*?'|[^\s>]*)/gi;
var tagMatch;
var root = new Element();
var stack = [root];
var container = root;
var protect = false;
if (options.bodyOnly) {
// check for body tag
if (tagMatch = /<body[^>]*>((\n|.)*)<\/body>/i.exec(html)) {
html = tagMatch[1];
}
}
html = html.concat("<xxx>"); // ensure last element/text is found
var lastIndex;
while (tagMatch = tagsRE.exec(html)) {
var tag = tagMatch[6]
? new Tag("--", null, tagMatch[6], options)
: new Tag(tagMatch[4], tagMatch[2], tagMatch[5], options);
// add the text
var text = html.substring(lastIndex, tagMatch.index);
if (text.length > 0) {
var child = container.children[container.children.length - 1];
if (container.children.length > 0
&& isText(child = container.children[container.children.length - 1])) {
// merge text
container.children[container.children.length - 1] = child.concat(text);
} else {
container.children.push(text);
}
}
lastIndex = tagsRE.lastIndex;
if (tag.isClosing) {
// find matching container
if (popToTagName(stack, [tag.name])) {
stack.pop();
container = stack[stack.length - 1];
}
} else {
// create a new element
var element = new Element(tag);
// add attributes
var attrMatch;
while (attrMatch = attrsRE.exec(tag.rawAttributes)) {
// check style attribute and do replacements
if (attrMatch[1].toLowerCase() == "style"
&& options.replaceStyles) {
var renderParent = !tag.isInline;
for (var i = 0; i < options.replaceStyles.length; i++) {
if (options.replaceStyles[i][0].test(attrMatch[2])) {
if (!renderParent) {
tag.render = false;
renderParent = true;
}
container.children.push(element); // assumes not replaced
stack.push(element);
container = element; // assumes replacement is a container
// create new tag and element
tag = new Tag(options.replaceStyles[i][1], "", "", options);
element = new Element(tag);
}
}
}
if (tag.allowedAttributes != null
&& (tag.allowedAttributes.length == 0
|| $.inArray(attrMatch[1], tag.allowedAttributes) > -1)) {
element.attributes.push(new Attribute(attrMatch[1], attrMatch[2]));
}
}
// add required empty ones
$.each(tag.requiredAttributes, function () {
var name = this.toString();
if (!element.hasAttribute(name)) element.attributes.push(new Attribute(name, ""));
});
// check for replacements
for (var repIndex = 0; repIndex < options.replace.length; repIndex++) {
for (var tagIndex = 0; tagIndex < options.replace[repIndex][0].length; tagIndex++) {
var byName = typeof (options.replace[repIndex][0][tagIndex]) == "string";
if ((byName && options.replace[repIndex][0][tagIndex] == tag.name)
|| (!byName && options.replace[repIndex][0][tagIndex].test(tagMatch))) {
// set the name to the replacement
tag.rename(options.replace[repIndex][1]);
repIndex = options.replace.length; // break out of both loops
break;
}
}
}
// check container rules
var add = true;
if (!container.isRoot) {
if (container.tag.isInline && !tag.isInline) {
if (add = popToContainer(stack)) {
container = stack[stack.length - 1];
}
} else if (container.tag.disallowNest && tag.disallowNest
&& !tag.requiredParent) {
add = false;
} else if (tag.requiredParent) {
if (add = popToTagName(stack, tag.requiredParent)) {
container = stack[stack.length - 1];
}
}
}
if (add) {
container.children.push(element);
if (tag.toProtect) {
// skip to closing tag
while (tagMatch2 = tagsRE.exec(html)) {
var tag2 = new Tag(tagMatch2[3], tagMatch2[1], tagMatch2[4], options);
if (tag2.isClosing && tag2.name == tag.name) {
element.children.push(RegExp.leftContext.substring(lastIndex));
lastIndex = tagsRE.lastIndex;
break;
}
}
} else {
// set as current container element
if (!tag.isSelfClosing && !tag.isNonClosing) {
stack.push(element);
container = element;
}
}
}
}
}
// render doc
return $.htmlClean.trim(render(root, options).join(""));
};
// defaults
$.htmlClean.defaults = {
// only clean the body tagbody
bodyOnly: true,
// only allow tags in this array, (white list), contents still rendered
allowedTags: [],
// remove tags in this array, (black list), contents still rendered
removeTags: ["basefont", "center", "dir", "font", "frame", "frameset", "iframe", "isindex", "menu", "noframes", "s", "strike", "u"],
// array of [attributeName], [optional array of allowed on elements] e.g. [["id"], ["style", ["p", "dl"]]] // allow all elements to have id and allow style on 'p' and 'dl'
allowedAttributes: [],
// array of attribute names to remove on all elements in addition to those not in tagAttributes e.g ["width", "height"]
removeAttrs: [],
// array of [className], [optional array of allowed on elements] e.g. [["aClass"], ["anotherClass", ["p", "dl"]]]
allowedClasses: [],
// format the result
format: false,
// format indent to start on
formatIndent: 0,
// tags to replace, and what to replace with, tag name or regex to match the tag and attributes
replace: [
[["b", "big"], "strong"],
[["i"], "em"]
],
// styles to replace with tags, multiple style matches supported, inline tags are replaced by the first match blocks are retained
replaceStyles: [
[/font-weight:\s*bold/i, "strong"],
[/font-style:\s*italic/i, "em"],
[/vertical-align:\s*super/i, "sup"],
[/vertical-align:\s*sub/i, "sub"]
],
allowComments: false
};
function applyFormat(element, options, output, indent) {
if (!element.tag.isInline && output.length > 0) {
output.push("\n");
for (i = 0; i < indent; i++) output.push("\t");
}
}
function render(element, options) {
var output = [], empty = element.attributes.length == 0, indent;
if (element.tag.isComment) {
if (options.allowComments) {
output.push("<!--");
output.push(element.tag.rawAttributes);
output.push(">");
if (options.format) applyFormat(element, options, output, indent - 1);
}
} else {
var openingTag = this.name.concat(element.tag.rawAttributes == undefined ? "" : element.tag.rawAttributes);
// don't render if not in allowedTags or in removeTags
var renderTag
= element.tag.render
&& (options.allowedTags.length == 0 || $.inArray(element.tag.name, options.allowedTags) > -1)
&& (options.removeTags.length == 0 || $.inArray(element.tag.name, options.removeTags) == -1);
if (!element.isRoot && renderTag) {
// render opening tag
output.push("<");
output.push(element.tag.name);
$.each(element.attributes, function () {
if ($.inArray(this.name, options.removeAttrs) == -1) {
var m = RegExp(/^(['"]?)(.*?)['"]?$/).exec(this.value);
var value = m[2];
var valueQuote = m[1] || "'";
// check for classes allowed
if (this.name == "class" && options.allowedClasses.length > 0) {
value =
$.grep(value.split(" "), function (c) {
return $.grep(options.allowedClasses, function (a) {
return a == c
|| (a[0] == c && (a.length == 1 || $.inArray(element.tag.name, a[1]) > -1));
}).length > 0;
})
.join(" ");
}
if (value != null && (value.length > 0 || $.inArray(this.name, element.tag.requiredAttributes) > -1)) {
output.push(" ");
output.push(this.name);
output.push("=");
output.push(valueQuote);
output.push(value);
output.push(valueQuote);
}
}
});
}
if (element.tag.isSelfClosing) {
// self closing
if (renderTag) output.push(" />");
empty = false;
} else if (element.tag.isNonClosing) {
empty = false;
} else {
if (!element.isRoot && renderTag) {
// close
output.push(">");
}
var indent = options.formatIndent++;
// render children
if (element.tag.toProtect) {
var outputChildren = $.htmlClean.trim(element.children.join("")).replace(/<br>/ig, "\n");
output.push(outputChildren);
empty = outputChildren.length == 0;
} else {
var outputChildren = [];
for (var i = 0; i < element.children.length; i++) {
var child = element.children[i];
var text = $.htmlClean.trim(textClean(isText(child) ? child : child.childrenToString()));
if (isInline(child)) {
if (i > 0 && text.length > 0
&& (startsWithWhitespace(child) || endsWithWhitespace(element.children[i - 1]))) {
outputChildren.push(" ");
}
}
if (isText(child)) {
if (text.length > 0) {
outputChildren.push(text);
}
} else {
// don't allow a break to be the last child
if (i != element.children.length - 1 || child.tag.name != "br") {
if (options.format) applyFormat(child, options, outputChildren, indent);
outputChildren = outputChildren.concat(render(child, options));
}
}
}
options.formatIndent--;
if (outputChildren.length > 0) {
if (options.format && outputChildren[0] != "\n") applyFormat(element, options, output, indent);
output = output.concat(outputChildren);
empty = false;
}
}
if (!element.isRoot && renderTag) {
// render the closing tag
if (options.format) applyFormat(element, options, output, indent - 1);
output.push("</");
output.push(element.tag.name);
output.push(">");
}
}
// check for empty tags
if (!element.tag.allowEmpty && empty) { return []; }
}
return output;
}
// find a matching tag, and pop to it, if not do nothing
function popToTagName(stack, tagNameArray) {
return pop(
stack,
function (element) {
return $.inArray(element.tag.nameOriginal, tagNameArray) > -1
});
}
function popToContainer(stack) {
return pop(
stack,
function (element) {
return element.isRoot || !element.tag.isInline;
});
}
function pop(stack, test, index) {
index = index || 1;
var element = stack[stack.length - index];
if (test(element)) {
return true;
} else if (stack.length - index > 0
&& pop(stack, test, index + 1)) {
stack.pop();
return true;
}
return false;
}
// Element Object
function Element(tag) {
if (tag) {
this.tag = tag;
this.isRoot = false;
} else {
this.tag = new Tag("root");
this.isRoot = true;
}
this.attributes = [];
this.children = [];
this.hasAttribute = function (name) {
for (var i = 0; i < this.attributes.length; i++) {
if (this.attributes[i].name == name) return true;
}
return false;
};
this.childrenToString = function () {
return this.children.join("");
};
return this;
}
// Attribute Object
function Attribute(name, value) {
this.name = name;
this.value = value;
return this;
}
// Tag object
function Tag(name, close, rawAttributes, options) {
this.name = name.toLowerCase();
this.nameOriginal = this.name;
this.render = true;
this.init = function () {
if (this.name == "--") {
this.isComment = true;
this.isSelfClosing = true;
} else {
this.isComment = false;
this.isSelfClosing = $.inArray(this.name, tagSelfClosing) > -1;
this.isNonClosing = $.inArray(this.name, tagNonClosing) > -1;
this.isClosing = (close != undefined && close.length > 0);
this.isInline = $.inArray(this.name, tagInline) > -1;
this.disallowNest = $.inArray(this.name, tagDisallowNest) > -1;
this.requiredParent = tagRequiredParent[$.inArray(this.name, tagRequiredParent) + 1];
this.allowEmpty = $.inArray(this.name, tagAllowEmpty) > -1;
this.toProtect = $.inArray(this.name, tagProtect) > -1;
}
this.rawAttributes = rawAttributes;
this.requiredAttributes = tagAttributesRequired[$.inArray(this.name, tagAttributesRequired) + 1];
if (options) {
if (!options.tagAttributesCache) options.tagAttributesCache = [];
if ($.inArray(this.name, options.tagAttributesCache) == -1) {
var cacheItem = tagAttributes[$.inArray(this.name, tagAttributes) + 1].slice(0);
// add extra ones from options
for (var i = 0; i < options.allowedAttributes.length; i++) {
var attrName = options.allowedAttributes[i][0];
if ((
options.allowedAttributes[i].length == 1
|| $.inArray(this.name, options.allowedAttributes[i][1]) > -1
) && $.inArray(attrName, cacheItem) == -1) {
cacheItem.push(attrName);
}
}
options.tagAttributesCache.push(this.name);
options.tagAttributesCache.push(cacheItem);
}
this.allowedAttributes = options.tagAttributesCache[$.inArray(this.name, options.tagAttributesCache) + 1];
}
}
this.init();
this.rename = function (newName) {
this.name = newName;
this.init();
};
return this;
}
function startsWithWhitespace(item) {
while (isElement(item) && item.children.length > 0) { item = item.children[0] }
if (!isText(item)) return false;
var text = textClean(item);
return text.length > 0 && $.htmlClean.isWhitespace(text.charAt(0));
}
function endsWithWhitespace(item) {
while (isElement(item) && item.children.length > 0) { item = item.children[item.children.length - 1] }
if (!isText(item)) return false;
var text = textClean(item);
return text.length > 0 && $.htmlClean.isWhitespace(text.charAt(text.length - 1));
}
function isText(item) { return item.constructor == String; }
function isInline(item) { return isText(item) || item.tag.isInline; }
function isElement(item) { return item.constructor == Element; }
function textClean(text) {
return text
.replace(/&nbsp;|\n/g, " ")
.replace(/\s\s+/g, " ");
}
// trim off white space, doesn't use regex
$.htmlClean.trim = function (text) {
return $.htmlClean.trimStart($.htmlClean.trimEnd(text));
};
$.htmlClean.trimStart = function (text) {
return text.substring($.htmlClean.trimStartIndex(text));
};
$.htmlClean.trimStartIndex = function (text) {
for (var start = 0; start < text.length - 1 && $.htmlClean.isWhitespace(text.charAt(start)); start++);
return start;
};
$.htmlClean.trimEnd = function (text) {
return text.substring(0, $.htmlClean.trimEndIndex(text));
};
$.htmlClean.trimEndIndex = function (text) {
for (var end = text.length - 1; end >= 0 && $.htmlClean.isWhitespace(text.charAt(end)); end--);
return end + 1;
};
// checks a char is white space or not
$.htmlClean.isWhitespace = function (c) { return $.inArray(c, whitespace) != -1; };
// tags which are inline
var tagInline = [
"a", "abbr", "acronym", "address", "b", "big", "br", "button",
"caption", "cite", "code", "del", "em", "font",
"hr", "i", "input", "img", "ins", "label", "legend", "map", "q",
"s", "samp", "select", "option", "param", "small", "span", "strike", "strong", "sub", "sup",
"tt", "u", "var"];
var tagDisallowNest = ["h1", "h2", "h3", "h4", "h5", "h6", "p", "th", "td", "object"];
var tagAllowEmpty = ["th", "td"];
var tagRequiredParent = [
null,
"li", ["ul", "ol"],
"dt", ["dl"],
"dd", ["dl"],
"td", ["tr"],
"th", ["tr"],
"tr", ["table", "thead", "tbody", "tfoot"],
"thead", ["table"],
"tbody", ["table"],
"tfoot", ["table"],
"param", ["object"]
];
var tagProtect = ["script", "style", "pre", "code"];
// tags which self close e.g. <br />
var tagSelfClosing = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr"];
// tags which do not close
var tagNonClosing = ["!doctype", "?xml"];
// attributes allowed on tags
var tagAttributes = [
["class"], // default, for all tags not mentioned
"?xml", [],
"!doctype", [],
"a", ["accesskey", "class", "href", "name", "title", "rel", "rev", "type", "tabindex"],
"abbr", ["class", "title"],
"acronym", ["class", "title"],
"blockquote", ["cite", "class"],
"button", ["class", "disabled", "name", "type", "value"],
"del", ["cite", "class", "datetime"],
"form", ["accept", "action", "class", "enctype", "method", "name"],
"input", ["accept", "accesskey", "alt", "checked", "class", "disabled", "ismap", "maxlength", "name", "size", "readonly", "src", "tabindex", "type", "usemap", "value"],
"img", ["alt", "class", "height", "src", "width"],
"ins", ["cite", "class", "datetime"],
"label", ["accesskey", "class", "for"],
"legend", ["accesskey", "class"],
"link", ["href", "rel", "type"],
"meta", ["content", "http-equiv", "name", "scheme", "charset"],
"map", ["name"],
"optgroup", ["class", "disabled", "label"],
"option", ["class", "disabled", "label", "selected", "value"],
"q", ["class", "cite"],
"script", ["src", "type"],
"select", ["class", "disabled", "multiple", "name", "size", "tabindex"],
"style", ["type"],
"table", ["class", "summary"],
"th", ["class", "colspan", "rowspan"],
"td", ["class", "colspan", "rowspan"],
"textarea", ["accesskey", "class", "cols", "disabled", "name", "readonly", "rows", "tabindex"],
"param", ["name", "value"],
"embed", ["height", "src", "type", "width"]
];
var tagAttributesRequired = [[], "img", ["alt"]];
// white space chars
var whitespace = [" ", " ", "\t", "\n", "\r", "\f"];
})(jQuery);
+11
View File
@@ -0,0 +1,11 @@
/*
* jQuery UI Touch Punch 0.2.2
*
* Copyright 2011, Dave Furfero
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* Depends:
* jquery.ui.widget.js
* jquery.ui.mouse.js
*/
(function(b){b.support.touch="ontouchend" in document;if(!b.support.touch){return;}var c=b.ui.mouse.prototype,e=c._mouseInit,a;function d(g,h){if(g.originalEvent.touches.length>1){return;}g.preventDefault();var i=g.originalEvent.changedTouches[0],f=document.createEvent("MouseEvents");f.initMouseEvent(h,true,true,window,1,i.screenX,i.screenY,i.clientX,i.clientY,false,false,false,false,0,null);g.target.dispatchEvent(f);}c._touchStart=function(g){var f=this;if(a||!f._mouseCapture(g.originalEvent.changedTouches[0])){return;}a=true;f._touchMoved=false;d(g,"mouseover");d(g,"mousemove");d(g,"mousedown");};c._touchMove=function(f){if(!a){return;}this._touchMoved=true;d(f,"mousemove");};c._touchEnd=function(f){if(!a){return;}d(f,"mouseup");d(f,"mouseout");if(!this._touchMoved){d(f,"click");}a=false;};c._mouseInit=function(){var f=this;f.element.bind("touchstart",b.proxy(f,"_touchStart")).bind("touchmove",b.proxy(f,"_touchMove")).bind("touchend",b.proxy(f,"_touchEnd"));e.call(f);};})(jQuery);
Executable
+578
View File
@@ -0,0 +1,578 @@
import $ from 'jquery'
import Util from './util'
/**
* --------------------------------------------------------------------------
* Bootstrap (v4.0.0): modal.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* --------------------------------------------------------------------------
*/
const Modal = (($) => {
/**
* ------------------------------------------------------------------------
* Constants
* ------------------------------------------------------------------------
*/
const NAME = 'modal'
const VERSION = '4.0.0'
const DATA_KEY = 'bs.modal'
const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
const JQUERY_NO_CONFLICT = $.fn[NAME]
const TRANSITION_DURATION = 300
const BACKDROP_TRANSITION_DURATION = 150
const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key
const Default = {
backdrop : true,
keyboard : true,
focus : true,
show : true
}
const DefaultType = {
backdrop : '(boolean|string)',
keyboard : 'boolean',
focus : 'boolean',
show : 'boolean'
}
const Event = {
HIDE : `hide${EVENT_KEY}`,
HIDDEN : `hidden${EVENT_KEY}`,
SHOW : `show${EVENT_KEY}`,
SHOWN : `shown${EVENT_KEY}`,
FOCUSIN : `focusin${EVENT_KEY}`,
RESIZE : `resize${EVENT_KEY}`,
CLICK_DISMISS : `click.dismiss${EVENT_KEY}`,
KEYDOWN_DISMISS : `keydown.dismiss${EVENT_KEY}`,
MOUSEUP_DISMISS : `mouseup.dismiss${EVENT_KEY}`,
MOUSEDOWN_DISMISS : `mousedown.dismiss${EVENT_KEY}`,
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
}
const ClassName = {
SCROLLBAR_MEASURER : 'modal-scrollbar-measure',
BACKDROP : 'modal-backdrop',
OPEN : 'modal-open',
FADE : 'fade',
SHOW : 'show'
}
const Selector = {
DIALOG : '.modal-dialog',
DATA_TOGGLE : '[data-toggle="modal"]',
DATA_DISMISS : '[data-dismiss="modal"]',
FIXED_CONTENT : '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top',
STICKY_CONTENT : '.sticky-top',
NAVBAR_TOGGLER : '.navbar-toggler'
}
/**
* ------------------------------------------------------------------------
* Class Definition
* ------------------------------------------------------------------------
*/
class Modal {
constructor(element, config) {
this._config = this._getConfig(config)
this._element = element
this._dialog = $(element).find(Selector.DIALOG)[0]
this._backdrop = null
this._isShown = false
this._isBodyOverflowing = false
this._ignoreBackdropClick = false
this._originalBodyPadding = 0
this._scrollbarWidth = 0
}
// Getters
static get VERSION() {
return VERSION
}
static get Default() {
return Default
}
// Public
toggle(relatedTarget) {
return this._isShown ? this.hide() : this.show(relatedTarget)
}
show(relatedTarget) {
if (this._isTransitioning || this._isShown) {
return
}
if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)) {
this._isTransitioning = true
}
const showEvent = $.Event(Event.SHOW, {
relatedTarget
})
$(this._element).trigger(showEvent)
if (this._isShown || showEvent.isDefaultPrevented()) {
return
}
this._isShown = true
this._checkScrollbar()
this._setScrollbar()
this._adjustDialog()
$(document.body).addClass(ClassName.OPEN)
this._setEscapeEvent()
this._setResizeEvent()
$(this._element).on(
Event.CLICK_DISMISS,
Selector.DATA_DISMISS,
(event) => this.hide(event)
)
$(this._dialog).on(Event.MOUSEDOWN_DISMISS, () => {
$(this._element).one(Event.MOUSEUP_DISMISS, (event) => {
if ($(event.target).is(this._element)) {
this._ignoreBackdropClick = true
}
})
})
this._showBackdrop(() => this._showElement(relatedTarget))
}
hide(event) {
if (event) {
event.preventDefault()
}
if (this._isTransitioning || !this._isShown) {
return
}
const hideEvent = $.Event(Event.HIDE)
$(this._element).trigger(hideEvent)
if (!this._isShown || hideEvent.isDefaultPrevented()) {
return
}
this._isShown = false
const transition = Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)
if (transition) {
this._isTransitioning = true
}
this._setEscapeEvent()
this._setResizeEvent()
$(document).off(Event.FOCUSIN)
$(this._element).removeClass(ClassName.SHOW)
$(this._element).off(Event.CLICK_DISMISS)
$(this._dialog).off(Event.MOUSEDOWN_DISMISS)
if (transition) {
$(this._element)
.one(Util.TRANSITION_END, (event) => this._hideModal(event))
.emulateTransitionEnd(TRANSITION_DURATION)
} else {
this._hideModal()
}
}
dispose() {
$.removeData(this._element, DATA_KEY)
$(window, document, this._element, this._backdrop).off(EVENT_KEY)
this._config = null
this._element = null
this._dialog = null
this._backdrop = null
this._isShown = null
this._isBodyOverflowing = null
this._ignoreBackdropClick = null
this._scrollbarWidth = null
}
handleUpdate() {
this._adjustDialog()
}
// Private
_getConfig(config) {
config = {
...Default,
...config
}
Util.typeCheckConfig(NAME, config, DefaultType)
return config
}
_showElement(relatedTarget) {
const transition = Util.supportsTransitionEnd() &&
$(this._element).hasClass(ClassName.FADE)
if (!this._element.parentNode ||
this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
// Don't move modal's DOM position
document.body.appendChild(this._element)
}
this._element.style.display = 'block'
this._element.removeAttribute('aria-hidden')
this._element.scrollTop = 0
if (transition) {
Util.reflow(this._element)
}
$(this._element).addClass(ClassName.SHOW)
if (this._config.focus) {
this._enforceFocus()
}
const shownEvent = $.Event(Event.SHOWN, {
relatedTarget
})
const transitionComplete = () => {
if (this._config.focus) {
this._element.focus()
}
this._isTransitioning = false
$(this._element).trigger(shownEvent)
}
if (transition) {
$(this._dialog)
.one(Util.TRANSITION_END, transitionComplete)
.emulateTransitionEnd(TRANSITION_DURATION)
} else {
transitionComplete()
}
}
_enforceFocus() {
$(document)
.off(Event.FOCUSIN) // Guard against infinite focus loop
.on(Event.FOCUSIN, (event) => {
if (document !== event.target &&
this._element !== event.target &&
$(this._element).has(event.target).length === 0) {
this._element.focus()
}
})
}
_setEscapeEvent() {
if (this._isShown && this._config.keyboard) {
$(this._element).on(Event.KEYDOWN_DISMISS, (event) => {
if (event.which === ESCAPE_KEYCODE) {
event.preventDefault()
this.hide()
}
})
} else if (!this._isShown) {
$(this._element).off(Event.KEYDOWN_DISMISS)
}
}
_setResizeEvent() {
if (this._isShown) {
$(window).on(Event.RESIZE, (event) => this.handleUpdate(event))
} else {
$(window).off(Event.RESIZE)
}
}
_hideModal() {
this._element.style.display = 'none'
this._element.setAttribute('aria-hidden', true)
this._isTransitioning = false
this._showBackdrop(() => {
$(document.body).removeClass(ClassName.OPEN)
this._resetAdjustments()
this._resetScrollbar()
$(this._element).trigger(Event.HIDDEN)
})
}
_removeBackdrop() {
if (this._backdrop) {
$(this._backdrop).remove()
this._backdrop = null
}
}
_showBackdrop(callback) {
const animate = $(this._element).hasClass(ClassName.FADE)
? ClassName.FADE : ''
if (this._isShown && this._config.backdrop) {
const doAnimate = Util.supportsTransitionEnd() && animate
this._backdrop = document.createElement('div')
this._backdrop.className = ClassName.BACKDROP
if (animate) {
$(this._backdrop).addClass(animate)
}
$(this._backdrop).appendTo(document.body)
$(this._element).on(Event.CLICK_DISMISS, (event) => {
if (this._ignoreBackdropClick) {
this._ignoreBackdropClick = false
return
}
if (event.target !== event.currentTarget) {
return
}
if (this._config.backdrop === 'static') {
this._element.focus()
} else {
this.hide()
}
})
if (doAnimate) {
Util.reflow(this._backdrop)
}
$(this._backdrop).addClass(ClassName.SHOW)
if (!callback) {
return
}
if (!doAnimate) {
callback()
return
}
$(this._backdrop)
.one(Util.TRANSITION_END, callback)
.emulateTransitionEnd(BACKDROP_TRANSITION_DURATION)
} else if (!this._isShown && this._backdrop) {
$(this._backdrop).removeClass(ClassName.SHOW)
const callbackRemove = () => {
this._removeBackdrop()
if (callback) {
callback()
}
}
if (Util.supportsTransitionEnd() &&
$(this._element).hasClass(ClassName.FADE)) {
$(this._backdrop)
.one(Util.TRANSITION_END, callbackRemove)
.emulateTransitionEnd(BACKDROP_TRANSITION_DURATION)
} else {
callbackRemove()
}
} else if (callback) {
callback()
}
}
// ----------------------------------------------------------------------
// the following methods are used to handle overflowing modals
// todo (fat): these should probably be refactored out of modal.js
// ----------------------------------------------------------------------
_adjustDialog() {
const isModalOverflowing =
this._element.scrollHeight > document.documentElement.clientHeight
if (!this._isBodyOverflowing && isModalOverflowing) {
this._element.style.paddingLeft = `${this._scrollbarWidth}px`
}
if (this._isBodyOverflowing && !isModalOverflowing) {
this._element.style.paddingRight = `${this._scrollbarWidth}px`
}
}
_resetAdjustments() {
this._element.style.paddingLeft = ''
this._element.style.paddingRight = ''
}
_checkScrollbar() {
const rect = document.body.getBoundingClientRect()
this._isBodyOverflowing = rect.left + rect.right < window.innerWidth
this._scrollbarWidth = this._getScrollbarWidth()
}
_setScrollbar() {
if (this._isBodyOverflowing) {
// Note: DOMNode.style.paddingRight returns the actual value or '' if not set
// while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set
// Adjust fixed content padding
$(Selector.FIXED_CONTENT).each((index, element) => {
const actualPadding = $(element)[0].style.paddingRight
const calculatedPadding = $(element).css('padding-right')
$(element).data('padding-right', actualPadding).css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)
})
// Adjust sticky content margin
$(Selector.STICKY_CONTENT).each((index, element) => {
const actualMargin = $(element)[0].style.marginRight
const calculatedMargin = $(element).css('margin-right')
$(element).data('margin-right', actualMargin).css('margin-right', `${parseFloat(calculatedMargin) - this._scrollbarWidth}px`)
})
// Adjust navbar-toggler margin
$(Selector.NAVBAR_TOGGLER).each((index, element) => {
const actualMargin = $(element)[0].style.marginRight
const calculatedMargin = $(element).css('margin-right')
$(element).data('margin-right', actualMargin).css('margin-right', `${parseFloat(calculatedMargin) + this._scrollbarWidth}px`)
})
// Adjust body padding
const actualPadding = document.body.style.paddingRight
const calculatedPadding = $('body').css('padding-right')
$('body').data('padding-right', actualPadding).css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)
}
}
_resetScrollbar() {
// Restore fixed content padding
$(Selector.FIXED_CONTENT).each((index, element) => {
const padding = $(element).data('padding-right')
if (typeof padding !== 'undefined') {
$(element).css('padding-right', padding).removeData('padding-right')
}
})
// Restore sticky content and navbar-toggler margin
$(`${Selector.STICKY_CONTENT}, ${Selector.NAVBAR_TOGGLER}`).each((index, element) => {
const margin = $(element).data('margin-right')
if (typeof margin !== 'undefined') {
$(element).css('margin-right', margin).removeData('margin-right')
}
})
// Restore body padding
const padding = $('body').data('padding-right')
if (typeof padding !== 'undefined') {
$('body').css('padding-right', padding).removeData('padding-right')
}
}
_getScrollbarWidth() { // thx d.walsh
const scrollDiv = document.createElement('div')
scrollDiv.className = ClassName.SCROLLBAR_MEASURER
document.body.appendChild(scrollDiv)
const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth
document.body.removeChild(scrollDiv)
return scrollbarWidth
}
// Static
static _jQueryInterface(config, relatedTarget) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _config = {
...Modal.Default,
...$(this).data(),
...typeof config === 'object' && config
}
if (!data) {
data = new Modal(this, _config)
$(this).data(DATA_KEY, data)
}
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {
throw new TypeError(`No method named "${config}"`)
}
data[config](relatedTarget)
} else if (_config.show) {
data.show(relatedTarget)
}
})
}
}
/**
* ------------------------------------------------------------------------
* Data Api implementation
* ------------------------------------------------------------------------
*/
$(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
let target
const selector = Util.getSelectorFromElement(this)
if (selector) {
target = $(selector)[0]
}
const config = $(target).data(DATA_KEY)
? 'toggle' : {
...$(target).data(),
...$(this).data()
}
if (this.tagName === 'A' || this.tagName === 'AREA') {
event.preventDefault()
}
const $target = $(target).one(Event.SHOW, (showEvent) => {
if (showEvent.isDefaultPrevented()) {
// Only register focus restorer if modal will actually get shown
return
}
$target.one(Event.HIDDEN, () => {
if ($(this).is(':visible')) {
this.focus()
}
})
})
Modal._jQueryInterface.call($(target), config, this)
})
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
*/
$.fn[NAME] = Modal._jQueryInterface
$.fn[NAME].Constructor = Modal
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Modal._jQueryInterface
}
return Modal
})($)
export default Modal
+2
View File
File diff suppressed because one or more lines are too long
+188
View File
@@ -0,0 +1,188 @@
import $ from 'jquery'
import Tooltip from './tooltip'
/**
* --------------------------------------------------------------------------
* Bootstrap (v4.0.0): popover.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* --------------------------------------------------------------------------
*/
const Popover = (($) => {
/**
* ------------------------------------------------------------------------
* Constants
* ------------------------------------------------------------------------
*/
const NAME = 'popover'
const VERSION = '4.0.0'
const DATA_KEY = 'bs.popover'
const EVENT_KEY = `.${DATA_KEY}`
const JQUERY_NO_CONFLICT = $.fn[NAME]
const CLASS_PREFIX = 'bs-popover'
const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g')
const Default = {
...Tooltip.Default,
placement : 'right',
trigger : 'click',
content : '',
template : '<div class="popover" role="tooltip">' +
'<div class="arrow"></div>' +
'<h3 class="popover-header"></h3>' +
'<div class="popover-body"></div></div>'
}
const DefaultType = {
...Tooltip.DefaultType,
content : '(string|element|function)'
}
const ClassName = {
FADE : 'fade',
SHOW : 'show'
}
const Selector = {
TITLE : '.popover-header',
CONTENT : '.popover-body'
}
const Event = {
HIDE : `hide${EVENT_KEY}`,
HIDDEN : `hidden${EVENT_KEY}`,
SHOW : `show${EVENT_KEY}`,
SHOWN : `shown${EVENT_KEY}`,
INSERTED : `inserted${EVENT_KEY}`,
CLICK : `click${EVENT_KEY}`,
FOCUSIN : `focusin${EVENT_KEY}`,
FOCUSOUT : `focusout${EVENT_KEY}`,
MOUSEENTER : `mouseenter${EVENT_KEY}`,
MOUSELEAVE : `mouseleave${EVENT_KEY}`
}
/**
* ------------------------------------------------------------------------
* Class Definition
* ------------------------------------------------------------------------
*/
class Popover extends Tooltip {
// Getters
static get VERSION() {
return VERSION
}
static get Default() {
return Default
}
static get NAME() {
return NAME
}
static get DATA_KEY() {
return DATA_KEY
}
static get Event() {
return Event
}
static get EVENT_KEY() {
return EVENT_KEY
}
static get DefaultType() {
return DefaultType
}
// Overrides
isWithContent() {
return this.getTitle() || this._getContent()
}
addAttachmentClass(attachment) {
$(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)
}
getTipElement() {
this.tip = this.tip || $(this.config.template)[0]
return this.tip
}
setContent() {
const $tip = $(this.getTipElement())
// We use append for html objects to maintain js events
this.setElementContent($tip.find(Selector.TITLE), this.getTitle())
let content = this._getContent()
if (typeof content === 'function') {
content = content.call(this.element)
}
this.setElementContent($tip.find(Selector.CONTENT), content)
$tip.removeClass(`${ClassName.FADE} ${ClassName.SHOW}`)
}
// Private
_getContent() {
return this.element.getAttribute('data-content') ||
this.config.content
}
_cleanTipClass() {
const $tip = $(this.getTipElement())
const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)
if (tabClass !== null && tabClass.length > 0) {
$tip.removeClass(tabClass.join(''))
}
}
// Static
static _jQueryInterface(config) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _config = typeof config === 'object' ? config : null
if (!data && /destroy|hide/.test(config)) {
return
}
if (!data) {
data = new Popover(this, _config)
$(this).data(DATA_KEY, data)
}
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {
throw new TypeError(`No method named "${config}"`)
}
data[config]()
}
})
}
}
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
*/
$.fn[NAME] = Popover._jQueryInterface
$.fn[NAME].Constructor = Popover
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Popover._jQueryInterface
}
return Popover
})($)
export default Popover
+509
View File
@@ -0,0 +1,509 @@
var webpage = "";
function supportstorage() {
if (typeof window.localStorage=='object')
return true;
else
return false;
}
function handleSaveLayout() {
var e = $(".demo").html();
if (!stopsave && e != window.demoHtml) {
stopsave++;
window.demoHtml = e;
saveLayout();
stopsave--;
}
}
var layouthistory;
function saveLayout(){
var data = layouthistory;
if (!data) {
data={};
data.count = 0;
data.list = [];
}
if (data.list.length>data.count) {
for (i=data.count;i<data.list.length;i++)
data.list[i]=null;
}
data.list[data.count] = window.demoHtml;
data.count++;
if (supportstorage()) {
localStorage.setItem("layoutdata",JSON.stringify(data));
}
layouthistory = data;
//console.log(data);
/*$.ajax({
type: "POST",
url: "/build/saveLayout",
data: { layout: $('.demo').html() },
success: function(data) {
//updateButtonsVisibility();
}
});*/
}
function downloadLayout(){
$.ajax({
type: "POST",
url: "/build/downloadLayout",
data: { layout: $('#download-layout').html() },
success: function(data) { window.location.href = '/build/download'; }
});
}
function downloadHtmlLayout(){
$.ajax({
type: "POST",
url: "/build/downloadLayout",
data: { layout: $('#download-layout').html() },
success: function(data) { window.location.href = '/build/downloadHtml'; }
});
}
function undoLayout() {
var data = layouthistory;
//console.log(data);
if (data) {
if (data.count<2) return false;
window.demoHtml = data.list[data.count-2];
data.count--;
$('.demo').html(window.demoHtml);
if (supportstorage()) {
localStorage.setItem("layoutdata",JSON.stringify(data));
}
return true;
}
return false;
/*$.ajax({
type: "POST",
url: "/build/getPreviousLayout",
data: { },
success: function(data) {
undoOperation(data);
}
});*/
}
function redoLayout() {
var data = layouthistory;
if (data) {
if (data.list[data.count]) {
window.demoHtml = data.list[data.count];
data.count++;
$('.demo').html(window.demoHtml);
if (supportstorage()) {
localStorage.setItem("layoutdata",JSON.stringify(data));
}
return true;
}
}
return false;
/*
$.ajax({
type: "POST",
url: "/build/getPreviousLayout",
data: { },
success: function(data) {
redoOperation(data);
}
});*/
}
function handleJsIds() {
handleModalIds();
handleAccordionIds();
handleCarouselIds();
handleTabsIds();
}
function handleAccordionIds() {
var e = $(".demo #myAccordion");
var t = randomNumber();
var n = "accordion-" + t;
var r;
e.attr("id", n);
e.find(".accordion-group").each(function(e, t) {
r = "accordion-element-" + randomNumber();
$(t).find(".accordion-toggle").each(function(e, t) {
$(t).attr("data-parent", "#" + n);
$(t).attr("href", "#" + r);
});
$(t).find(".accordion-body").each(function(e, t) {
$(t).attr("id", r);
});
});
}
function handleCarouselIds() {
var e = $(".demo #myCarousel");
var t = randomNumber();
var n = "carousel-" + t;
e.attr("id", n);
e.find(".carousel-indicators li").each(function(e, t) {
$(t).attr("data-target", "#" + n);
});
e.find(".left").attr("href", "#" + n);
e.find(".right").attr("href", "#" + n);
}
function handleModalIds() {
var e = $(".demo #myModalLink");
var t = randomNumber();
var n = "modal-container-" + t;
var r = "modal-" + t;
e.attr("id", r);
e.attr("href", "#" + n);
e.next().attr("id", n);
}
function handleTabsIds() {
var e = $(".demo #myTabs");
var t = randomNumber();
var n = "tabs-" + t;
e.attr("id", n);
e.find(".tab-pane").each(function(e, t) {
var n = $(t).attr("id");
var r = "panel-" + randomNumber();
$(t).attr("id", r);
$(t).parent().parent().find("a[href=#" + n + "]").attr("href", "#" + r);
});
}
function randomNumber() {
return randomFromInterval(1, 1e6);
}
function randomFromInterval(e, t) {
return Math.floor(Math.random() * (t - e + 1) + e);
}
function gridSystemGenerator() {
$(".lyrow .preview input").bind("keyup", function() {
var e = 0;
var t = "";
var n = $(this).val().split(" ", 12);
$.each(n, function(n, r) {
e = e + parseInt(r);
t += '<div class="span' + r + ' column"></div>';
});
if (e == 12) {
$(this).parent().next().children().html(t);
$(this).parent().prev().show();
} else {
$(this).parent().prev().hide();
}
});
}
function configurationElm(e, t) {
$(".demo").delegate(".configuration > a", "click", function(e) {
e.preventDefault();
var t = $(this).parent().next().next().children();
$(this).toggleClass("active");
t.toggleClass($(this).attr("rel"));
});
$(".demo").delegate(".configuration .dropdown-menu a", "click", function(e) {
e.preventDefault();
var t = $(this).parent().parent();
var n = t.parent().parent().next().next().children();
t.find("li").removeClass("active");
$(this).parent().addClass("active");
var r = "";
t.find("a").each(function() {
r += $(this).attr("rel") + " ";
});
t.parent().removeClass("open");
n.removeClass(r);
n.addClass($(this).attr("rel"));
});
}
function removeElm() {
$(".demo").delegate(".remove", "click", function(e) {
e.preventDefault();
$(this).parent().remove();
if (!$(".demo .lyrow").length > 0) {
clearDemo();
}
});
}
function clearDemo() {
$(".demo").empty();
layouthistory = null;
if (supportstorage())
localStorage.removeItem("layoutdata");
}
function removeMenuClasses() {
$("#menu-layoutit li button").removeClass("active");
}
function changeStructure(e, t) {
$("#download-layout ." + e).removeClass(e).addClass(t);
}
function cleanHtml(e) {
$(e).parent().append($(e).children().html());
}
function downloadLayoutSrc() {
var e = "";
$("#download-layout").children().html($(".demo").html());
var t = $("#download-layout").children();
t.find(".preview, .configuration, .drag, .remove").remove();
t.find(".lyrow").addClass("removeClean");
t.find(".box-element").addClass("removeClean");
t.find(".lyrow .lyrow .lyrow .lyrow .lyrow .removeClean").each(function() {
cleanHtml(this);
});
t.find(".lyrow .lyrow .lyrow .lyrow .removeClean").each(function() {
cleanHtml(this);
});
t.find(".lyrow .lyrow .lyrow .removeClean").each(function() {
cleanHtml(this);
});
t.find(".lyrow .lyrow .removeClean").each(function() {
cleanHtml(this);
});
t.find(".lyrow .removeClean").each(function() {
cleanHtml(this);
});
t.find(".removeClean").each(function() {
cleanHtml(this);
});
t.find(".removeClean").remove();
$("#download-layout .column").removeClass("ui-sortable");
$("#download-layout .row-fluid").removeClass("clearfix").children().removeClass("column");
if ($("#download-layout .container").length > 0) {
changeStructure("row-fluid", "row");
}
formatSrc = $.htmlClean($("#download-layout").html(), {
format: true,
allowedAttributes: [
["id"],
["class"],
["data-toggle"],
["data-target"],
["data-parent"],
["role"],
["data-dismiss"],
["aria-labelledby"],
["aria-hidden"],
["data-slide-to"],
["data-slide"]
]
});
$("#download-layout").html(formatSrc);
$("#downloadModal textarea").empty();
$("#downloadModal textarea").val(formatSrc);
webpage = formatSrc;
}
var currentDocument = null;
var timerSave = 1000;
var stopsave = 0;
var startdrag = 0;
var demoHtml = $(".demo").html();
var currenteditor = null;
// $(window).resize(function() {
// $("body").css("min-height", $(window).height() - 90);
// $(".demo").css("min-height", $(window).height() - 160)
// });
function restoreData(){
if (supportstorage()) {
layouthistory = JSON.parse(localStorage.getItem("layoutdata"));
if (!layouthistory) return false;
window.demoHtml = layouthistory.list[layouthistory.count-1];
if (window.demoHtml) $(".demo").html(window.demoHtml);
}
}
function initContainer(){
$(".demo, .demo .column").sortable({
connectWith: ".column",
opacity: .35,
handle: ".drag",
start: function(e,t) {
if (!startdrag) stopsave++;
startdrag = 1;
},
stop: function(e,t) {
if(stopsave>0) stopsave--;
startdrag = 0;
}
});
configurationElm();
}
$(document).ready(function() {
CKEDITOR.disableAutoInline = true;
restoreData();
var contenthandle = CKEDITOR.replace( 'contenteditor' ,{
language: 'en',
contentsCss: ['css/bootstrap-combined.min.css'],
allowedContent: true
});
// $("body").css("min-height", $(window).height() - 50);
// $(".demo").css("min-height", $(window).height() - 130);
$(".sidebar-nav .lyrow").draggable({
connectToSortable: ".demo",
helper: "clone",
handle: ".drag",
start: function(e,t) {
if (!startdrag) stopsave++;
startdrag = 1;
},
drag: function(e, t) {
t.helper.width(400);
},
stop: function(e, t) {
$(".demo .column").sortable({
opacity: .35,
connectWith: ".column",
start: function(e,t) {
if (!startdrag) stopsave++;
startdrag = 1;
},
stop: function(e,t) {
if(stopsave>0) stopsave--;
startdrag = 0;
}
});
if(stopsave>0) stopsave--;
startdrag = 0;
}
});
$(".sidebar-nav .box").draggable({
connectToSortable: ".column",
helper: "clone",
handle: ".drag",
start: function(e,t) {
if (!startdrag) stopsave++;
startdrag = 1;
},
drag: function(e, t) {
t.helper.width(400);
},
stop: function() {
handleJsIds();
if(stopsave>0) stopsave--;
startdrag = 0;
}
});
initContainer();
$('body.edit .demo').on("click","[data-target=#editorModal]",function(e) {
e.preventDefault();
currenteditor = $(this).parent().parent().find('.view');
var eText = currenteditor.html();
contenthandle.setData(eText);
});
$("#savecontent").click(function(e) {
e.preventDefault();
currenteditor.html(contenthandle.getData());
});
$("[data-target=#downloadModal]").click(function(e) {
e.preventDefault();
downloadLayoutSrc();
});
$("[data-target=#shareModal]").click(function(e) {
e.preventDefault();
handleSaveLayout();
});
$("#download").click(function() {
downloadLayout();
return false;
});
$("#downloadhtml").click(function() {
downloadHtmlLayout();
return false;
});
$("#edit").click(function() {
$("body").removeClass("devpreview sourcepreview");
$("body").addClass("edit");
removeMenuClasses();
$(this).addClass("active");
return false;
});
$("#clear").click(function(e) {
e.preventDefault();
clearDemo();
});
$("#devpreview").click(function() {
$("body").removeClass("edit sourcepreview");
$("body").addClass("devpreview");
removeMenuClasses();
$(this).addClass("active");
return false;
});
$("#sourcepreview").click(function() {
$("body").removeClass("edit");
$("body").addClass("devpreview sourcepreview");
removeMenuClasses();
$(this).addClass("active");
return false;
});
$("#fluidPage").click(function(e) {
e.preventDefault();
changeStructure("container", "container-fluid");
$("#fixedPage").removeClass("active");
$(this).addClass("active");
downloadLayoutSrc();
});
$("#fixedPage").click(function(e) {
e.preventDefault();
changeStructure("container-fluid", "container");
$("#fluidPage").removeClass("active");
$(this).addClass("active");
downloadLayoutSrc();
});
$(".nav-header").click(function() {
$(".sidebar-nav .boxes, .sidebar-nav .rows").hide();
$(this).next().slideDown();
});
$('#undo').click(function(){
stopsave++;
if (undoLayout()) initContainer();
stopsave--;
});
$('#redo').click(function(){
stopsave++;
if (redoLayout()) initContainer();
stopsave--;
});
removeElm();
gridSystemGenerator();
setInterval(function() {
handleSaveLayout();
}, timerSave);
var prevalue_sv = $('.sidebar-nav').css('overflow');
$('.popover-info').hover(function(){
$('.sidebar-nav').css('overflow', 'inherit');
}, function(){
$('.sidebar-nav').css('overflow', prevalue_sv);
});
});
function saveHtml()
{
var cpath = window.location.href;
cpath = cpath.substring(0, cpath.lastIndexOf("/"));
webpage = '<html>\n<head>\n<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet">\n<link href="'+cpath+'/css/bootstrap.min.css" rel="stylesheet" media="screen">\n<link href="'+cpath+'/css/other.css" rel="stylesheet">\n<link href="'+cpath+'/css/docs.min.css" rel="stylesheet" media="screen">\n<link href="'+cpath+'/css/toolbox.css" rel="stylesheet" media="stylesheet">\n</head>\n<body>\n'+ webpage +'\n<script type="text/javascript" src="'+cpath+'/js/jquery-2.0.0.min.js"></script>\n<script type="text/javascript" src="'+cpath+'/js/jquery-ui.js"></script>\n<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>\n<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.8.2/umd/popper.js"></script>\n<script type="text/javascript" src="'+cpath+'/js/bootstrap.js"></script>\n<script type="text/javascript" src="'+cpath+'/js/scrollspy.js"></script>\n<script type="text/javascript" src="'+cpath+'/js/tab.js"></script>\n<script type="text/javascript" src="'+cpath+'/js/dropdown.js"></script>\n<script type="text/javascript" src="'+cpath+'/js/modal.js"></script>\n<script type="text/javascript" src="'+cpath+'/js/collapse.js"></script>\n<script type="text/javascript" src="'+cpath+'/js/popover.js"></script>\n<script type="text/javascript" src="'+cpath+'/js/tooltip.js"></script>\n<script type="text/javascript" src="'+cpath+'/js/docs.min.js"></script>\n</body></html>';
/* FM aka Vegetam Added the function that save the file in the directory Downloads. Work only to Chrome Firefox And IE*/
if (navigator.appName =="Microsoft Internet Explorer" && window.ActiveXObject)
{
var locationFile = location.href.toString();
var dlg = false;
with(document){
ir=createElement('iframe');
ir.id='ifr';
ir.location='about.blank';
ir.style.display='none';
body.appendChild(ir);
with(getElementById('ifr').contentWindow.document){
open("text/html", "replace");
charset = "utf-8";
write(webpage);
close();
document.charset = "utf-8";
dlg = execCommand('SaveAs', false, locationFile+"webpage.html");
}
return dlg;
}
}
else{
webpage = webpage;
var blob = new Blob([webpage], {type: "text/html;charset=utf-8"});
saveAs(blob, "webpage.html");
}
}
+329
View File
@@ -0,0 +1,329 @@
import $ from 'jquery'
import Util from './util'
/**
* --------------------------------------------------------------------------
* Bootstrap (v4.0.0): scrollspy.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* --------------------------------------------------------------------------
*/
const ScrollSpy = (($) => {
/**
* ------------------------------------------------------------------------
* Constants
* ------------------------------------------------------------------------
*/
const NAME = 'scrollspy'
const VERSION = '4.0.0'
const DATA_KEY = 'bs.scrollspy'
const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
const JQUERY_NO_CONFLICT = $.fn[NAME]
const Default = {
offset : 10,
method : 'auto',
target : ''
}
const DefaultType = {
offset : 'number',
method : 'string',
target : '(string|element)'
}
const Event = {
ACTIVATE : `activate${EVENT_KEY}`,
SCROLL : `scroll${EVENT_KEY}`,
LOAD_DATA_API : `load${EVENT_KEY}${DATA_API_KEY}`
}
const ClassName = {
DROPDOWN_ITEM : 'dropdown-item',
DROPDOWN_MENU : 'dropdown-menu',
ACTIVE : 'active'
}
const Selector = {
DATA_SPY : '[data-spy="scroll"]',
ACTIVE : '.active',
NAV_LIST_GROUP : '.nav, .list-group',
NAV_LINKS : '.nav-link',
NAV_ITEMS : '.nav-item',
LIST_ITEMS : '.list-group-item',
DROPDOWN : '.dropdown',
DROPDOWN_ITEMS : '.dropdown-item',
DROPDOWN_TOGGLE : '.dropdown-toggle'
}
const OffsetMethod = {
OFFSET : 'offset',
POSITION : 'position'
}
/**
* ------------------------------------------------------------------------
* Class Definition
* ------------------------------------------------------------------------
*/
class ScrollSpy {
constructor(element, config) {
this._element = element
this._scrollElement = element.tagName === 'BODY' ? window : element
this._config = this._getConfig(config)
this._selector = `${this._config.target} ${Selector.NAV_LINKS},` +
`${this._config.target} ${Selector.LIST_ITEMS},` +
`${this._config.target} ${Selector.DROPDOWN_ITEMS}`
this._offsets = []
this._targets = []
this._activeTarget = null
this._scrollHeight = 0
$(this._scrollElement).on(Event.SCROLL, (event) => this._process(event))
this.refresh()
this._process()
}
// Getters
static get VERSION() {
return VERSION
}
static get Default() {
return Default
}
// Public
refresh() {
const autoMethod = this._scrollElement === this._scrollElement.window
? OffsetMethod.OFFSET : OffsetMethod.POSITION
const offsetMethod = this._config.method === 'auto'
? autoMethod : this._config.method
const offsetBase = offsetMethod === OffsetMethod.POSITION
? this._getScrollTop() : 0
this._offsets = []
this._targets = []
this._scrollHeight = this._getScrollHeight()
const targets = $.makeArray($(this._selector))
targets
.map((element) => {
let target
const targetSelector = Util.getSelectorFromElement(element)
if (targetSelector) {
target = $(targetSelector)[0]
}
if (target) {
const targetBCR = target.getBoundingClientRect()
if (targetBCR.width || targetBCR.height) {
// TODO (fat): remove sketch reliance on jQuery position/offset
return [
$(target)[offsetMethod]().top + offsetBase,
targetSelector
]
}
}
return null
})
.filter((item) => item)
.sort((a, b) => a[0] - b[0])
.forEach((item) => {
this._offsets.push(item[0])
this._targets.push(item[1])
})
}
dispose() {
$.removeData(this._element, DATA_KEY)
$(this._scrollElement).off(EVENT_KEY)
this._element = null
this._scrollElement = null
this._config = null
this._selector = null
this._offsets = null
this._targets = null
this._activeTarget = null
this._scrollHeight = null
}
// Private
_getConfig(config) {
config = {
...Default,
...config
}
if (typeof config.target !== 'string') {
let id = $(config.target).attr('id')
if (!id) {
id = Util.getUID(NAME)
$(config.target).attr('id', id)
}
config.target = `#${id}`
}
Util.typeCheckConfig(NAME, config, DefaultType)
return config
}
_getScrollTop() {
return this._scrollElement === window
? this._scrollElement.pageYOffset : this._scrollElement.scrollTop
}
_getScrollHeight() {
return this._scrollElement.scrollHeight || Math.max(
document.body.scrollHeight,
document.documentElement.scrollHeight
)
}
_getOffsetHeight() {
return this._scrollElement === window
? window.innerHeight : this._scrollElement.getBoundingClientRect().height
}
_process() {
const scrollTop = this._getScrollTop() + this._config.offset
const scrollHeight = this._getScrollHeight()
const maxScroll = this._config.offset +
scrollHeight -
this._getOffsetHeight()
if (this._scrollHeight !== scrollHeight) {
this.refresh()
}
if (scrollTop >= maxScroll) {
const target = this._targets[this._targets.length - 1]
if (this._activeTarget !== target) {
this._activate(target)
}
return
}
if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {
this._activeTarget = null
this._clear()
return
}
for (let i = this._offsets.length; i--;) {
const isActiveTarget = this._activeTarget !== this._targets[i] &&
scrollTop >= this._offsets[i] &&
(typeof this._offsets[i + 1] === 'undefined' ||
scrollTop < this._offsets[i + 1])
if (isActiveTarget) {
this._activate(this._targets[i])
}
}
}
_activate(target) {
this._activeTarget = target
this._clear()
let queries = this._selector.split(',')
// eslint-disable-next-line arrow-body-style
queries = queries.map((selector) => {
return `${selector}[data-target="${target}"],` +
`${selector}[href="${target}"]`
})
const $link = $(queries.join(','))
if ($link.hasClass(ClassName.DROPDOWN_ITEM)) {
$link.closest(Selector.DROPDOWN).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE)
$link.addClass(ClassName.ACTIVE)
} else {
// Set triggered link as active
$link.addClass(ClassName.ACTIVE)
// Set triggered links parents as active
// With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
$link.parents(Selector.NAV_LIST_GROUP).prev(`${Selector.NAV_LINKS}, ${Selector.LIST_ITEMS}`).addClass(ClassName.ACTIVE)
// Handle special case when .nav-link is inside .nav-item
$link.parents(Selector.NAV_LIST_GROUP).prev(Selector.NAV_ITEMS).children(Selector.NAV_LINKS).addClass(ClassName.ACTIVE)
}
$(this._scrollElement).trigger(Event.ACTIVATE, {
relatedTarget: target
})
}
_clear() {
$(this._selector).filter(Selector.ACTIVE).removeClass(ClassName.ACTIVE)
}
// Static
static _jQueryInterface(config) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _config = typeof config === 'object' && config
if (!data) {
data = new ScrollSpy(this, _config)
$(this).data(DATA_KEY, data)
}
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {
throw new TypeError(`No method named "${config}"`)
}
data[config]()
}
})
}
}
/**
* ------------------------------------------------------------------------
* Data Api implementation
* ------------------------------------------------------------------------
*/
$(window).on(Event.LOAD_DATA_API, () => {
const scrollSpys = $.makeArray($(Selector.DATA_SPY))
for (let i = scrollSpys.length; i--;) {
const $spy = $(scrollSpys[i])
ScrollSpy._jQueryInterface.call($spy, $spy.data())
}
})
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
*/
$.fn[NAME] = ScrollSpy._jQueryInterface
$.fn[NAME].Constructor = ScrollSpy
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return ScrollSpy._jQueryInterface
}
return ScrollSpy
})($)
export default ScrollSpy
Executable
+263
View File
@@ -0,0 +1,263 @@
import $ from 'jquery'
import Util from './util'
/**
* --------------------------------------------------------------------------
* Bootstrap (v4.0.0): tab.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* --------------------------------------------------------------------------
*/
const Tab = (($) => {
/**
* ------------------------------------------------------------------------
* Constants
* ------------------------------------------------------------------------
*/
const NAME = 'tab'
const VERSION = '4.0.0'
const DATA_KEY = 'bs.tab'
const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
const JQUERY_NO_CONFLICT = $.fn[NAME]
const TRANSITION_DURATION = 150
const Event = {
HIDE : `hide${EVENT_KEY}`,
HIDDEN : `hidden${EVENT_KEY}`,
SHOW : `show${EVENT_KEY}`,
SHOWN : `shown${EVENT_KEY}`,
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
}
const ClassName = {
DROPDOWN_MENU : 'dropdown-menu',
ACTIVE : 'active',
DISABLED : 'disabled',
FADE : 'fade',
SHOW : 'show'
}
const Selector = {
DROPDOWN : '.dropdown',
NAV_LIST_GROUP : '.nav, .list-group',
ACTIVE : '.active',
ACTIVE_UL : '> li > .active',
DATA_TOGGLE : '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',
DROPDOWN_TOGGLE : '.dropdown-toggle',
DROPDOWN_ACTIVE_CHILD : '> .dropdown-menu .active'
}
/**
* ------------------------------------------------------------------------
* Class Definition
* ------------------------------------------------------------------------
*/
class Tab {
constructor(element) {
this._element = element
}
// Getters
static get VERSION() {
return VERSION
}
// Public
show() {
if (this._element.parentNode &&
this._element.parentNode.nodeType === Node.ELEMENT_NODE &&
$(this._element).hasClass(ClassName.ACTIVE) ||
$(this._element).hasClass(ClassName.DISABLED)) {
return
}
let target
let previous
const listElement = $(this._element).closest(Selector.NAV_LIST_GROUP)[0]
const selector = Util.getSelectorFromElement(this._element)
if (listElement) {
const itemSelector = listElement.nodeName === 'UL' ? Selector.ACTIVE_UL : Selector.ACTIVE
previous = $.makeArray($(listElement).find(itemSelector))
previous = previous[previous.length - 1]
}
const hideEvent = $.Event(Event.HIDE, {
relatedTarget: this._element
})
const showEvent = $.Event(Event.SHOW, {
relatedTarget: previous
})
if (previous) {
$(previous).trigger(hideEvent)
}
$(this._element).trigger(showEvent)
if (showEvent.isDefaultPrevented() ||
hideEvent.isDefaultPrevented()) {
return
}
if (selector) {
target = $(selector)[0]
}
this._activate(
this._element,
listElement
)
const complete = () => {
const hiddenEvent = $.Event(Event.HIDDEN, {
relatedTarget: this._element
})
const shownEvent = $.Event(Event.SHOWN, {
relatedTarget: previous
})
$(previous).trigger(hiddenEvent)
$(this._element).trigger(shownEvent)
}
if (target) {
this._activate(target, target.parentNode, complete)
} else {
complete()
}
}
dispose() {
$.removeData(this._element, DATA_KEY)
this._element = null
}
// Private
_activate(element, container, callback) {
let activeElements
if (container.nodeName === 'UL') {
activeElements = $(container).find(Selector.ACTIVE_UL)
} else {
activeElements = $(container).children(Selector.ACTIVE)
}
const active = activeElements[0]
const isTransitioning = callback &&
Util.supportsTransitionEnd() &&
(active && $(active).hasClass(ClassName.FADE))
const complete = () => this._transitionComplete(
element,
active,
callback
)
if (active && isTransitioning) {
$(active)
.one(Util.TRANSITION_END, complete)
.emulateTransitionEnd(TRANSITION_DURATION)
} else {
complete()
}
}
_transitionComplete(element, active, callback) {
if (active) {
$(active).removeClass(`${ClassName.SHOW} ${ClassName.ACTIVE}`)
const dropdownChild = $(active.parentNode).find(
Selector.DROPDOWN_ACTIVE_CHILD
)[0]
if (dropdownChild) {
$(dropdownChild).removeClass(ClassName.ACTIVE)
}
if (active.getAttribute('role') === 'tab') {
active.setAttribute('aria-selected', false)
}
}
$(element).addClass(ClassName.ACTIVE)
if (element.getAttribute('role') === 'tab') {
element.setAttribute('aria-selected', true)
}
Util.reflow(element)
$(element).addClass(ClassName.SHOW)
if (element.parentNode &&
$(element.parentNode).hasClass(ClassName.DROPDOWN_MENU)) {
const dropdownElement = $(element).closest(Selector.DROPDOWN)[0]
if (dropdownElement) {
$(dropdownElement).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE)
}
element.setAttribute('aria-expanded', true)
}
if (callback) {
callback()
}
}
// Static
static _jQueryInterface(config) {
return this.each(function () {
const $this = $(this)
let data = $this.data(DATA_KEY)
if (!data) {
data = new Tab(this)
$this.data(DATA_KEY, data)
}
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {
throw new TypeError(`No method named "${config}"`)
}
data[config]()
}
})
}
}
/**
* ------------------------------------------------------------------------
* Data Api implementation
* ------------------------------------------------------------------------
*/
$(document)
.on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
event.preventDefault()
Tab._jQueryInterface.call($(this), 'show')
})
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
*/
$.fn[NAME] = Tab._jQueryInterface
$.fn[NAME].Constructor = Tab
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Tab._jQueryInterface
}
return Tab
})($)
export default Tab
Executable
+1811
View File
File diff suppressed because it is too large Load Diff
Vendored Executable
+4
View File
File diff suppressed because one or more lines are too long
+721
View File
@@ -0,0 +1,721 @@
import $ from 'jquery'
import Popper from 'popper.js'
import Util from './util'
/**
* --------------------------------------------------------------------------
* Bootstrap (v4.0.0): tooltip.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* --------------------------------------------------------------------------
*/
const Tooltip = (($) => {
/**
* ------------------------------------------------------------------------
* Constants
* ------------------------------------------------------------------------
*/
const NAME = 'tooltip'
const VERSION = '4.0.0'
const DATA_KEY = 'bs.tooltip'
const EVENT_KEY = `.${DATA_KEY}`
const JQUERY_NO_CONFLICT = $.fn[NAME]
const TRANSITION_DURATION = 150
const CLASS_PREFIX = 'bs-tooltip'
const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g')
const DefaultType = {
animation : 'boolean',
template : 'string',
title : '(string|element|function)',
trigger : 'string',
delay : '(number|object)',
html : 'boolean',
selector : '(string|boolean)',
placement : '(string|function)',
offset : '(number|string)',
container : '(string|element|boolean)',
fallbackPlacement : '(string|array)',
boundary : '(string|element)'
}
const AttachmentMap = {
AUTO : 'auto',
TOP : 'top',
RIGHT : 'right',
BOTTOM : 'bottom',
LEFT : 'left'
}
const Default = {
animation : true,
template : '<div class="tooltip" role="tooltip">' +
'<div class="arrow"></div>' +
'<div class="tooltip-inner"></div></div>',
trigger : 'hover focus',
title : '',
delay : 0,
html : false,
selector : false,
placement : 'top',
offset : 0,
container : false,
fallbackPlacement : 'flip',
boundary : 'scrollParent'
}
const HoverState = {
SHOW : 'show',
OUT : 'out'
}
const Event = {
HIDE : `hide${EVENT_KEY}`,
HIDDEN : `hidden${EVENT_KEY}`,
SHOW : `show${EVENT_KEY}`,
SHOWN : `shown${EVENT_KEY}`,
INSERTED : `inserted${EVENT_KEY}`,
CLICK : `click${EVENT_KEY}`,
FOCUSIN : `focusin${EVENT_KEY}`,
FOCUSOUT : `focusout${EVENT_KEY}`,
MOUSEENTER : `mouseenter${EVENT_KEY}`,
MOUSELEAVE : `mouseleave${EVENT_KEY}`
}
const ClassName = {
FADE : 'fade',
SHOW : 'show'
}
const Selector = {
TOOLTIP : '.tooltip',
TOOLTIP_INNER : '.tooltip-inner',
ARROW : '.arrow'
}
const Trigger = {
HOVER : 'hover',
FOCUS : 'focus',
CLICK : 'click',
MANUAL : 'manual'
}
/**
* ------------------------------------------------------------------------
* Class Definition
* ------------------------------------------------------------------------
*/
class Tooltip {
constructor(element, config) {
/**
* Check for Popper dependency
* Popper - https://popper.js.org
*/
if (typeof Popper === 'undefined') {
throw new TypeError('Bootstrap tooltips require Popper.js (https://popper.js.org)')
}
// private
this._isEnabled = true
this._timeout = 0
this._hoverState = ''
this._activeTrigger = {}
this._popper = null
// Protected
this.element = element
this.config = this._getConfig(config)
this.tip = null
this._setListeners()
}
// Getters
static get VERSION() {
return VERSION
}
static get Default() {
return Default
}
static get NAME() {
return NAME
}
static get DATA_KEY() {
return DATA_KEY
}
static get Event() {
return Event
}
static get EVENT_KEY() {
return EVENT_KEY
}
static get DefaultType() {
return DefaultType
}
// Public
enable() {
this._isEnabled = true
}
disable() {
this._isEnabled = false
}
toggleEnabled() {
this._isEnabled = !this._isEnabled
}
toggle(event) {
if (!this._isEnabled) {
return
}
if (event) {
const dataKey = this.constructor.DATA_KEY
let context = $(event.currentTarget).data(dataKey)
if (!context) {
context = new this.constructor(
event.currentTarget,
this._getDelegateConfig()
)
$(event.currentTarget).data(dataKey, context)
}
context._activeTrigger.click = !context._activeTrigger.click
if (context._isWithActiveTrigger()) {
context._enter(null, context)
} else {
context._leave(null, context)
}
} else {
if ($(this.getTipElement()).hasClass(ClassName.SHOW)) {
this._leave(null, this)
return
}
this._enter(null, this)
}
}
dispose() {
clearTimeout(this._timeout)
$.removeData(this.element, this.constructor.DATA_KEY)
$(this.element).off(this.constructor.EVENT_KEY)
$(this.element).closest('.modal').off('hide.bs.modal')
if (this.tip) {
$(this.tip).remove()
}
this._isEnabled = null
this._timeout = null
this._hoverState = null
this._activeTrigger = null
if (this._popper !== null) {
this._popper.destroy()
}
this._popper = null
this.element = null
this.config = null
this.tip = null
}
show() {
if ($(this.element).css('display') === 'none') {
throw new Error('Please use show on visible elements')
}
const showEvent = $.Event(this.constructor.Event.SHOW)
if (this.isWithContent() && this._isEnabled) {
$(this.element).trigger(showEvent)
const isInTheDom = $.contains(
this.element.ownerDocument.documentElement,
this.element
)
if (showEvent.isDefaultPrevented() || !isInTheDom) {
return
}
const tip = this.getTipElement()
const tipId = Util.getUID(this.constructor.NAME)
tip.setAttribute('id', tipId)
this.element.setAttribute('aria-describedby', tipId)
this.setContent()
if (this.config.animation) {
$(tip).addClass(ClassName.FADE)
}
const placement = typeof this.config.placement === 'function'
? this.config.placement.call(this, tip, this.element)
: this.config.placement
const attachment = this._getAttachment(placement)
this.addAttachmentClass(attachment)
const container = this.config.container === false ? document.body : $(this.config.container)
$(tip).data(this.constructor.DATA_KEY, this)
if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {
$(tip).appendTo(container)
}
$(this.element).trigger(this.constructor.Event.INSERTED)
this._popper = new Popper(this.element, tip, {
placement: attachment,
modifiers: {
offset: {
offset: this.config.offset
},
flip: {
behavior: this.config.fallbackPlacement
},
arrow: {
element: Selector.ARROW
},
preventOverflow: {
boundariesElement: this.config.boundary
}
},
onCreate: (data) => {
if (data.originalPlacement !== data.placement) {
this._handlePopperPlacementChange(data)
}
},
onUpdate: (data) => {
this._handlePopperPlacementChange(data)
}
})
$(tip).addClass(ClassName.SHOW)
// If this is a touch-enabled device we add extra
// empty mouseover listeners to the body's immediate children;
// only needed because of broken event delegation on iOS
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
if ('ontouchstart' in document.documentElement) {
$('body').children().on('mouseover', null, $.noop)
}
const complete = () => {
if (this.config.animation) {
this._fixTransition()
}
const prevHoverState = this._hoverState
this._hoverState = null
$(this.element).trigger(this.constructor.Event.SHOWN)
if (prevHoverState === HoverState.OUT) {
this._leave(null, this)
}
}
if (Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE)) {
$(this.tip)
.one(Util.TRANSITION_END, complete)
.emulateTransitionEnd(Tooltip._TRANSITION_DURATION)
} else {
complete()
}
}
}
hide(callback) {
const tip = this.getTipElement()
const hideEvent = $.Event(this.constructor.Event.HIDE)
const complete = () => {
if (this._hoverState !== HoverState.SHOW && tip.parentNode) {
tip.parentNode.removeChild(tip)
}
this._cleanTipClass()
this.element.removeAttribute('aria-describedby')
$(this.element).trigger(this.constructor.Event.HIDDEN)
if (this._popper !== null) {
this._popper.destroy()
}
if (callback) {
callback()
}
}
$(this.element).trigger(hideEvent)
if (hideEvent.isDefaultPrevented()) {
return
}
$(tip).removeClass(ClassName.SHOW)
// If this is a touch-enabled device we remove the extra
// empty mouseover listeners we added for iOS support
if ('ontouchstart' in document.documentElement) {
$('body').children().off('mouseover', null, $.noop)
}
this._activeTrigger[Trigger.CLICK] = false
this._activeTrigger[Trigger.FOCUS] = false
this._activeTrigger[Trigger.HOVER] = false
if (Util.supportsTransitionEnd() &&
$(this.tip).hasClass(ClassName.FADE)) {
$(tip)
.one(Util.TRANSITION_END, complete)
.emulateTransitionEnd(TRANSITION_DURATION)
} else {
complete()
}
this._hoverState = ''
}
update() {
if (this._popper !== null) {
this._popper.scheduleUpdate()
}
}
// Protected
isWithContent() {
return Boolean(this.getTitle())
}
addAttachmentClass(attachment) {
$(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)
}
getTipElement() {
this.tip = this.tip || $(this.config.template)[0]
return this.tip
}
setContent() {
const $tip = $(this.getTipElement())
this.setElementContent($tip.find(Selector.TOOLTIP_INNER), this.getTitle())
$tip.removeClass(`${ClassName.FADE} ${ClassName.SHOW}`)
}
setElementContent($element, content) {
const html = this.config.html
if (typeof content === 'object' && (content.nodeType || content.jquery)) {
// Content is a DOM node or a jQuery
if (html) {
if (!$(content).parent().is($element)) {
$element.empty().append(content)
}
} else {
$element.text($(content).text())
}
} else {
$element[html ? 'html' : 'text'](content)
}
}
getTitle() {
let title = this.element.getAttribute('data-original-title')
if (!title) {
title = typeof this.config.title === 'function'
? this.config.title.call(this.element)
: this.config.title
}
return title
}
// Private
_getAttachment(placement) {
return AttachmentMap[placement.toUpperCase()]
}
_setListeners() {
const triggers = this.config.trigger.split(' ')
triggers.forEach((trigger) => {
if (trigger === 'click') {
$(this.element).on(
this.constructor.Event.CLICK,
this.config.selector,
(event) => this.toggle(event)
)
} else if (trigger !== Trigger.MANUAL) {
const eventIn = trigger === Trigger.HOVER
? this.constructor.Event.MOUSEENTER
: this.constructor.Event.FOCUSIN
const eventOut = trigger === Trigger.HOVER
? this.constructor.Event.MOUSELEAVE
: this.constructor.Event.FOCUSOUT
$(this.element)
.on(
eventIn,
this.config.selector,
(event) => this._enter(event)
)
.on(
eventOut,
this.config.selector,
(event) => this._leave(event)
)
}
$(this.element).closest('.modal').on(
'hide.bs.modal',
() => this.hide()
)
})
if (this.config.selector) {
this.config = {
...this.config,
trigger: 'manual',
selector: ''
}
} else {
this._fixTitle()
}
}
_fixTitle() {
const titleType = typeof this.element.getAttribute('data-original-title')
if (this.element.getAttribute('title') ||
titleType !== 'string') {
this.element.setAttribute(
'data-original-title',
this.element.getAttribute('title') || ''
)
this.element.setAttribute('title', '')
}
}
_enter(event, context) {
const dataKey = this.constructor.DATA_KEY
context = context || $(event.currentTarget).data(dataKey)
if (!context) {
context = new this.constructor(
event.currentTarget,
this._getDelegateConfig()
)
$(event.currentTarget).data(dataKey, context)
}
if (event) {
context._activeTrigger[
event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER
] = true
}
if ($(context.getTipElement()).hasClass(ClassName.SHOW) ||
context._hoverState === HoverState.SHOW) {
context._hoverState = HoverState.SHOW
return
}
clearTimeout(context._timeout)
context._hoverState = HoverState.SHOW
if (!context.config.delay || !context.config.delay.show) {
context.show()
return
}
context._timeout = setTimeout(() => {
if (context._hoverState === HoverState.SHOW) {
context.show()
}
}, context.config.delay.show)
}
_leave(event, context) {
const dataKey = this.constructor.DATA_KEY
context = context || $(event.currentTarget).data(dataKey)
if (!context) {
context = new this.constructor(
event.currentTarget,
this._getDelegateConfig()
)
$(event.currentTarget).data(dataKey, context)
}
if (event) {
context._activeTrigger[
event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER
] = false
}
if (context._isWithActiveTrigger()) {
return
}
clearTimeout(context._timeout)
context._hoverState = HoverState.OUT
if (!context.config.delay || !context.config.delay.hide) {
context.hide()
return
}
context._timeout = setTimeout(() => {
if (context._hoverState === HoverState.OUT) {
context.hide()
}
}, context.config.delay.hide)
}
_isWithActiveTrigger() {
for (const trigger in this._activeTrigger) {
if (this._activeTrigger[trigger]) {
return true
}
}
return false
}
_getConfig(config) {
config = {
...this.constructor.Default,
...$(this.element).data(),
...config
}
if (typeof config.delay === 'number') {
config.delay = {
show: config.delay,
hide: config.delay
}
}
if (typeof config.title === 'number') {
config.title = config.title.toString()
}
if (typeof config.content === 'number') {
config.content = config.content.toString()
}
Util.typeCheckConfig(
NAME,
config,
this.constructor.DefaultType
)
return config
}
_getDelegateConfig() {
const config = {}
if (this.config) {
for (const key in this.config) {
if (this.constructor.Default[key] !== this.config[key]) {
config[key] = this.config[key]
}
}
}
return config
}
_cleanTipClass() {
const $tip = $(this.getTipElement())
const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)
if (tabClass !== null && tabClass.length > 0) {
$tip.removeClass(tabClass.join(''))
}
}
_handlePopperPlacementChange(data) {
this._cleanTipClass()
this.addAttachmentClass(this._getAttachment(data.placement))
}
_fixTransition() {
const tip = this.getTipElement()
const initConfigAnimation = this.config.animation
if (tip.getAttribute('x-placement') !== null) {
return
}
$(tip).removeClass(ClassName.FADE)
this.config.animation = false
this.hide()
this.show()
this.config.animation = initConfigAnimation
}
// Static
static _jQueryInterface(config) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _config = typeof config === 'object' && config
if (!data && /dispose|hide/.test(config)) {
return
}
if (!data) {
data = new Tooltip(this, _config)
$(this).data(DATA_KEY, data)
}
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {
throw new TypeError(`No method named "${config}"`)
}
data[config]()
}
})
}
}
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
*/
$.fn[NAME] = Tooltip._jQueryInterface
$.fn[NAME].Constructor = Tooltip
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Tooltip._jQueryInterface
}
return Tooltip
})($, Popper)
export default Tooltip
+1
View File
@@ -0,0 +1 @@
webpage = '<html>\n<head>\n<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet">\n<link href="'+cpath+'/css/bootstrap.min.css" rel="stylesheet" media="screen">\n<link href="'+cpath+'/css/other.css" rel="stylesheet">\n<link href="'+cpath+'/css/docs.min.css" rel="stylesheet" media="screen">\n<link href="'+cpath+'/css/toolbox.css" rel="stylesheet" media="stylesheet">\n</head>\n<body>\n'+ webpage +'\n<script type="text/javascript" src="'+cpath+'/js/jquery-2.0.0.min.js"></script>\n<script type="text/javascript" src="'+cpath+'/js/jquery-ui.js"></script>\n<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>\n<script type="text/javascript" src="'+cpath+'/js/bootstrap.js"></script>\n<script type="text/javascript" src="'+cpath+'/js/scrollspy.js"></script>\n<script type="text/javascript" src="'+cpath+'/js/tab.js"></script>\n<script type="text/javascript" src="'+cpath+'/js/dropdown.js"></script>\n<script type="text/javascript" src="'+cpath+'/js/modal.js"></script>\n<script type="text/javascript" src="'+cpath+'/js/collapse.js"></script>\n<script type="text/javascript" src="'+cpath+'/js/popover.js"></script>\n<script type="text/javascript" src="'+cpath+'/js/tooltip.js"></script>\n<script type="text/javascript" src="'+cpath+'/js/docs.min.js"></script>\n</body></html>'
Executable
+161
View File
@@ -0,0 +1,161 @@
import $ from 'jquery'
/**
* --------------------------------------------------------------------------
* Bootstrap (v4.0.0): util.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* --------------------------------------------------------------------------
*/
const Util = (($) => {
/**
* ------------------------------------------------------------------------
* Private TransitionEnd Helpers
* ------------------------------------------------------------------------
*/
let transition = false
const MAX_UID = 1000000
// Shoutout AngusCroll (https://goo.gl/pxwQGp)
function toType(obj) {
return {}.toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}
function getSpecialTransitionEndEvent() {
return {
bindType: transition.end,
delegateType: transition.end,
handle(event) {
if ($(event.target).is(this)) {
return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params
}
return undefined // eslint-disable-line no-undefined
}
}
}
function transitionEndTest() {
if (typeof window !== 'undefined' && window.QUnit) {
return false
}
return {
end: 'transitionend'
}
}
function transitionEndEmulator(duration) {
let called = false
$(this).one(Util.TRANSITION_END, () => {
called = true
})
setTimeout(() => {
if (!called) {
Util.triggerTransitionEnd(this)
}
}, duration)
return this
}
function setTransitionEndSupport() {
transition = transitionEndTest()
$.fn.emulateTransitionEnd = transitionEndEmulator
if (Util.supportsTransitionEnd()) {
$.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()
}
}
function escapeId(selector) {
// We escape IDs in case of special selectors (selector = '#myId:something')
// $.escapeSelector does not exist in jQuery < 3
selector = typeof $.escapeSelector === 'function' ? $.escapeSelector(selector).substr(1)
: selector.replace(/(:|\.|\[|\]|,|=|@)/g, '\\$1')
return selector
}
/**
* --------------------------------------------------------------------------
* Public Util Api
* --------------------------------------------------------------------------
*/
const Util = {
TRANSITION_END: 'bsTransitionEnd',
getUID(prefix) {
do {
// eslint-disable-next-line no-bitwise
prefix += ~~(Math.random() * MAX_UID) // "~~" acts like a faster Math.floor() here
} while (document.getElementById(prefix))
return prefix
},
getSelectorFromElement(element) {
let selector = element.getAttribute('data-target')
if (!selector || selector === '#') {
selector = element.getAttribute('href') || ''
}
// If it's an ID
if (selector.charAt(0) === '#') {
selector = escapeId(selector)
}
try {
const $selector = $(document).find(selector)
return $selector.length > 0 ? selector : null
} catch (err) {
return null
}
},
reflow(element) {
return element.offsetHeight
},
triggerTransitionEnd(element) {
$(element).trigger(transition.end)
},
supportsTransitionEnd() {
return Boolean(transition)
},
isElement(obj) {
return (obj[0] || obj).nodeType
},
typeCheckConfig(componentName, config, configTypes) {
for (const property in configTypes) {
if (Object.prototype.hasOwnProperty.call(configTypes, property)) {
const expectedTypes = configTypes[property]
const value = config[property]
const valueType = value && Util.isElement(value)
? 'element' : toType(value)
if (!new RegExp(expectedTypes).test(valueType)) {
throw new Error(
`${componentName.toUpperCase()}: ` +
`Option "${property}" provided type "${valueType}" ` +
`but expected type "${expectedTypes}".`)
}
}
}
}
}
setTransitionEndSupport()
return Util
})($)
export default Util
Vendored Executable
+166
View File
@@ -0,0 +1,166 @@
/* Blob.js
* A Blob implementation.
* 2013-12-27
*
* By Eli Grey, http://eligrey.com
* By Devin Samarin, https://github.com/eboyjr
* License: X11/MIT
* See LICENSE.md
*/
/*global self, unescape */
/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
plusplus: true */
/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
if (!(typeof Blob === "function" || typeof Blob === "object") || typeof URL === "undefined")
if ((typeof Blob === "function" || typeof Blob === "object") && typeof webkitURL !== "undefined") self.URL = webkitURL;
else var Blob = (function (view) {
"use strict";
var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || view.MSBlobBuilder || (function(view) {
var
get_class = function(object) {
return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
}
, FakeBlobBuilder = function BlobBuilder() {
this.data = [];
}
, FakeBlob = function Blob(data, type, encoding) {
this.data = data;
this.size = data.length;
this.type = type;
this.encoding = encoding;
}
, FBB_proto = FakeBlobBuilder.prototype
, FB_proto = FakeBlob.prototype
, FileReaderSync = view.FileReaderSync
, FileException = function(type) {
this.code = this[this.name = type];
}
, file_ex_codes = (
"NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "
+ "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
).split(" ")
, file_ex_code = file_ex_codes.length
, real_URL = view.URL || view.webkitURL || view
, real_create_object_URL = real_URL.createObjectURL
, real_revoke_object_URL = real_URL.revokeObjectURL
, URL = real_URL
, btoa = view.btoa
, atob = view.atob
, ArrayBuffer = view.ArrayBuffer
, Uint8Array = view.Uint8Array
;
FakeBlob.fake = FB_proto.fake = true;
while (file_ex_code--) {
FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
}
if (!real_URL.createObjectURL) {
URL = view.URL = {};
}
URL.createObjectURL = function(blob) {
var
type = blob.type
, data_URI_header
;
if (type === null) {
type = "application/octet-stream";
}
if (blob instanceof FakeBlob) {
data_URI_header = "data:" + type;
if (blob.encoding === "base64") {
return data_URI_header + ";base64," + blob.data;
} else if (blob.encoding === "URI") {
return data_URI_header + "," + decodeURIComponent(blob.data);
} if (btoa) {
return data_URI_header + ";base64," + btoa(blob.data);
} else {
return data_URI_header + "," + encodeURIComponent(blob.data);
}
} else if (real_create_object_URL) {
return real_create_object_URL.call(real_URL, blob);
}
};
URL.revokeObjectURL = function(object_URL) {
if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
real_revoke_object_URL.call(real_URL, object_URL);
}
};
FBB_proto.append = function(data/*, endings*/) {
var bb = this.data;
// decode data to a binary string
if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
var
str = ""
, buf = new Uint8Array(data)
, i = 0
, buf_len = buf.length
;
for (; i < buf_len; i++) {
str += String.fromCharCode(buf[i]);
}
bb.push(str);
} else if (get_class(data) === "Blob" || get_class(data) === "File") {
if (FileReaderSync) {
var fr = new FileReaderSync;
bb.push(fr.readAsBinaryString(data));
} else {
// async FileReader won't work as BlobBuilder is sync
throw new FileException("NOT_READABLE_ERR");
}
} else if (data instanceof FakeBlob) {
if (data.encoding === "base64" && atob) {
bb.push(atob(data.data));
} else if (data.encoding === "URI") {
bb.push(decodeURIComponent(data.data));
} else if (data.encoding === "raw") {
bb.push(data.data);
}
} else {
if (typeof data !== "string") {
data += ""; // convert unsupported types to strings
}
// decode UTF-16 to binary string
bb.push(unescape(encodeURIComponent(data)));
}
};
FBB_proto.getBlob = function(type) {
if (!arguments.length) {
type = null;
}
return new FakeBlob(this.data.join(""), type, "raw");
};
FBB_proto.toString = function() {
return "[object BlobBuilder]";
};
FB_proto.slice = function(start, end, type) {
var args = arguments.length;
if (args < 3) {
type = null;
}
return new FakeBlob(
this.data.slice(start, args > 1 ? end : this.data.length)
, type
, this.encoding
);
};
FB_proto.toString = function() {
return "[object Blob]";
};
return FakeBlobBuilder;
}(view));
return function Blob(blobParts, options) {
var type = options ? (options.type || "") : "";
var builder = new BlobBuilder();
if (blobParts) {
for (var i = 0, len = blobParts.length; i < len; i++) {
builder.append(blobParts[i]);
}
}
return builder.getBlob(type);
};
}(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content || this));
Vendored Executable
+242
View File
@@ -0,0 +1,242 @@
/* FileSaver.js
* A saveAs() FileSaver implementation.
* 2014-01-24
*
* By Eli Grey, http://eligrey.com
* License: X11/MIT
* See LICENSE.md
*/
/*global self */
/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
plusplus: true */
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
var saveAs = saveAs
// IE 10+ (native saveAs)
|| (navigator.msSaveOrOpenBlob && navigator.msSaveOrOpenBlob.bind(navigator))
// Everyone else
|| (function(view) {
"use strict";
// IE <10 is explicitly unsupported
if (/MSIE [1-9]\./.test(navigator.userAgent)) {
return;
}
var
doc = view.document
// only get URL when necessary in case BlobBuilder.js hasn't overridden it yet
, get_URL = function() {
return view.URL || view.webkitURL || view;
}
, URL = view.URL || view.webkitURL || view
, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
, can_use_save_link = !view.externalHost && "download" in save_link
, click = function(node) {
var event = doc.createEvent("MouseEvents");
event.initMouseEvent(
"click", true, false, view, 0, 0, 0, 0, 0
, false, false, false, false, 0, null
);
node.dispatchEvent(event);
}
, webkit_req_fs = view.webkitRequestFileSystem
, req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem
, throw_outside = function (ex) {
(view.setImmediate || view.setTimeout)(function() {
throw ex;
}, 0);
}
, force_saveable_type = "application/octet-stream"
, fs_min_size = 0
, deletion_queue = []
, process_deletion_queue = function() {
var i = deletion_queue.length;
while (i--) {
var file = deletion_queue[i];
if (typeof file === "string") { // file is an object URL
URL.revokeObjectURL(file);
} else { // file is a File
file.remove();
}
}
deletion_queue.length = 0; // clear queue
}
, dispatch = function(filesaver, event_types, event) {
event_types = [].concat(event_types);
var i = event_types.length;
while (i--) {
var listener = filesaver["on" + event_types[i]];
if (typeof listener === "function") {
try {
listener.call(filesaver, event || filesaver);
} catch (ex) {
throw_outside(ex);
}
}
}
}
, FileSaver = function(blob, name) {
// First try a.download, then web filesystem, then object URLs
var
filesaver = this
, type = blob.type
, blob_changed = false
, object_url
, target_view
, get_object_url = function() {
var object_url = get_URL().createObjectURL(blob);
deletion_queue.push(object_url);
return object_url;
}
, dispatch_all = function() {
dispatch(filesaver, "writestart progress write writeend".split(" "));
}
// on any filesys errors revert to saving with object URLs
, fs_error = function() {
// don't create more object URLs than needed
if (blob_changed || !object_url) {
object_url = get_object_url(blob);
}
if (target_view) {
target_view.location.href = object_url;
} else {
window.open(object_url, "_blank");
}
filesaver.readyState = filesaver.DONE;
dispatch_all();
}
, abortable = function(func) {
return function() {
if (filesaver.readyState !== filesaver.DONE) {
return func.apply(this, arguments);
}
};
}
, create_if_not_found = {create: true, exclusive: false}
, slice
;
filesaver.readyState = filesaver.INIT;
if (!name) {
name = "download";
}
if (can_use_save_link) {
object_url = get_object_url(blob);
// FF for Android has a nasty garbage collection mechanism
// that turns all objects that are not pure javascript into 'deadObject'
// this means `doc` and `save_link` are unusable and need to be recreated
// `view` is usable though:
doc = view.document;
save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a");
save_link.href = object_url;
save_link.download = name;
var event = doc.createEvent("MouseEvents");
event.initMouseEvent(
"click", true, false, view, 0, 0, 0, 0, 0
, false, false, false, false, 0, null
);
save_link.dispatchEvent(event);
filesaver.readyState = filesaver.DONE;
dispatch_all();
return;
}
// Object and web filesystem URLs have a problem saving in Google Chrome when
// viewed in a tab, so I force save with application/octet-stream
// http://code.google.com/p/chromium/issues/detail?id=91158
if (view.chrome && type && type !== force_saveable_type) {
slice = blob.slice || blob.webkitSlice;
blob = slice.call(blob, 0, blob.size, force_saveable_type);
blob_changed = true;
}
// Since I can't be sure that the guessed media type will trigger a download
// in WebKit, I append .download to the filename.
// https://bugs.webkit.org/show_bug.cgi?id=65440
if (webkit_req_fs && name !== "download") {
name += ".download";
}
if (type === force_saveable_type || webkit_req_fs) {
target_view = view;
}
if (!req_fs) {
fs_error();
return;
}
fs_min_size += blob.size;
req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) {
fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) {
var save = function() {
dir.getFile(name, create_if_not_found, abortable(function(file) {
file.createWriter(abortable(function(writer) {
writer.onwriteend = function(event) {
target_view.location.href = file.toURL();
deletion_queue.push(file);
filesaver.readyState = filesaver.DONE;
dispatch(filesaver, "writeend", event);
};
writer.onerror = function() {
var error = writer.error;
if (error.code !== error.ABORT_ERR) {
fs_error();
}
};
"writestart progress write abort".split(" ").forEach(function(event) {
writer["on" + event] = filesaver["on" + event];
});
writer.write(blob);
filesaver.abort = function() {
writer.abort();
filesaver.readyState = filesaver.DONE;
};
filesaver.readyState = filesaver.WRITING;
}), fs_error);
}), fs_error);
};
dir.getFile(name, {create: false}, abortable(function(file) {
// delete file if it already exists
file.remove();
save();
}), abortable(function(ex) {
if (ex.code === ex.NOT_FOUND_ERR) {
save();
} else {
fs_error();
}
}));
}), fs_error);
}), fs_error);
}
, FS_proto = FileSaver.prototype
, saveAs = function(blob, name) {
return new FileSaver(blob, name);
}
;
FS_proto.abort = function() {
var filesaver = this;
filesaver.readyState = filesaver.DONE;
dispatch(filesaver, "abort");
};
FS_proto.readyState = FS_proto.INIT = 0;
FS_proto.WRITING = 1;
FS_proto.DONE = 2;
FS_proto.error =
FS_proto.onwritestart =
FS_proto.onprogress =
FS_proto.onwrite =
FS_proto.onabort =
FS_proto.onerror =
FS_proto.onwriteend =
null;
view.addEventListener("unload", process_deletion_queue, false);
return saveAs;
}(
typeof self !== "undefined" && self
|| typeof window !== "undefined" && window
|| this.content
));
// `self` is undefined in Firefox for Android content script context
// while `this` is nsIContentFrameMessageManager
// with an attribute `content` that corresponds to the window
if (typeof module !== "undefined") module.exports = saveAs;
Vendored Executable
+648
View File
@@ -0,0 +1,648 @@
/*!
Holder - 2.3.1 - client side image placeholders
(c) 2012-2014 Ivan Malopinsky / http://imsky.co
Provided under the MIT License.
Commercial use requires attribution.
*/
var Holder = Holder || {};
(function (app, win) {
var system_config = {
use_svg: false,
use_canvas: false,
use_fallback: false
};
var instance_config = {};
var preempted = false;
canvas = document.createElement('canvas');
var dpr = 1, bsr = 1;
var resizable_images = [];
if (!canvas.getContext) {
system_config.use_fallback = true;
} else {
if (canvas.toDataURL("image/png")
.indexOf("data:image/png") < 0) {
//Android doesn't support data URI
system_config.use_fallback = true;
} else {
var ctx = canvas.getContext("2d");
}
}
if(!!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect){
system_config.use_svg = true;
system_config.use_canvas = false;
}
if(!system_config.use_fallback){
dpr = window.devicePixelRatio || 1,
bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1;
}
var ratio = dpr / bsr;
var settings = {
domain: "holder.js",
images: "img",
bgnodes: ".holderjs",
themes: {
"gray": {
background: "#eee",
foreground: "#aaa",
size: 12
},
"social": {
background: "#3a5a97",
foreground: "#fff",
size: 12
},
"industrial": {
background: "#434A52",
foreground: "#C2F200",
size: 12
},
"sky": {
background: "#0D8FDB",
foreground: "#fff",
size: 12
},
"vine": {
background: "#39DBAC",
foreground: "#1E292C",
size: 12
},
"lava": {
background: "#F8591A",
foreground: "#1C2846",
size: 12
}
},
stylesheet: ""
};
app.flags = {
dimensions: {
regex: /^(\d+)x(\d+)$/,
output: function (val) {
var exec = this.regex.exec(val);
return {
width: +exec[1],
height: +exec[2]
}
}
},
fluid: {
regex: /^([0-9%]+)x([0-9%]+)$/,
output: function (val) {
var exec = this.regex.exec(val);
return {
width: exec[1],
height: exec[2]
}
}
},
colors: {
regex: /#([0-9a-f]{3,})\:#([0-9a-f]{3,})/i,
output: function (val) {
var exec = this.regex.exec(val);
return {
size: settings.themes.gray.size,
foreground: "#" + exec[2],
background: "#" + exec[1]
}
}
},
text: {
regex: /text\:(.*)/,
output: function (val) {
return this.regex.exec(val)[1];
}
},
font: {
regex: /font\:(.*)/,
output: function (val) {
return this.regex.exec(val)[1];
}
},
auto: {
regex: /^auto$/
},
textmode: {
regex: /textmode\:(.*)/,
output: function(val){
return this.regex.exec(val)[1];
}
}
}
function text_size(width, height, template) {
height = parseInt(height, 10);
width = parseInt(width, 10);
var bigSide = Math.max(height, width)
var smallSide = Math.min(height, width)
var scale = 1 / 12;
var newHeight = Math.min(smallSide * 0.75, 0.75 * bigSide * scale);
return {
height: Math.round(Math.max(template.size, newHeight))
}
}
var svg_el = (function(){
//Prevent IE <9 from initializing SVG renderer
if(!window.XMLSerializer) return;
var serializer = new XMLSerializer();
var svg_ns = "http://www.w3.org/2000/svg"
var svg = document.createElementNS(svg_ns, "svg");
//IE throws an exception if this is set and Chrome requires it to be set
if(svg.webkitMatchesSelector){
svg.setAttribute("xmlns", "http://www.w3.org/2000/svg")
}
var bg_el = document.createElementNS(svg_ns, "rect")
var text_el = document.createElementNS(svg_ns, "text")
var textnode_el = document.createTextNode(null)
text_el.setAttribute("text-anchor", "middle")
text_el.appendChild(textnode_el)
svg.appendChild(bg_el)
svg.appendChild(text_el)
return function(props){
svg.setAttribute("width",props.width);
svg.setAttribute("height", props.height);
bg_el.setAttribute("width", props.width);
bg_el.setAttribute("height", props.height);
bg_el.setAttribute("fill", props.template.background);
text_el.setAttribute("x", props.width/2)
text_el.setAttribute("y", props.height/2)
textnode_el.nodeValue=props.text
text_el.setAttribute("style", css_properties({
"fill": props.template.foreground,
"font-weight": "bold",
"font-size": props.text_height+"px",
"font-family":props.font,
"dominant-baseline":"central"
}))
return serializer.serializeToString(svg)
}
})()
function css_properties(props){
var ret = [];
for(p in props){
if(props.hasOwnProperty(p)){
ret.push(p+":"+props[p])
}
}
return ret.join(";")
}
function draw_canvas(args) {
var ctx = args.ctx,
dimensions = args.dimensions,
template = args.template,
ratio = args.ratio,
holder = args.holder,
literal = holder.textmode == "literal",
exact = holder.textmode == "exact";
var ts = text_size(dimensions.width, dimensions.height, template);
var text_height = ts.height;
var width = dimensions.width * ratio,
height = dimensions.height * ratio;
var font = template.font ? template.font : "Arial,Helvetica,sans-serif";
canvas.width = width;
canvas.height = height;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle = template.background;
ctx.fillRect(0, 0, width, height);
ctx.fillStyle = template.foreground;
ctx.font = "bold " + text_height + "px " + font;
var text = template.text ? template.text : (Math.floor(dimensions.width) + "x" + Math.floor(dimensions.height));
if (literal) {
var dimensions = holder.dimensions;
text = dimensions.width + "x" + dimensions.height;
}
else if(exact && holder.exact_dimensions){
var dimensions = holder.exact_dimensions;
text = (Math.floor(dimensions.width) + "x" + Math.floor(dimensions.height));
}
var text_width = ctx.measureText(text).width;
if (text_width / width >= 0.75) {
text_height = Math.floor(text_height * 0.75 * (width / text_width));
}
//Resetting font size if necessary
ctx.font = "bold " + (text_height * ratio) + "px " + font;
ctx.fillText(text, (width / 2), (height / 2), width);
return canvas.toDataURL("image/png");
}
function draw_svg(args){
var dimensions = args.dimensions,
template = args.template,
holder = args.holder,
literal = holder.textmode == "literal",
exact = holder.textmode == "exact";
var ts = text_size(dimensions.width, dimensions.height, template);
var text_height = ts.height;
var width = dimensions.width,
height = dimensions.height;
var font = template.font ? template.font : "Arial,Helvetica,sans-serif";
var text = template.text ? template.text : (Math.floor(dimensions.width) + "x" + Math.floor(dimensions.height));
if (literal) {
var dimensions = holder.dimensions;
text = dimensions.width + "x" + dimensions.height;
}
else if(exact && holder.exact_dimensions){
var dimensions = holder.exact_dimensions;
text = (Math.floor(dimensions.width) + "x" + Math.floor(dimensions.height));
}
var string = svg_el({
text: text,
width:width,
height:height,
text_height:text_height,
font:font,
template:template
})
return "data:image/svg+xml;base64,"+btoa(string);
}
function draw(args) {
if(instance_config.use_canvas && !instance_config.use_svg){
return draw_canvas(args);
}
else{
return draw_svg(args);
}
}
function render(mode, el, holder, src) {
var dimensions = holder.dimensions,
theme = holder.theme,
text = holder.text ? decodeURIComponent(holder.text) : holder.text;
var dimensions_caption = dimensions.width + "x" + dimensions.height;
theme = (text ? extend(theme, {
text: text
}) : theme);
theme = (holder.font ? extend(theme, {
font: holder.font
}) : theme);
el.setAttribute("data-src", src);
holder.theme = theme;
el.holder_data = holder;
if (mode == "image") {
el.setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption);
if (instance_config.use_fallback || !holder.auto) {
el.style.width = dimensions.width + "px";
el.style.height = dimensions.height + "px";
}
if (instance_config.use_fallback) {
el.style.backgroundColor = theme.background;
} else {
el.setAttribute("src", draw({ctx: ctx, dimensions: dimensions, template: theme, ratio:ratio, holder: holder}));
if(holder.textmode && holder.textmode == "exact"){
resizable_images.push(el);
resizable_update(el);
}
}
} else if (mode == "background") {
if (!instance_config.use_fallback) {
el.style.backgroundImage = "url(" + draw({ctx:ctx, dimensions: dimensions, template: theme, ratio: ratio, holder: holder}) + ")";
el.style.backgroundSize = dimensions.width + "px " + dimensions.height + "px";
}
} else if (mode == "fluid") {
el.setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption);
if (dimensions.height.slice(-1) == "%") {
el.style.height = dimensions.height
} else if(holder.auto == null || !holder.auto){
el.style.height = dimensions.height + "px"
}
if (dimensions.width.slice(-1) == "%") {
el.style.width = dimensions.width
} else if(holder.auto == null || !holder.auto){
el.style.width = dimensions.width + "px"
}
if (el.style.display == "inline" || el.style.display === "" || el.style.display == "none") {
el.style.display = "block";
}
set_initial_dimensions(el)
if (instance_config.use_fallback) {
el.style.backgroundColor = theme.background;
} else {
resizable_images.push(el);
resizable_update(el);
}
}
}
function dimension_check(el, callback) {
var dimensions = {
height: el.clientHeight,
width: el.clientWidth
};
if (!dimensions.height && !dimensions.width) {
el.setAttribute("data-holder-invisible", true)
callback.call(this, el)
}
else{
el.removeAttribute("data-holder-invisible")
return dimensions;
}
}
function set_initial_dimensions(el){
if(el.holder_data){
var dimensions = dimension_check(el, app.invisible_error_fn( set_initial_dimensions))
if(dimensions){
var holder = el.holder_data;
holder.initial_dimensions = dimensions;
holder.fluid_data = {
fluid_height: holder.dimensions.height.slice(-1) == "%",
fluid_width: holder.dimensions.width.slice(-1) == "%",
mode: null
}
if(holder.fluid_data.fluid_width && !holder.fluid_data.fluid_height){
holder.fluid_data.mode = "width"
holder.fluid_data.ratio = holder.initial_dimensions.width / parseFloat(holder.dimensions.height)
}
else if(!holder.fluid_data.fluid_width && holder.fluid_data.fluid_height){
holder.fluid_data.mode = "height";
holder.fluid_data.ratio = parseFloat(holder.dimensions.width) / holder.initial_dimensions.height
}
}
}
}
function resizable_update(element) {
var images;
if (element.nodeType == null) {
images = resizable_images;
} else {
images = [element]
}
for (var i in images) {
if (!images.hasOwnProperty(i)) {
continue;
}
var el = images[i]
if (el.holder_data) {
var holder = el.holder_data;
var dimensions = dimension_check(el, app.invisible_error_fn( resizable_update))
if(dimensions){
if(holder.fluid){
if(holder.auto){
switch(holder.fluid_data.mode){
case "width":
dimensions.height = dimensions.width / holder.fluid_data.ratio;
break;
case "height":
dimensions.width = dimensions.height * holder.fluid_data.ratio;
break;
}
}
el.setAttribute("src", draw({
ctx: ctx,
dimensions: dimensions,
template: holder.theme,
ratio: ratio,
holder: holder
}))
}
if(holder.textmode && holder.textmode == "exact"){
holder.exact_dimensions = dimensions;
el.setAttribute("src", draw({
ctx: ctx,
dimensions: holder.dimensions,
template: holder.theme,
ratio: ratio,
holder: holder
}))
}
}
}
}
}
function parse_flags(flags, options) {
var ret = {
theme: extend(settings.themes.gray, {})
};
var render = false;
for (var fl = flags.length, j = 0; j < fl; j++) {
var flag = flags[j];
if (app.flags.dimensions.match(flag)) {
render = true;
ret.dimensions = app.flags.dimensions.output(flag);
} else if (app.flags.fluid.match(flag)) {
render = true;
ret.dimensions = app.flags.fluid.output(flag);
ret.fluid = true;
} else if (app.flags.textmode.match(flag)) {
ret.textmode = app.flags.textmode.output(flag)
} else if (app.flags.colors.match(flag)) {
ret.theme = app.flags.colors.output(flag);
} else if (options.themes[flag]) {
//If a theme is specified, it will override custom colors
if(options.themes.hasOwnProperty(flag)){
ret.theme = extend(options.themes[flag], {});
}
} else if (app.flags.font.match(flag)) {
ret.font = app.flags.font.output(flag);
} else if (app.flags.auto.match(flag)) {
ret.auto = true;
} else if (app.flags.text.match(flag)) {
ret.text = app.flags.text.output(flag);
}
}
return render ? ret : false;
}
for (var flag in app.flags) {
if (!app.flags.hasOwnProperty(flag)) continue;
app.flags[flag].match = function (val) {
return val.match(this.regex)
}
}
app.invisible_error_fn = function(fn){
return function(el){
if(el.hasAttribute("data-holder-invisible")){
throw new Error("Holder: invisible placeholder")
}
}
}
app.add_theme = function (name, theme) {
name != null && theme != null && (settings.themes[name] = theme);
return app;
};
app.add_image = function (src, el) {
var node = selector(el);
if (node.length) {
for (var i = 0, l = node.length; i < l; i++) {
var img = document.createElement("img")
img.setAttribute("data-src", src);
node[i].appendChild(img);
}
}
return app;
};
app.run = function (o) {
instance_config = extend({}, system_config)
preempted = true;
var options = extend(settings, o),
images = [],
imageNodes = [],
bgnodes = [];
if(options.use_canvas != null && options.use_canvas){
instance_config.use_canvas = true;
instance_config.use_svg = false;
}
if (typeof (options.images) == "string") {
imageNodes = selector(options.images);
} else if (window.NodeList && options.images instanceof window.NodeList) {
imageNodes = options.images;
} else if (window.Node && options.images instanceof window.Node) {
imageNodes = [options.images];
} else if(window.HTMLCollection && options.images instanceof window.HTMLCollection){
imageNodes = options.images
}
if (typeof (options.bgnodes) == "string") {
bgnodes = selector(options.bgnodes);
} else if (window.NodeList && options.elements instanceof window.NodeList) {
bgnodes = options.bgnodes;
} else if (window.Node && options.bgnodes instanceof window.Node) {
bgnodes = [options.bgnodes];
}
for (i = 0, l = imageNodes.length; i < l; i++) images.push(imageNodes[i]);
var holdercss = document.getElementById("holderjs-style");
if (!holdercss) {
holdercss = document.createElement("style");
holdercss.setAttribute("id", "holderjs-style");
holdercss.type = "text/css";
document.getElementsByTagName("head")[0].appendChild(holdercss);
}
if (!options.nocss) {
if (holdercss.styleSheet) {
holdercss.styleSheet.cssText += options.stylesheet;
} else {
holdercss.appendChild(document.createTextNode(options.stylesheet));
}
}
var cssregex = new RegExp(options.domain + "\/(.*?)\"?\\)");
for (var l = bgnodes.length, i = 0; i < l; i++) {
var src = window.getComputedStyle(bgnodes[i], null)
.getPropertyValue("background-image");
var flags = src.match(cssregex);
var bgsrc = bgnodes[i].getAttribute("data-background-src");
if (flags) {
var holder = parse_flags(flags[1].split("/"), options);
if (holder) {
render("background", bgnodes[i], holder, src);
}
} else if (bgsrc != null) {
var holder = parse_flags(bgsrc.substr(bgsrc.lastIndexOf(options.domain) + options.domain.length + 1)
.split("/"), options);
if (holder) {
render("background", bgnodes[i], holder, src);
}
}
}
for (l = images.length, i = 0; i < l; i++) {
var attr_data_src, attr_src;
attr_src = attr_data_src = src = null;
try {
attr_src = images[i].getAttribute("src");
attr_datasrc = images[i].getAttribute("data-src");
} catch (e) {}
if (attr_datasrc == null && !! attr_src && attr_src.indexOf(options.domain) >= 0) {
src = attr_src;
} else if ( !! attr_datasrc && attr_datasrc.indexOf(options.domain) >= 0) {
src = attr_datasrc;
}
if (src) {
var holder = parse_flags(src.substr(src.lastIndexOf(options.domain) + options.domain.length + 1).split("/"), options);
if (holder) {
if (holder.fluid) {
render("fluid", images[i], holder, src)
} else {
render("image", images[i], holder, src);
}
}
}
}
return app;
};
contentLoaded(win, function () {
if (window.addEventListener) {
window.addEventListener("resize", resizable_update, false);
window.addEventListener("orientationchange", resizable_update, false);
} else {
window.attachEvent("onresize", resizable_update)
}
preempted || app.run({});
});
if (typeof define === "function" && define.amd) {
define([], function () {
return app;
});
}
//github.com/davidchambers/Base64.js
(function(){function t(t){this.message=t}var e="undefined"!=typeof exports?exports:this,r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";t.prototype=Error(),t.prototype.name="InvalidCharacterError",e.btoa||(e.btoa=function(e){for(var o,n,a=0,i=r,c="";e.charAt(0|a)||(i="=",a%1);c+=i.charAt(63&o>>8-8*(a%1))){if(n=e.charCodeAt(a+=.75),n>255)throw new t("'btoa' failed");o=o<<8|n}return c}),e.atob||(e.atob=function(e){if(e=e.replace(/=+$/,""),1==e.length%4)throw new t("'atob' failed");for(var o,n,a=0,i=0,c="";n=e.charAt(i++);~n&&(o=a%4?64*o+n:n,a++%4)?c+=String.fromCharCode(255&o>>(6&-2*a)):0)n=r.indexOf(n);return c})})();
//getElementsByClassName polyfill
document.getElementsByClassName||(document.getElementsByClassName=function(e){var t=document,n,r,i,s=[];if(t.querySelectorAll)return t.querySelectorAll("."+e);if(t.evaluate){r=".//*[contains(concat(' ', @class, ' '), ' "+e+" ')]",n=t.evaluate(r,t,null,0,null);while(i=n.iterateNext())s.push(i)}else{n=t.getElementsByTagName("*"),r=new RegExp("(^|\\s)"+e+"(\\s|$)");for(i=0;i<n.length;i++)r.test(n[i].className)&&s.push(n[i])}return s})
//getComputedStyle polyfill
window.getComputedStyle||(window.getComputedStyle=function(e){return this.el=e,this.getPropertyValue=function(t){var n=/(\-([a-z]){1})/g;return t=="float"&&(t="styleFloat"),n.test(t)&&(t=t.replace(n,function(){return arguments[2].toUpperCase()})),e.currentStyle[t]?e.currentStyle[t]:null},this})
//http://javascript.nwbox.com/ContentLoaded by Diego Perini with modifications
function contentLoaded(n,t){var l="complete",s="readystatechange",u=!1,h=u,c=!0,i=n.document,a=i.documentElement,e=i.addEventListener?"addEventListener":"attachEvent",v=i.addEventListener?"removeEventListener":"detachEvent",f=i.addEventListener?"":"on",r=function(e){(e.type!=s||i.readyState==l)&&((e.type=="load"?n:i)[v](f+e.type,r,u),!h&&(h=!0)&&t.call(n,null))},o=function(){try{a.doScroll("left")}catch(n){setTimeout(o,50);return}r("poll")};if(i.readyState==l)t.call(n,"lazy");else{if(i.createEventObject&&a.doScroll){try{c=!n.frameElement}catch(y){}c&&o()}i[e](f+"DOMContentLoaded",r,u),i[e](f+s,r,u),n[e](f+"load",r,u)}}
//https://gist.github.com/991057 by Jed Schmidt with modifications
function selector(a,b){var a=a.match(/^(\W)?(.*)/),b=b||document,c=b["getElement"+(a[1]?"#"==a[1]?"ById":"sByClassName":"sByTagName")],d=c.call(b,a[2]),e=[];return null!==d&&(e=d.length||0===d.length?d:[d]),e}
//shallow object property extend
function extend(a,b){
var c={};
for(var i in a){
if(a.hasOwnProperty(i)){
c[i]=a[i];
}
}
for(var i in b){
if(b.hasOwnProperty(i)){
c[i]=b[i];
}
}
return c
}
//hasOwnProperty polyfill
if (!Object.prototype.hasOwnProperty)
/*jshint -W001, -W103 */
Object.prototype.hasOwnProperty = function(prop) {
var proto = this.__proto__ || this.constructor.prototype;
return (prop in this) && (!(prop in proto) || proto[prop] !== this[prop]);
}
/*jshint +W001, +W103 */
})(Holder, window);
Vendored Executable
+14
View File
File diff suppressed because one or more lines are too long
Vendored Executable
+16
View File
File diff suppressed because one or more lines are too long
Vendored Executable
+14
View File
File diff suppressed because one or more lines are too long