viewport_position.right && target_position.left - width >= viewport_position.left) {
576 | // flip left
577 | right = target_position.left - offset.x
578 | left = right - width
579 | orientation.x = mirror(orientation.x)
580 | }
581 |
582 | // out of viewport on the top or bottom,
583 | // and we have room on the bottom or top
584 | if (top < viewport_position.top && target_position.bottom + height <= viewport_position.bottom) {
585 | // flip bottom
586 | top = target_position.bottom - offset.y
587 | bottom = top + height
588 | orientation.y = mirror(orientation.y)
589 | } else
590 | if (bottom > viewport_position.bottom && target_position.top - height >= viewport_position.top) {
591 | // flip top
592 | bottom = target_position.top - offset.y
593 | top = bottom - height
594 | orientation.y = mirror(orientation.y)
595 | }
596 | }
597 |
598 | return {
599 | top: top,
600 | left: left,
601 | width: width,
602 | height: height,
603 | right: right,
604 | bottom: bottom,
605 | orientation: expr(orientation)
606 | }
607 | }
608 | }
609 |
610 | },{"./lib/expression":4,"./lib/mirror":5,"object-assign":6}],4:[function(require,module,exports){
611 | /**
612 | * Export `expression`
613 | *
614 | * @param {String|Object} expr
615 | * @return {Object|String}
616 | */
617 |
618 | module.exports = function expr (expr) {
619 | return typeof expr === 'string'
620 | ? parse(expr)
621 | : compile(expr)
622 | }
623 |
624 | /**
625 | * Parse the expression
626 | *
627 | * @param {String} expr
628 | * @return {Object}
629 | */
630 |
631 | function parse(expr) {
632 | var tokens = expr.split(/\s+/)
633 | var out = {}
634 |
635 | // token defaults
636 | if (tokens.length === 1) {
637 | switch(tokens[0]) {
638 | case 'middle': tokens.push('center'); break
639 | case 'bottom': tokens.push('center'); break
640 | case 'center': tokens.push('middle'); break
641 | case 'right': tokens.push('middle'); break
642 | case 'left': tokens.push('middle'); break
643 | case 'top': tokens.push('center'); break
644 | }
645 | }
646 |
647 | // turn strings into numbers
648 | tokens.forEach(function(token, i) {
649 | switch (token) {
650 | case 'center': return out.x = 0.5
651 | case 'middle': return out.y = 0.5
652 | case 'bottom': return out.y = 1
653 | case 'right': return out.x = 1
654 | case 'left': return out.x = 0
655 | case 'top': return out.y = 0
656 | default:
657 | return i % 2
658 | ? out.y = percentage(token)
659 | : out.x = percentage(token)
660 | }
661 | })
662 |
663 | return out
664 | }
665 |
666 | /**
667 | * Compile an object into a string
668 | * the reverse of parse
669 | *
670 | * @param {Object} n
671 | * @return {String}
672 | */
673 |
674 | function compile (expr) {
675 | var out = []
676 | switch (expr.x) {
677 | case 0: out.push('left'); break
678 | case 0.5: out.push('center'); break
679 | case 1: out.push('right'); break
680 | default: out.push(expr.x * 100 + '%')
681 | }
682 |
683 | switch (expr.y) {
684 | case 0: out.push('top'); break
685 | case 0.5: out.push('middle'); break
686 | case 1: out.push('bottom'); break
687 | default: out.push((expr.y * 100) + '%')
688 | }
689 |
690 | return out.join(' ')
691 | }
692 |
693 | /**
694 | * To percentage
695 | *
696 | * @param {String} val
697 | * @return {Number}
698 | */
699 |
700 | function percentage (val) {
701 | var float = parseFloat(val)
702 | return isNaN(float) ? 0 : float / 100
703 | }
704 |
705 | },{}],5:[function(require,module,exports){
706 | /**
707 | * Export `mirror`
708 | */
709 |
710 | module.exports = mirror
711 |
712 | /**
713 | * Get the mirror of the attachment
714 | *
715 | * @param {Number|Object}
716 | * @return {Object}
717 | */
718 |
719 | function mirror (p) {
720 | if (typeof p === 'number') {
721 | return round(Math.abs(1 - p))
722 | }
723 |
724 | return {
725 | x: round(Math.abs(1 - p.x)),
726 | y: round(Math.abs(1 - p.y))
727 | }
728 | }
729 |
730 | /**
731 | * Rounding
732 | *
733 | * @param {Number} n
734 | * @return {Number}
735 | */
736 |
737 | function round (n) {
738 | return parseFloat(n.toFixed(2))
739 | }
740 |
741 | },{}],6:[function(require,module,exports){
742 | 'use strict';
743 | var propIsEnumerable = Object.prototype.propertyIsEnumerable;
744 |
745 | function ToObject(val) {
746 | if (val == null) {
747 | throw new TypeError('Object.assign cannot be called with null or undefined');
748 | }
749 |
750 | return Object(val);
751 | }
752 |
753 | function ownEnumerableKeys(obj) {
754 | var keys = Object.getOwnPropertyNames(obj);
755 |
756 | if (Object.getOwnPropertySymbols) {
757 | keys = keys.concat(Object.getOwnPropertySymbols(obj));
758 | }
759 |
760 | return keys.filter(function (key) {
761 | return propIsEnumerable.call(obj, key);
762 | });
763 | }
764 |
765 | module.exports = Object.assign || function (target, source) {
766 | var from;
767 | var keys;
768 | var to = ToObject(target);
769 |
770 | for (var s = 1; s < arguments.length; s++) {
771 | from = arguments[s];
772 | keys = ownEnumerableKeys(Object(from));
773 |
774 | for (var i = 0; i < keys.length; i++) {
775 | to[keys[i]] = from[keys[i]];
776 | }
777 | }
778 |
779 | return to;
780 | };
781 |
782 | },{}],7:[function(require,module,exports){
783 | /**
784 | * Expose `requestAnimationFrame()`.
785 | */
786 |
787 | exports = module.exports = window.requestAnimationFrame
788 | || window.webkitRequestAnimationFrame
789 | || window.mozRequestAnimationFrame
790 | || fallback;
791 |
792 | /**
793 | * Fallback implementation.
794 | */
795 |
796 | var prev = new Date().getTime();
797 | function fallback(fn) {
798 | var curr = new Date().getTime();
799 | var ms = Math.max(0, 16 - (curr - prev));
800 | var req = setTimeout(fn, ms);
801 | prev = curr;
802 | return req;
803 | }
804 |
805 | /**
806 | * Cancel.
807 | */
808 |
809 | var cancel = window.cancelAnimationFrame
810 | || window.webkitCancelAnimationFrame
811 | || window.mozCancelAnimationFrame
812 | || window.clearTimeout;
813 |
814 | exports.cancel = function(id){
815 | cancel.call(window, id);
816 | };
817 |
818 | },{}],8:[function(require,module,exports){
819 | (function (global){
820 | module.exports =
821 | global.performance &&
822 | global.performance.now ? function now() {
823 | return performance.now()
824 | } : Date.now || function now() {
825 | return +new Date
826 | }
827 |
828 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
829 | },{}],9:[function(require,module,exports){
830 | ;(function () {
831 | var parents = function (node, ps) {
832 | if (node.parentNode === null) { return ps; }
833 |
834 | return parents(node.parentNode, ps.concat([node]));
835 | };
836 |
837 | var style = function (node, prop) {
838 | return getComputedStyle(node, null).getPropertyValue(prop);
839 | };
840 |
841 | var overflow = function (node) {
842 | return style(node, "overflow") + style(node, "overflow-y") + style(node, "overflow-x");
843 | };
844 |
845 | var scroll = function (node) {
846 | return (/(auto|scroll)/).test(overflow(node));
847 | };
848 |
849 | var scrollParent = function (node) {
850 | if (!(node instanceof HTMLElement)) {
851 | return ;
852 | }
853 |
854 | var ps = parents(node.parentNode, []);
855 |
856 | for (var i = 0; i < ps.length; i += 1) {
857 | if (scroll(ps[i])) {
858 | return ps[i];
859 | }
860 | }
861 |
862 | return window;
863 | };
864 |
865 | // If common js is defined use it.
866 | if (typeof module === "object" && module !== null) {
867 | module.exports = scrollParent;
868 | } else {
869 | window.Scrollparent = scrollParent;
870 | }
871 | })();
872 |
873 | },{}],10:[function(require,module,exports){
874 |
875 | /**
876 | * Module dependencies.
877 | */
878 |
879 | var transform = require('transform-property');
880 | var has3d = require('has-translate3d');
881 |
882 | /**
883 | * Expose `translate`.
884 | */
885 |
886 | module.exports = translate;
887 |
888 | /**
889 | * Translate `el` by `(x, y)`.
890 | *
891 | * @param {Element} el
892 | * @param {Number} x
893 | * @param {Number} y
894 | * @api public
895 | */
896 |
897 | function translate(el, x, y){
898 | if (transform) {
899 | if (has3d) {
900 | el.style[transform] = 'translate3d(' + x + 'px,' + y + 'px, 0)';
901 | } else {
902 | el.style[transform] = 'translate(' + x + 'px,' + y + 'px)';
903 | }
904 | } else {
905 | el.style.left = x;
906 | el.style.top = y;
907 | }
908 | };
909 |
910 | },{"has-translate3d":11,"transform-property":12}],11:[function(require,module,exports){
911 |
912 | var prop = require('transform-property');
913 |
914 | // IE <=8 doesn't have `getComputedStyle`
915 | if (!prop || !window.getComputedStyle) {
916 | module.exports = false;
917 |
918 | } else {
919 | var map = {
920 | webkitTransform: '-webkit-transform',
921 | OTransform: '-o-transform',
922 | msTransform: '-ms-transform',
923 | MozTransform: '-moz-transform',
924 | transform: 'transform'
925 | };
926 |
927 | // from: https://gist.github.com/lorenzopolidori/3794226
928 | var el = document.createElement('div');
929 | el.style[prop] = 'translate3d(1px,1px,1px)';
930 | document.body.insertBefore(el, null);
931 | var val = getComputedStyle(el).getPropertyValue(map[prop]);
932 | document.body.removeChild(el);
933 | module.exports = null != val && val.length && 'none' != val;
934 | }
935 |
936 | },{"transform-property":12}],12:[function(require,module,exports){
937 |
938 | var styles = [
939 | 'webkitTransform',
940 | 'MozTransform',
941 | 'msTransform',
942 | 'OTransform',
943 | 'transform'
944 | ];
945 |
946 | var el = document.createElement('p');
947 | var style;
948 |
949 | for (var i = 0; i < styles.length; i++) {
950 | style = styles[i];
951 | if (null != el.style[style]) {
952 | module.exports = style;
953 | break;
954 | }
955 | }
956 |
957 | },{}],13:[function(require,module,exports){
958 | /**
959 | * Module dependencies.
960 | */
961 |
962 | var index = require('indexof');
963 |
964 | /**
965 | * Whitespace regexp.
966 | */
967 |
968 | var re = /\s+/;
969 |
970 | /**
971 | * toString reference.
972 | */
973 |
974 | var toString = Object.prototype.toString;
975 |
976 | /**
977 | * Wrap `el` in a `ClassList`.
978 | *
979 | * @param {Element} el
980 | * @return {ClassList}
981 | * @api public
982 | */
983 |
984 | module.exports = function(el){
985 | return new ClassList(el);
986 | };
987 |
988 | /**
989 | * Initialize a new ClassList for `el`.
990 | *
991 | * @param {Element} el
992 | * @api private
993 | */
994 |
995 | function ClassList(el) {
996 | if (!el || !el.nodeType) {
997 | throw new Error('A DOM element reference is required');
998 | }
999 | this.el = el;
1000 | this.list = el.classList;
1001 | }
1002 |
1003 | /**
1004 | * Add class `name` if not already present.
1005 | *
1006 | * @param {String} name
1007 | * @return {ClassList}
1008 | * @api public
1009 | */
1010 |
1011 | ClassList.prototype.add = function(name){
1012 | // classList
1013 | if (this.list) {
1014 | this.list.add(name);
1015 | return this;
1016 | }
1017 |
1018 | // fallback
1019 | var arr = this.array();
1020 | var i = index(arr, name);
1021 | if (!~i) arr.push(name);
1022 | this.el.className = arr.join(' ');
1023 | return this;
1024 | };
1025 |
1026 | /**
1027 | * Remove class `name` when present, or
1028 | * pass a regular expression to remove
1029 | * any which match.
1030 | *
1031 | * @param {String|RegExp} name
1032 | * @return {ClassList}
1033 | * @api public
1034 | */
1035 |
1036 | ClassList.prototype.remove = function(name){
1037 | if ('[object RegExp]' == toString.call(name)) {
1038 | return this.removeMatching(name);
1039 | }
1040 |
1041 | // classList
1042 | if (this.list) {
1043 | this.list.remove(name);
1044 | return this;
1045 | }
1046 |
1047 | // fallback
1048 | var arr = this.array();
1049 | var i = index(arr, name);
1050 | if (~i) arr.splice(i, 1);
1051 | this.el.className = arr.join(' ');
1052 | return this;
1053 | };
1054 |
1055 | /**
1056 | * Remove all classes matching `re`.
1057 | *
1058 | * @param {RegExp} re
1059 | * @return {ClassList}
1060 | * @api private
1061 | */
1062 |
1063 | ClassList.prototype.removeMatching = function(re){
1064 | var arr = this.array();
1065 | for (var i = 0; i < arr.length; i++) {
1066 | if (re.test(arr[i])) {
1067 | this.remove(arr[i]);
1068 | }
1069 | }
1070 | return this;
1071 | };
1072 |
1073 | /**
1074 | * Toggle class `name`, can force state via `force`.
1075 | *
1076 | * For browsers that support classList, but do not support `force` yet,
1077 | * the mistake will be detected and corrected.
1078 | *
1079 | * @param {String} name
1080 | * @param {Boolean} force
1081 | * @return {ClassList}
1082 | * @api public
1083 | */
1084 |
1085 | ClassList.prototype.toggle = function(name, force){
1086 | // classList
1087 | if (this.list) {
1088 | if ("undefined" !== typeof force) {
1089 | if (force !== this.list.toggle(name, force)) {
1090 | this.list.toggle(name); // toggle again to correct
1091 | }
1092 | } else {
1093 | this.list.toggle(name);
1094 | }
1095 | return this;
1096 | }
1097 |
1098 | // fallback
1099 | if ("undefined" !== typeof force) {
1100 | if (!force) {
1101 | this.remove(name);
1102 | } else {
1103 | this.add(name);
1104 | }
1105 | } else {
1106 | if (this.has(name)) {
1107 | this.remove(name);
1108 | } else {
1109 | this.add(name);
1110 | }
1111 | }
1112 |
1113 | return this;
1114 | };
1115 |
1116 | /**
1117 | * Return an array of classes.
1118 | *
1119 | * @return {Array}
1120 | * @api public
1121 | */
1122 |
1123 | ClassList.prototype.array = function(){
1124 | var className = this.el.getAttribute('class') || '';
1125 | var str = className.replace(/^\s+|\s+$/g, '');
1126 | var arr = str.split(re);
1127 | if ('' === arr[0]) arr.shift();
1128 | return arr;
1129 | };
1130 |
1131 | /**
1132 | * Check if class `name` is present.
1133 | *
1134 | * @param {String} name
1135 | * @return {ClassList}
1136 | * @api public
1137 | */
1138 |
1139 | ClassList.prototype.has =
1140 | ClassList.prototype.contains = function(name){
1141 | return this.list
1142 | ? this.list.contains(name)
1143 | : !! ~index(this.array(), name);
1144 | };
1145 |
1146 | },{"indexof":14}],14:[function(require,module,exports){
1147 | module.exports = function(arr, obj){
1148 | if (arr.indexOf) return arr.indexOf(obj);
1149 | for (var i = 0; i < arr.length; ++i) {
1150 | if (arr[i] === obj) return i;
1151 | }
1152 | return -1;
1153 | };
1154 | },{}],15:[function(require,module,exports){
1155 |
1156 | /**
1157 | * Module dependencies.
1158 | */
1159 |
1160 | var events = require('event');
1161 | var delegate = require('delegate');
1162 |
1163 | /**
1164 | * Expose `Events`.
1165 | */
1166 |
1167 | module.exports = Events;
1168 |
1169 | /**
1170 | * Initialize an `Events` with the given
1171 | * `el` object which events will be bound to,
1172 | * and the `obj` which will receive method calls.
1173 | *
1174 | * @param {Object} el
1175 | * @param {Object} obj
1176 | * @api public
1177 | */
1178 |
1179 | function Events(el, obj) {
1180 | if (!(this instanceof Events)) return new Events(el, obj);
1181 | if (!el) throw new Error('element required');
1182 | if (!obj) throw new Error('object required');
1183 | this.el = el;
1184 | this.obj = obj;
1185 | this._events = {};
1186 | }
1187 |
1188 | /**
1189 | * Subscription helper.
1190 | */
1191 |
1192 | Events.prototype.sub = function(event, method, cb){
1193 | this._events[event] = this._events[event] || {};
1194 | this._events[event][method] = cb;
1195 | };
1196 |
1197 | /**
1198 | * Bind to `event` with optional `method` name.
1199 | * When `method` is undefined it becomes `event`
1200 | * with the "on" prefix.
1201 | *
1202 | * Examples:
1203 | *
1204 | * Direct event handling:
1205 | *
1206 | * events.bind('click') // implies "onclick"
1207 | * events.bind('click', 'remove')
1208 | * events.bind('click', 'sort', 'asc')
1209 | *
1210 | * Delegated event handling:
1211 | *
1212 | * events.bind('click li > a')
1213 | * events.bind('click li > a', 'remove')
1214 | * events.bind('click a.sort-ascending', 'sort', 'asc')
1215 | * events.bind('click a.sort-descending', 'sort', 'desc')
1216 | *
1217 | * @param {String} event
1218 | * @param {String|function} [method]
1219 | * @return {Function} callback
1220 | * @api public
1221 | */
1222 |
1223 | Events.prototype.bind = function(event, method){
1224 | var e = parse(event);
1225 | var el = this.el;
1226 | var obj = this.obj;
1227 | var name = e.name;
1228 | var method = method || 'on' + name;
1229 | var args = [].slice.call(arguments, 2);
1230 |
1231 | // callback
1232 | function cb(){
1233 | var a = [].slice.call(arguments).concat(args);
1234 | obj[method].apply(obj, a);
1235 | }
1236 |
1237 | // bind
1238 | if (e.selector) {
1239 | cb = delegate.bind(el, e.selector, name, cb);
1240 | } else {
1241 | events.bind(el, name, cb);
1242 | }
1243 |
1244 | // subscription for unbinding
1245 | this.sub(name, method, cb);
1246 |
1247 | return cb;
1248 | };
1249 |
1250 | /**
1251 | * Unbind a single binding, all bindings for `event`,
1252 | * or all bindings within the manager.
1253 | *
1254 | * Examples:
1255 | *
1256 | * Unbind direct handlers:
1257 | *
1258 | * events.unbind('click', 'remove')
1259 | * events.unbind('click')
1260 | * events.unbind()
1261 | *
1262 | * Unbind delegate handlers:
1263 | *
1264 | * events.unbind('click', 'remove')
1265 | * events.unbind('click')
1266 | * events.unbind()
1267 | *
1268 | * @param {String|Function} [event]
1269 | * @param {String|Function} [method]
1270 | * @api public
1271 | */
1272 |
1273 | Events.prototype.unbind = function(event, method){
1274 | if (0 == arguments.length) return this.unbindAll();
1275 | if (1 == arguments.length) return this.unbindAllOf(event);
1276 |
1277 | // no bindings for this event
1278 | var bindings = this._events[event];
1279 | if (!bindings) return;
1280 |
1281 | // no bindings for this method
1282 | var cb = bindings[method];
1283 | if (!cb) return;
1284 |
1285 | events.unbind(this.el, event, cb);
1286 | };
1287 |
1288 | /**
1289 | * Unbind all events.
1290 | *
1291 | * @api private
1292 | */
1293 |
1294 | Events.prototype.unbindAll = function(){
1295 | for (var event in this._events) {
1296 | this.unbindAllOf(event);
1297 | }
1298 | };
1299 |
1300 | /**
1301 | * Unbind all events for `event`.
1302 | *
1303 | * @param {String} event
1304 | * @api private
1305 | */
1306 |
1307 | Events.prototype.unbindAllOf = function(event){
1308 | var bindings = this._events[event];
1309 | if (!bindings) return;
1310 |
1311 | for (var method in bindings) {
1312 | this.unbind(event, method);
1313 | }
1314 | };
1315 |
1316 | /**
1317 | * Parse `event`.
1318 | *
1319 | * @param {String} event
1320 | * @return {Object}
1321 | * @api private
1322 | */
1323 |
1324 | function parse(event) {
1325 | var parts = event.split(/ +/);
1326 | return {
1327 | name: parts.shift(),
1328 | selector: parts.join(' ')
1329 | }
1330 | }
1331 |
1332 | },{"delegate":16,"event":20}],16:[function(require,module,exports){
1333 | /**
1334 | * Module dependencies.
1335 | */
1336 |
1337 | var closest = require('closest')
1338 | , event = require('event');
1339 |
1340 | /**
1341 | * Delegate event `type` to `selector`
1342 | * and invoke `fn(e)`. A callback function
1343 | * is returned which may be passed to `.unbind()`.
1344 | *
1345 | * @param {Element} el
1346 | * @param {String} selector
1347 | * @param {String} type
1348 | * @param {Function} fn
1349 | * @param {Boolean} capture
1350 | * @return {Function}
1351 | * @api public
1352 | */
1353 |
1354 | exports.bind = function(el, selector, type, fn, capture){
1355 | return event.bind(el, type, function(e){
1356 | var target = e.target || e.srcElement;
1357 | e.delegateTarget = closest(target, selector, true, el);
1358 | if (e.delegateTarget) fn.call(el, e);
1359 | }, capture);
1360 | };
1361 |
1362 | /**
1363 | * Unbind event `type`'s callback `fn`.
1364 | *
1365 | * @param {Element} el
1366 | * @param {String} type
1367 | * @param {Function} fn
1368 | * @param {Boolean} capture
1369 | * @api public
1370 | */
1371 |
1372 | exports.unbind = function(el, type, fn, capture){
1373 | event.unbind(el, type, fn, capture);
1374 | };
1375 |
1376 | },{"closest":17,"event":20}],17:[function(require,module,exports){
1377 | /**
1378 | * Module Dependencies
1379 | */
1380 |
1381 | var matches = require('matches-selector')
1382 |
1383 | /**
1384 | * Export `closest`
1385 | */
1386 |
1387 | module.exports = closest
1388 |
1389 | /**
1390 | * Closest
1391 | *
1392 | * @param {Element} el
1393 | * @param {String} selector
1394 | * @param {Element} scope (optional)
1395 | */
1396 |
1397 | function closest (el, selector, scope) {
1398 | scope = scope || document.documentElement;
1399 |
1400 | // walk up the dom
1401 | while (el && el !== scope) {
1402 | if (matches(el, selector)) return el;
1403 | el = el.parentNode;
1404 | }
1405 |
1406 | // check scope for match
1407 | return matches(el, selector) ? el : null;
1408 | }
1409 |
1410 | },{"matches-selector":18}],18:[function(require,module,exports){
1411 | /**
1412 | * Module dependencies.
1413 | */
1414 |
1415 | var query = require('query');
1416 |
1417 | /**
1418 | * Element prototype.
1419 | */
1420 |
1421 | var proto = Element.prototype;
1422 |
1423 | /**
1424 | * Vendor function.
1425 | */
1426 |
1427 | var vendor = proto.matches
1428 | || proto.webkitMatchesSelector
1429 | || proto.mozMatchesSelector
1430 | || proto.msMatchesSelector
1431 | || proto.oMatchesSelector;
1432 |
1433 | /**
1434 | * Expose `match()`.
1435 | */
1436 |
1437 | module.exports = match;
1438 |
1439 | /**
1440 | * Match `el` to `selector`.
1441 | *
1442 | * @param {Element} el
1443 | * @param {String} selector
1444 | * @return {Boolean}
1445 | * @api public
1446 | */
1447 |
1448 | function match(el, selector) {
1449 | if (!el || el.nodeType !== 1) return false;
1450 | if (vendor) return vendor.call(el, selector);
1451 | var nodes = query.all(selector, el.parentNode);
1452 | for (var i = 0; i < nodes.length; ++i) {
1453 | if (nodes[i] == el) return true;
1454 | }
1455 | return false;
1456 | }
1457 |
1458 | },{"query":19}],19:[function(require,module,exports){
1459 | function one(selector, el) {
1460 | return el.querySelector(selector);
1461 | }
1462 |
1463 | exports = module.exports = function(selector, el){
1464 | el = el || document;
1465 | return one(selector, el);
1466 | };
1467 |
1468 | exports.all = function(selector, el){
1469 | el = el || document;
1470 | return el.querySelectorAll(selector);
1471 | };
1472 |
1473 | exports.engine = function(obj){
1474 | if (!obj.one) throw new Error('.one callback required');
1475 | if (!obj.all) throw new Error('.all callback required');
1476 | one = obj.one;
1477 | exports.all = obj.all;
1478 | return exports;
1479 | };
1480 |
1481 | },{}],20:[function(require,module,exports){
1482 | var bind = window.addEventListener ? 'addEventListener' : 'attachEvent',
1483 | unbind = window.removeEventListener ? 'removeEventListener' : 'detachEvent',
1484 | prefix = bind !== 'addEventListener' ? 'on' : '';
1485 |
1486 | /**
1487 | * Bind `el` event `type` to `fn`.
1488 | *
1489 | * @param {Element} el
1490 | * @param {String} type
1491 | * @param {Function} fn
1492 | * @param {Boolean} capture
1493 | * @return {Function}
1494 | * @api public
1495 | */
1496 |
1497 | exports.bind = function(el, type, fn, capture){
1498 | el[bind](prefix + type, fn, capture || false);
1499 | return fn;
1500 | };
1501 |
1502 | /**
1503 | * Unbind `el` event `type`'s callback `fn`.
1504 | *
1505 | * @param {Element} el
1506 | * @param {String} type
1507 | * @param {Function} fn
1508 | * @param {Boolean} capture
1509 | * @return {Function}
1510 | * @api public
1511 | */
1512 |
1513 | exports.unbind = function(el, type, fn, capture){
1514 | el[unbind](prefix + type, fn, capture || false);
1515 | return fn;
1516 | };
1517 | },{}],21:[function(require,module,exports){
1518 |
1519 | /**
1520 | * Expose `parse`.
1521 | */
1522 |
1523 | module.exports = parse;
1524 |
1525 | /**
1526 | * Tests for browser support.
1527 | */
1528 |
1529 | var innerHTMLBug = false;
1530 | var bugTestDiv;
1531 | if (typeof document !== 'undefined') {
1532 | bugTestDiv = document.createElement('div');
1533 | // Setup
1534 | bugTestDiv.innerHTML = ' a ';
1535 | // Make sure that link elements get serialized correctly by innerHTML
1536 | // This requires a wrapper element in IE
1537 | innerHTMLBug = !bugTestDiv.getElementsByTagName('link').length;
1538 | bugTestDiv = undefined;
1539 | }
1540 |
1541 | /**
1542 | * Wrap map from jquery.
1543 | */
1544 |
1545 | var map = {
1546 | legend: [1, '', ' '],
1547 | tr: [2, ''],
1548 | col: [2, ''],
1549 | // for script/link/style tags to work in IE6-8, you have to wrap
1550 | // in a div with a non-whitespace character in front, ha!
1551 | _default: innerHTMLBug ? [1, 'X', '
'] : [0, '', '']
1552 | };
1553 |
1554 | map.td =
1555 | map.th = [3, ''];
1556 |
1557 | map.option =
1558 | map.optgroup = [1, '', ' '];
1559 |
1560 | map.thead =
1561 | map.tbody =
1562 | map.colgroup =
1563 | map.caption =
1564 | map.tfoot = [1, ''];
1565 |
1566 | map.polyline =
1567 | map.ellipse =
1568 | map.polygon =
1569 | map.circle =
1570 | map.text =
1571 | map.line =
1572 | map.path =
1573 | map.rect =
1574 | map.g = [1, '',' '];
1575 |
1576 | /**
1577 | * Parse `html` and return a DOM Node instance, which could be a TextNode,
1578 | * HTML DOM Node of some kind ( for example), or a DocumentFragment
1579 | * instance, depending on the contents of the `html` string.
1580 | *
1581 | * @param {String} html - HTML string to "domify"
1582 | * @param {Document} doc - The `document` instance to create the Node for
1583 | * @return {DOMNode} the TextNode, DOM Node, or DocumentFragment instance
1584 | * @api private
1585 | */
1586 |
1587 | function parse(html, doc) {
1588 | if ('string' != typeof html) throw new TypeError('String expected');
1589 |
1590 | // default to the global `document` object
1591 | if (!doc) doc = document;
1592 |
1593 | // tag name
1594 | var m = /<([\w:]+)/.exec(html);
1595 | if (!m) return doc.createTextNode(html);
1596 |
1597 | html = html.replace(/^\s+|\s+$/g, ''); // Remove leading/trailing whitespace
1598 |
1599 | var tag = m[1];
1600 |
1601 | // body support
1602 | if (tag == 'body') {
1603 | var el = doc.createElement('html');
1604 | el.innerHTML = html;
1605 | return el.removeChild(el.lastChild);
1606 | }
1607 |
1608 | // wrap map
1609 | var wrap = map[tag] || map._default;
1610 | var depth = wrap[0];
1611 | var prefix = wrap[1];
1612 | var suffix = wrap[2];
1613 | var el = doc.createElement('div');
1614 | el.innerHTML = prefix + html + suffix;
1615 | while (depth--) el = el.lastChild;
1616 |
1617 | // one element
1618 | if (el.firstChild == el.lastChild) {
1619 | return el.removeChild(el.firstChild);
1620 | }
1621 |
1622 | // several elements
1623 | var fragment = doc.createDocumentFragment();
1624 | while (el.firstChild) {
1625 | fragment.appendChild(el.removeChild(el.firstChild));
1626 | }
1627 |
1628 | return fragment;
1629 | }
1630 |
1631 | },{}],22:[function(require,module,exports){
1632 |
1633 | module.exports = inserted;
1634 |
1635 | /**
1636 | * Watch for removal with a DOM3 Mutation Event.
1637 | *
1638 | * @param {Element} el
1639 | * @param {Function} fn
1640 | * @api private
1641 | */
1642 |
1643 | function inserted(el, fn) {
1644 | function cb(mutationEvent) {
1645 | var target = mutationEvent.target
1646 | , children = target.getElementsByTagName ? [].slice.call(target.getElementsByTagName('*')) : [];
1647 |
1648 | if (el === target || ~children.indexOf(el)) {
1649 | fn(el);
1650 | document.removeEventListener('DOMNodeInserted', cb);
1651 | }
1652 | }
1653 |
1654 | document.addEventListener('DOMNodeInserted', cb);
1655 | }
1656 |
1657 | },{}],23:[function(require,module,exports){
1658 |
1659 | /**
1660 | * Module dependencies.
1661 | */
1662 |
1663 | var withinDoc = require('within-document')
1664 | , Observer = require('mutation-observer');
1665 |
1666 | /**
1667 | * Expose `inserted`.
1668 | */
1669 |
1670 | module.exports = inserted;
1671 |
1672 | /**
1673 | * Watched elements.
1674 | *
1675 | * @api private
1676 | */
1677 |
1678 | var watched = [];
1679 |
1680 | /**
1681 | * Set up observer.
1682 | *
1683 | * @api private
1684 | */
1685 |
1686 | var observer = new Observer(onchanges);
1687 |
1688 | /**
1689 | * Generic observer callback.
1690 | *
1691 | * @api private
1692 | */
1693 |
1694 | function onchanges(changes){
1695 | // keep track of number of found els
1696 | var found = 0;
1697 |
1698 | for (var i = 0, l = changes.length; i < l; i++) {
1699 | if (changes[i].addedNodes.length) {
1700 | // allow for manipulation of `watched`
1701 | // from within the callback
1702 | var w = watched.slice();
1703 |
1704 | for (var i2 = 0, l2 = w.length; i2 < l2; i2++) {
1705 | var el = w[i2][0];
1706 |
1707 | // check if the added element is the same
1708 | // or that it's now part of the document
1709 | if (withinDoc(el)) {
1710 | watched.splice(i2 - found++, 1)[0][1]();
1711 |
1712 | // abort if nothing else left to watch
1713 | if (!watched.length) observer.disconnect();
1714 | }
1715 | }
1716 |
1717 | // we only need to loop through watched els once
1718 | break;
1719 | }
1720 | }
1721 | }
1722 |
1723 | /**
1724 | * Starts observing the DOM.
1725 | *
1726 | * @api private
1727 | */
1728 |
1729 | function observe(){
1730 | var html = document.documentElement;
1731 | observer.observe(html, {
1732 | subtree: true,
1733 | childList: true
1734 | });
1735 | }
1736 |
1737 | /**
1738 | * Watches for insertion of `el` into DOM.
1739 | *
1740 | * @param {Element} el
1741 | * @param {Function} fn
1742 | * @api private
1743 | */
1744 |
1745 | function inserted(el, fn){
1746 | // reattach observer if we weren't watching
1747 | if (!watched.length) observe();
1748 |
1749 | // we add it to the list of elements to check
1750 | watched.push([el, fn]);
1751 | }
1752 |
1753 | },{"mutation-observer":26,"within-document":30}],24:[function(require,module,exports){
1754 |
1755 | /**
1756 | * Module dependencies.
1757 | */
1758 |
1759 | var withinDocument = require('within-document');
1760 |
1761 | /**
1762 | * Expose `inserted`.
1763 | */
1764 |
1765 | exports = module.exports = inserted;
1766 |
1767 | /**
1768 | * Default interval.
1769 | */
1770 |
1771 | exports.interval = 200;
1772 |
1773 | /**
1774 | * Watch for removal and invoke `fn(el)`.
1775 | *
1776 | * @param {Element} el
1777 | * @param {Function} fn
1778 | * @api public
1779 | */
1780 |
1781 | function inserted(el, fn){
1782 | interval(el, fn);
1783 | }
1784 |
1785 | /**
1786 | * Watch for removal with an interval.
1787 | *
1788 | * @param {Element} el
1789 | * @param {Function} fn
1790 | * @api private
1791 | */
1792 |
1793 | function interval(el, fn) {
1794 | var id = setInterval(function(){
1795 | if (!withinDocument(el)) return;
1796 | clearInterval(id);
1797 | fn(el);
1798 | }, exports.interval);
1799 | }
1800 |
1801 | },{"within-document":30}],25:[function(require,module,exports){
1802 |
1803 | /**
1804 | * Module dependencies.
1805 | */
1806 |
1807 | var Observer = require('mutation-observer');
1808 |
1809 | /**
1810 | * Exports the `MutationObserver` based approach
1811 | * or the fallback one depending on UA capabilities.
1812 | */
1813 |
1814 | module.exports = Observer
1815 | ? require('./dom4')
1816 | : document.addEventListener
1817 | ? require('./dom3')
1818 | : require('./fallback');
1819 |
1820 | },{"./dom3":22,"./dom4":23,"./fallback":24,"mutation-observer":26}],26:[function(require,module,exports){
1821 | var MutationObserver = window.MutationObserver
1822 | || window.WebKitMutationObserver
1823 | || window.MozMutationObserver;
1824 |
1825 | /*
1826 | * Copyright 2012 The Polymer Authors. All rights reserved.
1827 | * Use of this source code is goverened by a BSD-style
1828 | * license that can be found in the LICENSE file.
1829 | */
1830 |
1831 | var WeakMap = window.WeakMap;
1832 |
1833 | if (typeof WeakMap === 'undefined') {
1834 | var defineProperty = Object.defineProperty;
1835 | var counter = Date.now() % 1e9;
1836 |
1837 | WeakMap = function() {
1838 | this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__');
1839 | };
1840 |
1841 | WeakMap.prototype = {
1842 | set: function(key, value) {
1843 | var entry = key[this.name];
1844 | if (entry && entry[0] === key)
1845 | entry[1] = value;
1846 | else
1847 | defineProperty(key, this.name, {value: [key, value], writable: true});
1848 | return this;
1849 | },
1850 | get: function(key) {
1851 | var entry;
1852 | return (entry = key[this.name]) && entry[0] === key ?
1853 | entry[1] : undefined;
1854 | },
1855 | 'delete': function(key) {
1856 | var entry = key[this.name];
1857 | if (!entry) return false;
1858 | var hasValue = entry[0] === key;
1859 | entry[0] = entry[1] = undefined;
1860 | return hasValue;
1861 | },
1862 | has: function(key) {
1863 | var entry = key[this.name];
1864 | if (!entry) return false;
1865 | return entry[0] === key;
1866 | }
1867 | };
1868 | }
1869 |
1870 | var registrationsTable = new WeakMap();
1871 |
1872 | // We use setImmediate or postMessage for our future callback.
1873 | var setImmediate = window.msSetImmediate;
1874 |
1875 | // Use post message to emulate setImmediate.
1876 | if (!setImmediate) {
1877 | var setImmediateQueue = [];
1878 | var sentinel = String(Math.random());
1879 | window.addEventListener('message', function(e) {
1880 | if (e.data === sentinel) {
1881 | var queue = setImmediateQueue;
1882 | setImmediateQueue = [];
1883 | queue.forEach(function(func) {
1884 | func();
1885 | });
1886 | }
1887 | });
1888 | setImmediate = function(func) {
1889 | setImmediateQueue.push(func);
1890 | window.postMessage(sentinel, '*');
1891 | };
1892 | }
1893 |
1894 | // This is used to ensure that we never schedule 2 callas to setImmediate
1895 | var isScheduled = false;
1896 |
1897 | // Keep track of observers that needs to be notified next time.
1898 | var scheduledObservers = [];
1899 |
1900 | /**
1901 | * Schedules |dispatchCallback| to be called in the future.
1902 | * @param {MutationObserver} observer
1903 | */
1904 | function scheduleCallback(observer) {
1905 | scheduledObservers.push(observer);
1906 | if (!isScheduled) {
1907 | isScheduled = true;
1908 | setImmediate(dispatchCallbacks);
1909 | }
1910 | }
1911 |
1912 | function wrapIfNeeded(node) {
1913 | return window.ShadowDOMPolyfill &&
1914 | window.ShadowDOMPolyfill.wrapIfNeeded(node) ||
1915 | node;
1916 | }
1917 |
1918 | function dispatchCallbacks() {
1919 | // http://dom.spec.whatwg.org/#mutation-observers
1920 |
1921 | isScheduled = false; // Used to allow a new setImmediate call above.
1922 |
1923 | var observers = scheduledObservers;
1924 | scheduledObservers = [];
1925 | // Sort observers based on their creation UID (incremental).
1926 | observers.sort(function(o1, o2) {
1927 | return o1.uid_ - o2.uid_;
1928 | });
1929 |
1930 | var anyNonEmpty = false;
1931 | observers.forEach(function(observer) {
1932 |
1933 | // 2.1, 2.2
1934 | var queue = observer.takeRecords();
1935 | // 2.3. Remove all transient registered observers whose observer is mo.
1936 | removeTransientObserversFor(observer);
1937 |
1938 | // 2.4
1939 | if (queue.length) {
1940 | observer.callback_(queue, observer);
1941 | anyNonEmpty = true;
1942 | }
1943 | });
1944 |
1945 | // 3.
1946 | if (anyNonEmpty)
1947 | dispatchCallbacks();
1948 | }
1949 |
1950 | function removeTransientObserversFor(observer) {
1951 | observer.nodes_.forEach(function(node) {
1952 | var registrations = registrationsTable.get(node);
1953 | if (!registrations)
1954 | return;
1955 | registrations.forEach(function(registration) {
1956 | if (registration.observer === observer)
1957 | registration.removeTransientObservers();
1958 | });
1959 | });
1960 | }
1961 |
1962 | /**
1963 | * This function is used for the "For each registered observer observer (with
1964 | * observer's options as options) in target's list of registered observers,
1965 | * run these substeps:" and the "For each ancestor ancestor of target, and for
1966 | * each registered observer observer (with options options) in ancestor's list
1967 | * of registered observers, run these substeps:" part of the algorithms. The
1968 | * |options.subtree| is checked to ensure that the callback is called
1969 | * correctly.
1970 | *
1971 | * @param {Node} target
1972 | * @param {function(MutationObserverInit):MutationRecord} callback
1973 | */
1974 | function forEachAncestorAndObserverEnqueueRecord(target, callback) {
1975 | for (var node = target; node; node = node.parentNode) {
1976 | var registrations = registrationsTable.get(node);
1977 |
1978 | if (registrations) {
1979 | for (var j = 0; j < registrations.length; j++) {
1980 | var registration = registrations[j];
1981 | var options = registration.options;
1982 |
1983 | // Only target ignores subtree.
1984 | if (node !== target && !options.subtree)
1985 | continue;
1986 |
1987 | var record = callback(options);
1988 | if (record)
1989 | registration.enqueue(record);
1990 | }
1991 | }
1992 | }
1993 | }
1994 |
1995 | var uidCounter = 0;
1996 |
1997 | /**
1998 | * The class that maps to the DOM MutationObserver interface.
1999 | * @param {Function} callback.
2000 | * @constructor
2001 | */
2002 | function JsMutationObserver(callback) {
2003 | this.callback_ = callback;
2004 | this.nodes_ = [];
2005 | this.records_ = [];
2006 | this.uid_ = ++uidCounter;
2007 | }
2008 |
2009 | JsMutationObserver.prototype = {
2010 | observe: function(target, options) {
2011 | target = wrapIfNeeded(target);
2012 |
2013 | // 1.1
2014 | if (!options.childList && !options.attributes && !options.characterData ||
2015 |
2016 | // 1.2
2017 | options.attributeOldValue && !options.attributes ||
2018 |
2019 | // 1.3
2020 | options.attributeFilter && options.attributeFilter.length &&
2021 | !options.attributes ||
2022 |
2023 | // 1.4
2024 | options.characterDataOldValue && !options.characterData) {
2025 |
2026 | throw new SyntaxError();
2027 | }
2028 |
2029 | var registrations = registrationsTable.get(target);
2030 | if (!registrations)
2031 | registrationsTable.set(target, registrations = []);
2032 |
2033 | // 2
2034 | // If target's list of registered observers already includes a registered
2035 | // observer associated with the context object, replace that registered
2036 | // observer's options with options.
2037 | var registration;
2038 | for (var i = 0; i < registrations.length; i++) {
2039 | if (registrations[i].observer === this) {
2040 | registration = registrations[i];
2041 | registration.removeListeners();
2042 | registration.options = options;
2043 | break;
2044 | }
2045 | }
2046 |
2047 | // 3.
2048 | // Otherwise, add a new registered observer to target's list of registered
2049 | // observers with the context object as the observer and options as the
2050 | // options, and add target to context object's list of nodes on which it
2051 | // is registered.
2052 | if (!registration) {
2053 | registration = new Registration(this, target, options);
2054 | registrations.push(registration);
2055 | this.nodes_.push(target);
2056 | }
2057 |
2058 | registration.addListeners();
2059 | },
2060 |
2061 | disconnect: function() {
2062 | this.nodes_.forEach(function(node) {
2063 | var registrations = registrationsTable.get(node);
2064 | for (var i = 0; i < registrations.length; i++) {
2065 | var registration = registrations[i];
2066 | if (registration.observer === this) {
2067 | registration.removeListeners();
2068 | registrations.splice(i, 1);
2069 | // Each node can only have one registered observer associated with
2070 | // this observer.
2071 | break;
2072 | }
2073 | }
2074 | }, this);
2075 | this.records_ = [];
2076 | },
2077 |
2078 | takeRecords: function() {
2079 | var copyOfRecords = this.records_;
2080 | this.records_ = [];
2081 | return copyOfRecords;
2082 | }
2083 | };
2084 |
2085 | /**
2086 | * @param {string} type
2087 | * @param {Node} target
2088 | * @constructor
2089 | */
2090 | function MutationRecord(type, target) {
2091 | this.type = type;
2092 | this.target = target;
2093 | this.addedNodes = [];
2094 | this.removedNodes = [];
2095 | this.previousSibling = null;
2096 | this.nextSibling = null;
2097 | this.attributeName = null;
2098 | this.attributeNamespace = null;
2099 | this.oldValue = null;
2100 | }
2101 |
2102 | function copyMutationRecord(original) {
2103 | var record = new MutationRecord(original.type, original.target);
2104 | record.addedNodes = original.addedNodes.slice();
2105 | record.removedNodes = original.removedNodes.slice();
2106 | record.previousSibling = original.previousSibling;
2107 | record.nextSibling = original.nextSibling;
2108 | record.attributeName = original.attributeName;
2109 | record.attributeNamespace = original.attributeNamespace;
2110 | record.oldValue = original.oldValue;
2111 | return record;
2112 | };
2113 |
2114 | // We keep track of the two (possibly one) records used in a single mutation.
2115 | var currentRecord, recordWithOldValue;
2116 |
2117 | /**
2118 | * Creates a record without |oldValue| and caches it as |currentRecord| for
2119 | * later use.
2120 | * @param {string} oldValue
2121 | * @return {MutationRecord}
2122 | */
2123 | function getRecord(type, target) {
2124 | return currentRecord = new MutationRecord(type, target);
2125 | }
2126 |
2127 | /**
2128 | * Gets or creates a record with |oldValue| based in the |currentRecord|
2129 | * @param {string} oldValue
2130 | * @return {MutationRecord}
2131 | */
2132 | function getRecordWithOldValue(oldValue) {
2133 | if (recordWithOldValue)
2134 | return recordWithOldValue;
2135 | recordWithOldValue = copyMutationRecord(currentRecord);
2136 | recordWithOldValue.oldValue = oldValue;
2137 | return recordWithOldValue;
2138 | }
2139 |
2140 | function clearRecords() {
2141 | currentRecord = recordWithOldValue = undefined;
2142 | }
2143 |
2144 | /**
2145 | * @param {MutationRecord} record
2146 | * @return {boolean} Whether the record represents a record from the current
2147 | * mutation event.
2148 | */
2149 | function recordRepresentsCurrentMutation(record) {
2150 | return record === recordWithOldValue || record === currentRecord;
2151 | }
2152 |
2153 | /**
2154 | * Selects which record, if any, to replace the last record in the queue.
2155 | * This returns |null| if no record should be replaced.
2156 | *
2157 | * @param {MutationRecord} lastRecord
2158 | * @param {MutationRecord} newRecord
2159 | * @param {MutationRecord}
2160 | */
2161 | function selectRecord(lastRecord, newRecord) {
2162 | if (lastRecord === newRecord)
2163 | return lastRecord;
2164 |
2165 | // Check if the the record we are adding represents the same record. If
2166 | // so, we keep the one with the oldValue in it.
2167 | if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord))
2168 | return recordWithOldValue;
2169 |
2170 | return null;
2171 | }
2172 |
2173 | /**
2174 | * Class used to represent a registered observer.
2175 | * @param {MutationObserver} observer
2176 | * @param {Node} target
2177 | * @param {MutationObserverInit} options
2178 | * @constructor
2179 | */
2180 | function Registration(observer, target, options) {
2181 | this.observer = observer;
2182 | this.target = target;
2183 | this.options = options;
2184 | this.transientObservedNodes = [];
2185 | }
2186 |
2187 | Registration.prototype = {
2188 | enqueue: function(record) {
2189 | var records = this.observer.records_;
2190 | var length = records.length;
2191 |
2192 | // There are cases where we replace the last record with the new record.
2193 | // For example if the record represents the same mutation we need to use
2194 | // the one with the oldValue. If we get same record (this can happen as we
2195 | // walk up the tree) we ignore the new record.
2196 | if (records.length > 0) {
2197 | var lastRecord = records[length - 1];
2198 | var recordToReplaceLast = selectRecord(lastRecord, record);
2199 | if (recordToReplaceLast) {
2200 | records[length - 1] = recordToReplaceLast;
2201 | return;
2202 | }
2203 | } else {
2204 | scheduleCallback(this.observer);
2205 | }
2206 |
2207 | records[length] = record;
2208 | },
2209 |
2210 | addListeners: function() {
2211 | this.addListeners_(this.target);
2212 | },
2213 |
2214 | addListeners_: function(node) {
2215 | var options = this.options;
2216 | if (options.attributes)
2217 | node.addEventListener('DOMAttrModified', this, true);
2218 |
2219 | if (options.characterData)
2220 | node.addEventListener('DOMCharacterDataModified', this, true);
2221 |
2222 | if (options.childList)
2223 | node.addEventListener('DOMNodeInserted', this, true);
2224 |
2225 | if (options.childList || options.subtree)
2226 | node.addEventListener('DOMNodeRemoved', this, true);
2227 | },
2228 |
2229 | removeListeners: function() {
2230 | this.removeListeners_(this.target);
2231 | },
2232 |
2233 | removeListeners_: function(node) {
2234 | var options = this.options;
2235 | if (options.attributes)
2236 | node.removeEventListener('DOMAttrModified', this, true);
2237 |
2238 | if (options.characterData)
2239 | node.removeEventListener('DOMCharacterDataModified', this, true);
2240 |
2241 | if (options.childList)
2242 | node.removeEventListener('DOMNodeInserted', this, true);
2243 |
2244 | if (options.childList || options.subtree)
2245 | node.removeEventListener('DOMNodeRemoved', this, true);
2246 | },
2247 |
2248 | /**
2249 | * Adds a transient observer on node. The transient observer gets removed
2250 | * next time we deliver the change records.
2251 | * @param {Node} node
2252 | */
2253 | addTransientObserver: function(node) {
2254 | // Don't add transient observers on the target itself. We already have all
2255 | // the required listeners set up on the target.
2256 | if (node === this.target)
2257 | return;
2258 |
2259 | this.addListeners_(node);
2260 | this.transientObservedNodes.push(node);
2261 | var registrations = registrationsTable.get(node);
2262 | if (!registrations)
2263 | registrationsTable.set(node, registrations = []);
2264 |
2265 | // We know that registrations does not contain this because we already
2266 | // checked if node === this.target.
2267 | registrations.push(this);
2268 | },
2269 |
2270 | removeTransientObservers: function() {
2271 | var transientObservedNodes = this.transientObservedNodes;
2272 | this.transientObservedNodes = [];
2273 |
2274 | transientObservedNodes.forEach(function(node) {
2275 | // Transient observers are never added to the target.
2276 | this.removeListeners_(node);
2277 |
2278 | var registrations = registrationsTable.get(node);
2279 | for (var i = 0; i < registrations.length; i++) {
2280 | if (registrations[i] === this) {
2281 | registrations.splice(i, 1);
2282 | // Each node can only have one registered observer associated with
2283 | // this observer.
2284 | break;
2285 | }
2286 | }
2287 | }, this);
2288 | },
2289 |
2290 | handleEvent: function(e) {
2291 | // Stop propagation since we are managing the propagation manually.
2292 | // This means that other mutation events on the page will not work
2293 | // correctly but that is by design.
2294 | e.stopImmediatePropagation();
2295 |
2296 | switch (e.type) {
2297 | case 'DOMAttrModified':
2298 | // http://dom.spec.whatwg.org/#concept-mo-queue-attributes
2299 |
2300 | var name = e.attrName;
2301 | var namespace = e.relatedNode.namespaceURI;
2302 | var target = e.target;
2303 |
2304 | // 1.
2305 | var record = new getRecord('attributes', target);
2306 | record.attributeName = name;
2307 | record.attributeNamespace = namespace;
2308 |
2309 | // 2.
2310 | var oldValue =
2311 | e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;
2312 |
2313 | forEachAncestorAndObserverEnqueueRecord(target, function(options) {
2314 | // 3.1, 4.2
2315 | if (!options.attributes)
2316 | return;
2317 |
2318 | // 3.2, 4.3
2319 | if (options.attributeFilter && options.attributeFilter.length &&
2320 | options.attributeFilter.indexOf(name) === -1 &&
2321 | options.attributeFilter.indexOf(namespace) === -1) {
2322 | return;
2323 | }
2324 | // 3.3, 4.4
2325 | if (options.attributeOldValue)
2326 | return getRecordWithOldValue(oldValue);
2327 |
2328 | // 3.4, 4.5
2329 | return record;
2330 | });
2331 |
2332 | break;
2333 |
2334 | case 'DOMCharacterDataModified':
2335 | // http://dom.spec.whatwg.org/#concept-mo-queue-characterdata
2336 | var target = e.target;
2337 |
2338 | // 1.
2339 | var record = getRecord('characterData', target);
2340 |
2341 | // 2.
2342 | var oldValue = e.prevValue;
2343 |
2344 |
2345 | forEachAncestorAndObserverEnqueueRecord(target, function(options) {
2346 | // 3.1, 4.2
2347 | if (!options.characterData)
2348 | return;
2349 |
2350 | // 3.2, 4.3
2351 | if (options.characterDataOldValue)
2352 | return getRecordWithOldValue(oldValue);
2353 |
2354 | // 3.3, 4.4
2355 | return record;
2356 | });
2357 |
2358 | break;
2359 |
2360 | case 'DOMNodeRemoved':
2361 | this.addTransientObserver(e.target);
2362 | // Fall through.
2363 | case 'DOMNodeInserted':
2364 | // http://dom.spec.whatwg.org/#concept-mo-queue-childlist
2365 | var target = e.relatedNode;
2366 | var changedNode = e.target;
2367 | var addedNodes, removedNodes;
2368 | if (e.type === 'DOMNodeInserted') {
2369 | addedNodes = [changedNode];
2370 | removedNodes = [];
2371 | } else {
2372 |
2373 | addedNodes = [];
2374 | removedNodes = [changedNode];
2375 | }
2376 | var previousSibling = changedNode.previousSibling;
2377 | var nextSibling = changedNode.nextSibling;
2378 |
2379 | // 1.
2380 | var record = getRecord('childList', target);
2381 | record.addedNodes = addedNodes;
2382 | record.removedNodes = removedNodes;
2383 | record.previousSibling = previousSibling;
2384 | record.nextSibling = nextSibling;
2385 |
2386 | forEachAncestorAndObserverEnqueueRecord(target, function(options) {
2387 | // 2.1, 3.2
2388 | if (!options.childList)
2389 | return;
2390 |
2391 | // 2.2, 3.3
2392 | return record;
2393 | });
2394 |
2395 | }
2396 |
2397 | clearRecords();
2398 | }
2399 | };
2400 |
2401 | if (!MutationObserver) {
2402 | MutationObserver = JsMutationObserver;
2403 | }
2404 |
2405 | module.exports = MutationObserver;
2406 |
2407 | },{}],27:[function(require,module,exports){
2408 |
2409 | /**
2410 | * Module exports.
2411 | */
2412 |
2413 | module.exports = loadStyles;
2414 |
2415 | /**
2416 | * Injects the CSS into the DOM node.
2417 | *
2418 | * @param {String} css CSS string to add to the