- if (this.tagName === 'INPUT' && name === 'type') {
- this.type = value;
- }
- else {
- var attributes = this._attributes[namespace] || (this._attributes[namespace] = {});
- attributes[localName] = {value: value, prefix: prefix};
- }
- };
-
-DOMElement.prototype.getAttributeNS =
- function _Element_getAttributeNS(namespace, name) {
- var attributes = this._attributes[namespace];
- var value = attributes && attributes[name] && attributes[name].value;
- if (this.tagName === 'INPUT' && name === 'type') {
- return this.type;
- }
- if (typeof value !== "string") {
- return null
- }
- return value
- };
-
-DOMElement.prototype.removeAttributeNS =
- function _Element_removeAttributeNS(namespace, name) {
- var attributes = this._attributes[namespace];
- if (attributes) {
- delete attributes[name];
- }
- };
-
-DOMElement.prototype.hasAttributeNS =
- function _Element_hasAttributeNS(namespace, name) {
- var attributes = this._attributes[namespace];
- return !!attributes && name in attributes;
- };
-
-DOMElement.prototype.setAttribute = function _Element_setAttribute(name, value) {
- return this.setAttributeNS(null, name, value)
-};
-
-DOMElement.prototype.getAttribute = function _Element_getAttribute(name) {
- return this.getAttributeNS(null, name)
-};
-
-DOMElement.prototype.removeAttribute = function _Element_removeAttribute(name) {
- return this.removeAttributeNS(null, name)
-};
-
-DOMElement.prototype.hasAttribute = function _Element_hasAttribute(name) {
- return this.hasAttributeNS(null, name)
-};
-
-DOMElement.prototype.removeEventListener = removeEventListener_1;
-DOMElement.prototype.addEventListener = addEventListener_1;
-DOMElement.prototype.dispatchEvent = dispatchEvent_1;
-
-// Un-implemented
-DOMElement.prototype.focus = function _Element_focus() {
- return void 0
-};
-
-DOMElement.prototype.toString = function _Element_toString() {
- return serialize(this)
-};
-
-DOMElement.prototype.getElementsByClassName = function _Element_getElementsByClassName(classNames) {
- var classes = classNames.split(" ");
- var elems = [];
-
- domWalk(this, function (node) {
- if (node.nodeType === 1) {
- var nodeClassName = node.className || "";
- var nodeClasses = nodeClassName.split(" ");
-
- if (classes.every(function (item) {
- return nodeClasses.indexOf(item) !== -1
- })) {
- elems.push(node);
- }
- }
- });
-
- return elems
-};
-
-DOMElement.prototype.getElementsByTagName = function _Element_getElementsByTagName(tagName) {
- tagName = tagName.toLowerCase();
- var elems = [];
-
- domWalk(this.childNodes, function (node) {
- if (node.nodeType === 1 && (tagName === '*' || node.tagName.toLowerCase() === tagName)) {
- elems.push(node);
- }
- });
-
- return elems
-};
-
-DOMElement.prototype.contains = function _Element_contains(element) {
- return domWalk(this, function (node) {
- return element === node
- }) || false
-};
-
-var domFragment = DocumentFragment;
-
-function DocumentFragment(owner) {
- if (!(this instanceof DocumentFragment)) {
- return new DocumentFragment()
- }
-
- this.childNodes = [];
- this.parentNode = null;
- this.ownerDocument = owner || null;
-}
-
-DocumentFragment.prototype.type = "DocumentFragment";
-DocumentFragment.prototype.nodeType = 11;
-DocumentFragment.prototype.nodeName = "#document-fragment";
-
-DocumentFragment.prototype.appendChild = domElement.prototype.appendChild;
-DocumentFragment.prototype.replaceChild = domElement.prototype.replaceChild;
-DocumentFragment.prototype.removeChild = domElement.prototype.removeChild;
-
-DocumentFragment.prototype.toString =
- function _DocumentFragment_toString() {
- return this.childNodes.map(function (node) {
- return String(node)
- }).join("")
- };
-
-var event = Event;
-
-function Event(family) {}
-
-Event.prototype.initEvent = function _Event_initEvent(type, bubbles, cancelable) {
- this.type = type;
- this.bubbles = bubbles;
- this.cancelable = cancelable;
-};
-
-Event.prototype.preventDefault = function _Event_preventDefault() {
-
-};
-
-var document$1 = Document;
-
-function Document() {
- if (!(this instanceof Document)) {
- return new Document();
- }
-
- this.head = this.createElement("head");
- this.body = this.createElement("body");
- this.documentElement = this.createElement("html");
- this.documentElement.appendChild(this.head);
- this.documentElement.appendChild(this.body);
- this.childNodes = [this.documentElement];
- this.nodeType = 9;
-}
-
-var proto = Document.prototype;
-proto.createTextNode = function createTextNode(value) {
- return new domText(value, this)
-};
-
-proto.createElementNS = function createElementNS(namespace, tagName) {
- var ns = namespace === null ? null : String(namespace);
- return new domElement(tagName, this, ns)
-};
-
-proto.createElement = function createElement(tagName) {
- return new domElement(tagName, this)
-};
-
-proto.createDocumentFragment = function createDocumentFragment() {
- return new domFragment(this)
-};
-
-proto.createEvent = function createEvent(family) {
- return new event(family)
-};
-
-proto.createComment = function createComment(data) {
- return new domComment(data, this)
-};
-
-proto.getElementById = function getElementById(id) {
- id = String(id);
-
- var result = domWalk(this.childNodes, function (node) {
- if (String(node.id) === id) {
- return node
- }
- });
-
- return result || null
-};
-
-proto.getElementsByClassName = domElement.prototype.getElementsByClassName;
-proto.getElementsByTagName = domElement.prototype.getElementsByTagName;
-proto.contains = domElement.prototype.contains;
-
-proto.removeEventListener = removeEventListener_1;
-proto.addEventListener = addEventListener_1;
-proto.dispatchEvent = dispatchEvent_1;
-
-var minDocument = new document$1();
-
-var topLevel = typeof commonjsGlobal !== 'undefined' ? commonjsGlobal :
- typeof window !== 'undefined' ? window : {};
-
-
-var doccy;
-
-if (typeof document !== 'undefined') {
- doccy = document;
-} else {
- doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'];
-
- if (!doccy) {
- doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDocument;
- }
-}
-
-var document_1 = doccy;
-
-var applyProperties_1 = applyProperties;
-
-function applyProperties(node, props, previous) {
- for (var propName in props) {
- var propValue = props[propName];
-
- if (propValue === undefined) {
- removeProperty(node, propName, propValue, previous);
- } else if (isVhook(propValue)) {
- removeProperty(node, propName, propValue, previous);
- if (propValue.hook) {
- propValue.hook(node,
- propName,
- previous ? previous[propName] : undefined);
- }
- } else {
- if (isObject(propValue)) {
- patchObject(node, props, previous, propName, propValue);
- } else {
- node[propName] = propValue;
- }
- }
- }
-}
-
-function removeProperty(node, propName, propValue, previous) {
- if (previous) {
- var previousValue = previous[propName];
-
- if (!isVhook(previousValue)) {
- if (propName === "attributes") {
- for (var attrName in previousValue) {
- node.removeAttribute(attrName);
- }
- } else if (propName === "style") {
- for (var i in previousValue) {
- node.style[i] = "";
- }
- } else if (typeof previousValue === "string") {
- node[propName] = "";
- } else {
- node[propName] = null;
- }
- } else if (previousValue.unhook) {
- previousValue.unhook(node, propName, propValue);
- }
- }
-}
-
-function patchObject(node, props, previous, propName, propValue) {
- var previousValue = previous ? previous[propName] : undefined;
-
- // Set attributes
- if (propName === "attributes") {
- for (var attrName in propValue) {
- var attrValue = propValue[attrName];
-
- if (attrValue === undefined) {
- node.removeAttribute(attrName);
- } else {
- node.setAttribute(attrName, attrValue);
- }
- }
-
- return
- }
-
- if(previousValue && isObject(previousValue) &&
- getPrototype(previousValue) !== getPrototype(propValue)) {
- node[propName] = propValue;
- return
- }
-
- if (!isObject(node[propName])) {
- node[propName] = {};
- }
-
- var replacer = propName === "style" ? "" : undefined;
-
- for (var k in propValue) {
- var value = propValue[k];
- node[propName][k] = (value === undefined) ? replacer : value;
- }
-}
-
-function getPrototype(value) {
- if (Object.getPrototypeOf) {
- return Object.getPrototypeOf(value)
- } else if (value.__proto__) {
- return value.__proto__
- } else if (value.constructor) {
- return value.constructor.prototype
- }
-}
-
-var createElement_1$1 = createElement;
-
-function createElement(vnode, opts) {
- var doc = opts ? opts.document || document_1 : document_1;
- var warn = opts ? opts.warn : null;
-
- vnode = handleThunk_1(vnode).a;
-
- if (isWidget_1(vnode)) {
- return vnode.init()
- } else if (isVtext(vnode)) {
- return doc.createTextNode(vnode.text)
- } else if (!isVnode(vnode)) {
- if (warn) {
- warn("Item is not a valid virtual dom node", vnode);
- }
- return null
- }
-
- var node = (vnode.namespace === null) ?
- doc.createElement(vnode.tagName) :
- doc.createElementNS(vnode.namespace, vnode.tagName);
-
- var props = vnode.properties;
- applyProperties_1(node, props);
-
- var children = vnode.children;
-
- for (var i = 0; i < children.length; i++) {
- var childNode = createElement(children[i], opts);
- if (childNode) {
- node.appendChild(childNode);
- }
- }
-
- return node
-}
-
-// Maps a virtual DOM tree onto a real DOM tree in an efficient manner.
-// We don't want to read all of the DOM nodes in the tree so we use
-// the in-order tree indexing to eliminate recursion down certain branches.
-// We only recurse into a DOM node if we know that it contains a child of
-// interest.
-
-var noChild = {};
-
-var domIndex_1 = domIndex;
-
-function domIndex(rootNode, tree, indices, nodes) {
- if (!indices || indices.length === 0) {
- return {}
- } else {
- indices.sort(ascending);
- return recurse(rootNode, tree, indices, nodes, 0)
- }
-}
-
-function recurse(rootNode, tree, indices, nodes, rootIndex) {
- nodes = nodes || {};
-
-
- if (rootNode) {
- if (indexInRange(indices, rootIndex, rootIndex)) {
- nodes[rootIndex] = rootNode;
- }
-
- var vChildren = tree.children;
-
- if (vChildren) {
-
- var childNodes = rootNode.childNodes;
-
- for (var i = 0; i < tree.children.length; i++) {
- rootIndex += 1;
-
- var vChild = vChildren[i] || noChild;
- var nextIndex = rootIndex + (vChild.count || 0);
-
- // skip recursion down the tree if there are no nodes down here
- if (indexInRange(indices, rootIndex, nextIndex)) {
- recurse(childNodes[i], vChild, indices, nodes, rootIndex);
- }
-
- rootIndex = nextIndex;
- }
- }
- }
-
- return nodes
-}
-
-// Binary search for an index in the interval [left, right]
-function indexInRange(indices, left, right) {
- if (indices.length === 0) {
- return false
- }
-
- var minIndex = 0;
- var maxIndex = indices.length - 1;
- var currentIndex;
- var currentItem;
-
- while (minIndex <= maxIndex) {
- currentIndex = ((maxIndex + minIndex) / 2) >> 0;
- currentItem = indices[currentIndex];
-
- if (minIndex === maxIndex) {
- return currentItem >= left && currentItem <= right
- } else if (currentItem < left) {
- minIndex = currentIndex + 1;
- } else if (currentItem > right) {
- maxIndex = currentIndex - 1;
- } else {
- return true
- }
- }
-
- return false;
-}
-
-function ascending(a, b) {
- return a > b ? 1 : -1
-}
-
-var updateWidget_1 = updateWidget;
-
-function updateWidget(a, b) {
- if (isWidget_1(a) && isWidget_1(b)) {
- if ("name" in a && "name" in b) {
- return a.id === b.id
- } else {
- return a.init === b.init
- }
- }
-
- return false
-}
-
-var patchOp = applyPatch$1;
-
-function applyPatch$1(vpatch$1, domNode, renderOptions) {
- var type = vpatch$1.type;
- var vNode = vpatch$1.vNode;
- var patch = vpatch$1.patch;
-
- switch (type) {
- case vpatch.REMOVE:
- return removeNode$1(domNode, vNode)
- case vpatch.INSERT:
- return insertNode$1(domNode, patch, renderOptions)
- case vpatch.VTEXT:
- return stringPatch(domNode, vNode, patch, renderOptions)
- case vpatch.WIDGET:
- return widgetPatch(domNode, vNode, patch, renderOptions)
- case vpatch.VNODE:
- return vNodePatch(domNode, vNode, patch, renderOptions)
- case vpatch.ORDER:
- reorderChildren(domNode, patch);
- return domNode
- case vpatch.PROPS:
- applyProperties_1(domNode, patch, vNode.properties);
- return domNode
- case vpatch.THUNK:
- return replaceRoot(domNode,
- renderOptions.patch(domNode, patch, renderOptions))
- default:
- return domNode
- }
-}
-
-function removeNode$1(domNode, vNode) {
- var parentNode = domNode.parentNode;
-
- if (parentNode) {
- parentNode.removeChild(domNode);
- }
-
- destroyWidget(domNode, vNode);
-
- return null
-}
-
-function insertNode$1(parentNode, vNode, renderOptions) {
- var newNode = renderOptions.render(vNode, renderOptions);
-
- if (parentNode) {
- parentNode.appendChild(newNode);
- }
-
- return parentNode
-}
-
-function stringPatch(domNode, leftVNode, vText, renderOptions) {
- var newNode;
-
- if (domNode.nodeType === 3) {
- domNode.replaceData(0, domNode.length, vText.text);
- newNode = domNode;
- } else {
- var parentNode = domNode.parentNode;
- newNode = renderOptions.render(vText, renderOptions);
-
- if (parentNode && newNode !== domNode) {
- parentNode.replaceChild(newNode, domNode);
- }
- }
-
- return newNode
-}
-
-function widgetPatch(domNode, leftVNode, widget, renderOptions) {
- var updating = updateWidget_1(leftVNode, widget);
- var newNode;
-
- if (updating) {
- newNode = widget.update(leftVNode, domNode) || domNode;
- } else {
- newNode = renderOptions.render(widget, renderOptions);
- }
-
- var parentNode = domNode.parentNode;
-
- if (parentNode && newNode !== domNode) {
- parentNode.replaceChild(newNode, domNode);
- }
-
- if (!updating) {
- destroyWidget(domNode, leftVNode);
- }
-
- return newNode
-}
-
-function vNodePatch(domNode, leftVNode, vNode, renderOptions) {
- var parentNode = domNode.parentNode;
- var newNode = renderOptions.render(vNode, renderOptions);
-
- if (parentNode && newNode !== domNode) {
- parentNode.replaceChild(newNode, domNode);
- }
-
- return newNode
-}
-
-function destroyWidget(domNode, w) {
- if (typeof w.destroy === "function" && isWidget_1(w)) {
- w.destroy(domNode);
- }
-}
-
-function reorderChildren(domNode, moves) {
- var childNodes = domNode.childNodes;
- var keyMap = {};
- var node;
- var remove;
- var insert;
-
- for (var i = 0; i < moves.removes.length; i++) {
- remove = moves.removes[i];
- node = childNodes[remove.from];
- if (remove.key) {
- keyMap[remove.key] = node;
- }
- domNode.removeChild(node);
- }
-
- var length = childNodes.length;
- for (var j = 0; j < moves.inserts.length; j++) {
- insert = moves.inserts[j];
- node = keyMap[insert.key];
- // this is the weirdest bug i've ever seen in webkit
- domNode.insertBefore(node, insert.to >= length++ ? null : childNodes[insert.to]);
- }
-}
-
-function replaceRoot(oldRoot, newRoot) {
- if (oldRoot && newRoot && oldRoot !== newRoot && oldRoot.parentNode) {
- oldRoot.parentNode.replaceChild(newRoot, oldRoot);
- }
-
- return newRoot;
-}
-
-var patch_1$1 = patch;
-
-function patch(rootNode, patches, renderOptions) {
- renderOptions = renderOptions || {};
- renderOptions.patch = renderOptions.patch && renderOptions.patch !== patch
- ? renderOptions.patch
- : patchRecursive;
- renderOptions.render = renderOptions.render || createElement_1$1;
-
- return renderOptions.patch(rootNode, patches, renderOptions)
-}
-
-function patchRecursive(rootNode, patches, renderOptions) {
- var indices = patchIndices(patches);
-
- if (indices.length === 0) {
- return rootNode
- }
-
- var index = domIndex_1(rootNode, patches.a, indices);
- var ownerDocument = rootNode.ownerDocument;
-
- if (!renderOptions.document && ownerDocument !== document_1) {
- renderOptions.document = ownerDocument;
- }
-
- for (var i = 0; i < indices.length; i++) {
- var nodeIndex = indices[i];
- rootNode = applyPatch(rootNode,
- index[nodeIndex],
- patches[nodeIndex],
- renderOptions);
- }
-
- return rootNode
-}
-
-function applyPatch(rootNode, domNode, patchList, renderOptions) {
- if (!domNode) {
- return rootNode
- }
-
- var newNode;
-
- if (xIsArray(patchList)) {
- for (var i = 0; i < patchList.length; i++) {
- newNode = patchOp(patchList[i], domNode, renderOptions);
-
- if (domNode === rootNode) {
- rootNode = newNode;
- }
- }
- } else {
- newNode = patchOp(patchList, domNode, renderOptions);
-
- if (domNode === rootNode) {
- rootNode = newNode;
- }
- }
-
- return rootNode
-}
-
-function patchIndices(patches) {
- var indices = [];
-
- for (var key in patches) {
- if (key !== "a") {
- indices.push(Number(key));
- }
- }
-
- return indices
-}
-
-var patch_1 = patch_1$1;
-
-var vnode = VirtualNode;
-
-var noProperties = {};
-var noChildren = [];
-
-function VirtualNode(tagName, properties, children, key, namespace) {
- this.tagName = tagName;
- this.properties = properties || noProperties;
- this.children = children || noChildren;
- this.key = key != null ? String(key) : undefined;
- this.namespace = (typeof namespace === "string") ? namespace : null;
-
- var count = (children && children.length) || 0;
- var descendants = 0;
- var hasWidgets = false;
- var hasThunks = false;
- var descendantHooks = false;
- var hooks;
-
- for (var propName in properties) {
- if (properties.hasOwnProperty(propName)) {
- var property = properties[propName];
- if (isVhook(property) && property.unhook) {
- if (!hooks) {
- hooks = {};
- }
-
- hooks[propName] = property;
- }
- }
- }
-
- for (var i = 0; i < count; i++) {
- var child = children[i];
- if (isVnode(child)) {
- descendants += child.count || 0;
-
- if (!hasWidgets && child.hasWidgets) {
- hasWidgets = true;
- }
-
- if (!hasThunks && child.hasThunks) {
- hasThunks = true;
- }
-
- if (!descendantHooks && (child.hooks || child.descendantHooks)) {
- descendantHooks = true;
- }
- } else if (!hasWidgets && isWidget_1(child)) {
- if (typeof child.destroy === "function") {
- hasWidgets = true;
- }
- } else if (!hasThunks && isThunk_1(child)) {
- hasThunks = true;
- }
- }
-
- this.count = count + descendants;
- this.hasWidgets = hasWidgets;
- this.hasThunks = hasThunks;
- this.hooks = hooks;
- this.descendantHooks = descendantHooks;
-}
-
-VirtualNode.prototype.version = version;
-VirtualNode.prototype.type = "VirtualNode";
-
-var vtext = VirtualText;
-
-function VirtualText(text) {
- this.text = String(text);
-}
-
-VirtualText.prototype.version = version;
-VirtualText.prototype.type = "VirtualText";
-
-/*!
- * Cross-Browser Split 1.1.1
- * Copyright 2007-2012 Steven Levithan <stevenlevithan.com>
- * Available under the MIT License
- * ECMAScript compliant, uniform cross-browser split method
- */
-/**
- * Splits a string into an array of strings using a regex or string separator. Matches of the
- * separator are not included in the result array. However, if `separator` is a regex that contains
- * capturing groups, backreferences are spliced into the result each time `separator` is matched.
- * Fixes browser bugs compared to the native `String.prototype.split` and can be used reliably
- * cross-browser.
- * @param {String} str String to split.
- * @param {RegExp|String} separator Regex or string to use for separating the string.
- * @param {Number} [limit] Maximum number of items to include in the result array.
- * @returns {Array} Array of substrings.
- * @example
- *
- * // Basic use
- * split('a b c d', ' ');
- * // -> ['a', 'b', 'c', 'd']
- *
- * // With limit
- * split('a b c d', ' ', 2);
- * // -> ['a', 'b']
- *
- * // Backreferences in result array
- * split('..word1 word2..', /([a-z]+)(\d+)/i);
- * // -> ['..', 'word', '1', ' ', 'word', '2', '..']
- */
-var browserSplit = (function split(undef) {
-
- var nativeSplit = String.prototype.split,
- compliantExecNpcg = /()??/.exec("")[1] === undef,
- // NPCG: nonparticipating capturing group
- self;
-
- self = function(str, separator, limit) {
- // If `separator` is not a regex, use `nativeSplit`
- if (Object.prototype.toString.call(separator) !== "[object RegExp]") {
- return nativeSplit.call(str, separator, limit);
- }
- var output = [],
- flags = (separator.ignoreCase ? "i" : "") + (separator.multiline ? "m" : "") + (separator.extended ? "x" : "") + // Proposed for ES6
- (separator.sticky ? "y" : ""),
- // Firefox 3+
- lastLastIndex = 0,
- // Make `global` and avoid `lastIndex` issues by working with a copy
- separator = new RegExp(separator.source, flags + "g"),
- separator2, match, lastIndex, lastLength;
- str += ""; // Type-convert
- if (!compliantExecNpcg) {
- // Doesn't need flags gy, but they don't hurt
- separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags);
- }
- /* Values for `limit`, per the spec:
- * If undefined: 4294967295 // Math.pow(2, 32) - 1
- * If 0, Infinity, or NaN: 0
- * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
- * If negative number: 4294967296 - Math.floor(Math.abs(limit))
- * If other: Type-convert, then use the above rules
- */
- limit = limit === undef ? -1 >>> 0 : // Math.pow(2, 32) - 1
- limit >>> 0; // ToUint32(limit)
- while (match = separator.exec(str)) {
- // `separator.lastIndex` is not reliable cross-browser
- lastIndex = match.index + match[0].length;
- if (lastIndex > lastLastIndex) {
- output.push(str.slice(lastLastIndex, match.index));
- // Fix browsers whose `exec` methods don't consistently return `undefined` for
- // nonparticipating capturing groups
- if (!compliantExecNpcg && match.length > 1) {
- match[0].replace(separator2, function() {
- for (var i = 1; i < arguments.length - 2; i++) {
- if (arguments[i] === undef) {
- match[i] = undef;
- }
- }
- });
- }
- if (match.length > 1 && match.index < str.length) {
- Array.prototype.push.apply(output, match.slice(1));
- }
- lastLength = match[0].length;
- lastLastIndex = lastIndex;
- if (output.length >= limit) {
- break;
- }
- }
- if (separator.lastIndex === match.index) {
- separator.lastIndex++; // Avoid an infinite loop
- }
- }
- if (lastLastIndex === str.length) {
- if (lastLength || !separator.test("")) {
- output.push("");
- }
- } else {
- output.push(str.slice(lastLastIndex));
- }
- return output.length > limit ? output.slice(0, limit) : output;
- };
-
- return self;
-})();
-
-var classIdSplit = /([\.#]?[a-zA-Z0-9\u007F-\uFFFF_:-]+)/;
-var notClassId = /^\.|#/;
-
-var parseTag_1 = parseTag;
-
-function parseTag(tag, props) {
- if (!tag) {
- return 'DIV';
- }
-
- var noId = !(props.hasOwnProperty('id'));
-
- var tagParts = browserSplit(tag, classIdSplit);
- var tagName = null;
-
- if (notClassId.test(tagParts[1])) {
- tagName = 'DIV';
- }
-
- var classes, part, type, i;
-
- for (i = 0; i < tagParts.length; i++) {
- part = tagParts[i];
-
- if (!part) {
- continue;
- }
-
- type = part.charAt(0);
-
- if (!tagName) {
- tagName = part;
- } else if (type === '.') {
- classes = classes || [];
- classes.push(part.substring(1, part.length));
- } else if (type === '#' && noId) {
- props.id = part.substring(1, part.length);
- }
- }
-
- if (classes) {
- if (props.className) {
- classes.push(props.className);
- }
-
- props.className = classes.join(' ');
- }
-
- return props.namespace ? tagName : tagName.toUpperCase();
-}
-
-var softSetHook = SoftSetHook;
-
-function SoftSetHook(value) {
- if (!(this instanceof SoftSetHook)) {
- return new SoftSetHook(value);
- }
-
- this.value = value;
-}
-
-SoftSetHook.prototype.hook = function (node, propertyName) {
- if (node[propertyName] !== this.value) {
- node[propertyName] = this.value;
- }
-};
-
-/*global window, global*/
-
-var root = typeof window !== 'undefined' ?
- window : typeof commonjsGlobal !== 'undefined' ?
- commonjsGlobal : {};
-
-var individual = Individual;
-
-function Individual(key, value) {
- if (key in root) {
- return root[key];
- }
-
- root[key] = value;
-
- return value;
-}
-
-var oneVersion = OneVersion;
-
-function OneVersion(moduleName, version, defaultValue) {
- var key = '__INDIVIDUAL_ONE_VERSION_' + moduleName;
- var enforceKey = key + '_ENFORCE_SINGLETON';
-
- var versionValue = individual(enforceKey, version);
-
- if (versionValue !== version) {
- throw new Error('Can only have one copy of ' +
- moduleName + '.\n' +
- 'You already have version ' + versionValue +
- ' installed.\n' +
- 'This means you cannot install version ' + version);
- }
-
- return individual(key, defaultValue);
-}
-
-var MY_VERSION = '7';
-oneVersion('ev-store', MY_VERSION);
-
-var hashKey = '__EV_STORE_KEY@' + MY_VERSION;
-
-var evStore = EvStore;
-
-function EvStore(elem) {
- var hash = elem[hashKey];
-
- if (!hash) {
- hash = elem[hashKey] = {};
- }
-
- return hash;
-}
-
-var evHook = EvHook;
-
-function EvHook(value) {
- if (!(this instanceof EvHook)) {
- return new EvHook(value);
- }
-
- this.value = value;
-}
-
-EvHook.prototype.hook = function (node, propertyName) {
- var es = evStore(node);
- var propName = propertyName.substr(3);
-
- es[propName] = this.value;
-};
-
-EvHook.prototype.unhook = function(node, propertyName) {
- var es = evStore(node);
- var propName = propertyName.substr(3);
-
- es[propName] = undefined;
-};
-
-var virtualHyperscript = h;
-
-function h(tagName, properties, children) {
- var childNodes = [];
- var tag, props, key, namespace;
-
- if (!children && isChildren(properties)) {
- children = properties;
- props = {};
- }
-
- props = props || properties || {};
- tag = parseTag_1(tagName, props);
-
- // support keys
- if (props.hasOwnProperty('key')) {
- key = props.key;
- props.key = undefined;
- }
-
- // support namespace
- if (props.hasOwnProperty('namespace')) {
- namespace = props.namespace;
- props.namespace = undefined;
- }
-
- // fix cursor bug
- if (tag === 'INPUT' &&
- !namespace &&
- props.hasOwnProperty('value') &&
- props.value !== undefined &&
- !isVhook(props.value)
- ) {
- props.value = softSetHook(props.value);
- }
-
- transformProperties(props);
-
- if (children !== undefined && children !== null) {
- addChild(children, childNodes, tag, props);
- }
-
-
- return new vnode(tag, props, childNodes, key, namespace);
-}
-
-function addChild(c, childNodes, tag, props) {
- if (typeof c === 'string') {
- childNodes.push(new vtext(c));
- } else if (typeof c === 'number') {
- childNodes.push(new vtext(String(c)));
- } else if (isChild(c)) {
- childNodes.push(c);
- } else if (xIsArray(c)) {
- for (var i = 0; i < c.length; i++) {
- addChild(c[i], childNodes, tag, props);
- }
- } else if (c === null || c === undefined) {
- return;
- } else {
- throw UnexpectedVirtualElement({
- foreignObject: c,
- parentVnode: {
- tagName: tag,
- properties: props
- }
- });
- }
-}
-
-function transformProperties(props) {
- for (var propName in props) {
- if (props.hasOwnProperty(propName)) {
- var value = props[propName];
-
- if (isVhook(value)) {
- continue;
- }
-
- if (propName.substr(0, 3) === 'ev-') {
- // add ev-foo support
- props[propName] = evHook(value);
- }
- }
- }
-}
-
-function isChild(x) {
- return isVnode(x) || isVtext(x) || isWidget_1(x) || isThunk_1(x);
-}
-
-function isChildren(x) {
- return typeof x === 'string' || xIsArray(x) || isChild(x);
-}
-
-function UnexpectedVirtualElement(data) {
- var err = new Error();
-
- err.type = 'virtual-hyperscript.unexpected.virtual-element';
- err.message = 'Unexpected virtual child passed to h().\n' +
- 'Expected a VNode / Vthunk / VWidget / string but:\n' +
- 'got:\n' +
- errorString(data.foreignObject) +
- '.\n' +
- 'The parent vnode is:\n' +
- errorString(data.parentVnode);
- err.foreignObject = data.foreignObject;
- err.parentVnode = data.parentVnode;
-
- return err;
-}
-
-function errorString(obj) {
- try {
- return JSON.stringify(obj, null, ' ');
- } catch (e) {
- return String(obj);
- }
-}
-
-var h_1 = virtualHyperscript;
-
-var createElement_1 = createElement_1$1;
-
-var virtualDom = {
- diff: diff_1,
- patch: patch_1,
- h: h_1,
- create: createElement_1,
- VNode: vnode,
- VText: vtext
-};
-
-class EventEmitter {
- constructor() { this._events = {}; }
- /**
- * Subscribe to an event by its name.
- * @param {string} type - The name of the event
- * to subscribe to.
- * @param {(event: T) => void} handler - The
- * handler called when the event occurs.
- */
- on(type, handler) {
- this._events[type] = this._events[type] || [];
- this._events[type].push(handler);
- }
- /**
- * Unsubscribe from an event by its name.
- * @param {string} type - The name of the event
- * to unsubscribe from.
- * @param {(event: T) => void} handler - The
- * handler to remove.
- */
- off(type, handler) {
- if (!type) {
- this._events = {};
- return;
- }
- if (this._listens(type)) {
- const index = this._events[type].indexOf(handler);
- if (index >= 0) {
- this._events[type].splice(index, 1);
- }
- if (!this._events[type].length) {
- delete this._events[type];
- }
- }
- }
- /**
- * @ignore
- */
- fire(type, event) {
- if (!this._listens(type)) {
- return;
- }
- for (const handler of this._events[type]) {
- handler(event);
- }
- }
- _listens(eventType) {
- return eventType in this._events;
- }
-}
-
-class SubscriptionHolder {
- constructor() {
- this._subscriptions = [];
- }
- push(subscription) {
- this._subscriptions.push(subscription);
- }
- unsubscribe() {
- for (const sub of this._subscriptions) {
- sub.unsubscribe();
- }
- this._subscriptions = [];
- }
-}
-
-class Component extends EventEmitter {
- constructor(name, container, navigator) {
- super();
- this._activated$ = new BehaviorSubject(false);
- this._configurationSubject$ = new Subject();
- this._activated = false;
- this._container = container;
- this._name = name;
- this._navigator = navigator;
- this._subscriptions = new SubscriptionHolder();
- this._configuration$ =
- this._configurationSubject$.pipe(startWith(this.defaultConfiguration), scan((conf, newConf) => {
- for (let key in newConf) {
- if (newConf.hasOwnProperty(key)) {
- conf[key] = newConf[key];
- }
- }
- return conf;
- }), publishReplay(1), refCount());
- this._configuration$.subscribe(() => { });
- }
- /**
- * Get activated.
- *
- * @returns {boolean} Value indicating if the component is
- * currently active.
- */
- get activated() {
- return this._activated;
- }
- /** @ignore */
- get activated$() {
- return this._activated$;
- }
- /**
- * Get default configuration.
- *
- * @returns {TConfiguration} Default configuration for component.
- */
- get defaultConfiguration() {
- return this._getDefaultConfiguration();
- }
- /** @ignore */
- get configuration$() {
- return this._configuration$;
- }
- /**
- * Get name.
- *
- * @description The name of the component. Used when interacting with the
- * component through the Viewer's API.
- */
- get name() {
- return this._name;
- }
- /** @ignore */
- activate(conf) {
- if (this._activated) {
- return;
- }
- if (conf !== undefined) {
- this._configurationSubject$.next(conf);
- }
- this._activated = true;
- this._activate();
- this._activated$.next(true);
- }
- /**
- * Configure the component.
- *
- * @param configuration Component configuration.
- */
- configure(configuration) {
- this._configurationSubject$.next(configuration);
- }
- /** @ignore */
- deactivate() {
- if (!this._activated) {
- return;
- }
- this._activated = false;
- this._deactivate();
- this._container.domRenderer.clear(this._name);
- this._container.glRenderer.clear(this._name);
- this._activated$.next(false);
- }
- /** @inheritdoc */
- fire(type, event) {
- super.fire(type, event);
- }
- /** @inheritdoc */
- off(type, handler) {
- super.off(type, handler);
- }
- /** @inheritdoc */
- on(type, handler) {
- super.on(type, handler);
- }
- /**
- * Detect the viewer's new width and height and resize the component's
- * rendered elements accordingly if applicable.
- *
- * @ignore
- */
- resize() { return; }
-}
-
-var CoverState;
-(function (CoverState) {
- CoverState[CoverState["Hidden"] = 0] = "Hidden";
- CoverState[CoverState["Loading"] = 1] = "Loading";
- CoverState[CoverState["Visible"] = 2] = "Visible";
-})(CoverState || (CoverState = {}));
-
-class CoverComponent extends Component {
- constructor(name, container, navigator) {
- super(name, container, navigator);
- }
- _activate() {
- const originalSrc$ = this.configuration$.pipe(first((c) => {
- return !!c.id;
- }), filter((c) => {
- return !c.src;
- }), switchMap((c) => {
- return this._getImageSrc$(c.id).pipe(catchError((error) => {
- console.error(error);
- return empty();
- }));
- }), publishReplay(1), refCount());
- const subs = this._subscriptions;
- subs.push(originalSrc$.pipe(map((src) => {
- return { src: src };
- }))
- .subscribe((c) => {
- this._configurationSubject$.next(c);
- }));
- subs.push(combineLatest(this.configuration$, originalSrc$).pipe(filter(([c, src]) => {
- return !!c.src && c.src !== src;
- }), first())
- .subscribe(([, src]) => {
- window.URL.revokeObjectURL(src);
- }));
- subs.push(this._configuration$.pipe(distinctUntilChanged(undefined, (configuration) => {
- return configuration.state;
- }), switchMap((configuration) => {
- return combineLatest(of(configuration.state), this._navigator.stateService.currentImage$);
- }), switchMap(([state, image]) => {
- const keySrc$ = combineLatest(of(image.id), image.image$.pipe(filter((imageElement) => {
- return !!imageElement;
- }), map((imageElement) => {
- return imageElement.src;
- })));
- return state === CoverState.Visible ? keySrc$.pipe(first()) : keySrc$;
- }), distinctUntilChanged(([k1, s1], [k2, s2]) => {
- return k1 === k2 && s1 === s2;
- }), map(([key, src]) => {
- return { id: key, src: src };
- }))
- .subscribe(this._configurationSubject$));
- subs.push(combineLatest(this._configuration$, this._container.configurationService.exploreUrl$, this._container.renderService.size$).pipe(map(([configuration, exploreUrl, size]) => {
- if (!configuration.src) {
- return { name: this._name, vNode: virtualDom.h("div", []) };
- }
- const compactClass = size.width <= 640 || size.height <= 480 ? ".mapillary-cover-compact" : "";
- if (configuration.state === CoverState.Hidden) {
- const doneContainer = virtualDom.h("div.mapillary-cover-container.mapillary-cover-done" + compactClass, [this._getCoverBackgroundVNode(configuration)]);
- return { name: this._name, vNode: doneContainer };
- }
- const container = virtualDom.h("div.mapillary-cover-container" + compactClass, [this._getCoverButtonVNode(configuration, exploreUrl)]);
- return { name: this._name, vNode: container };
- }))
- .subscribe(this._container.domRenderer.render$));
- }
- _deactivate() {
- this._subscriptions.unsubscribe();
- }
- _getDefaultConfiguration() {
- return { state: CoverState.Visible };
- }
- _getCoverButtonVNode(configuration, exploreUrl) {
- const cover = configuration.state === CoverState.Loading ? "div.mapillary-cover.mapillary-cover-loading" : "div.mapillary-cover";
- const coverButton = virtualDom.h("div.mapillary-cover-button", [virtualDom.h("div.mapillary-cover-button-icon", [])]);
- const coverLogo = virtualDom.h("a.mapillary-cover-logo", { href: exploreUrl, target: "_blank" }, []);
- const coverIndicator = virtualDom.h("div.mapillary-cover-indicator", { onclick: () => { this.configure({ state: CoverState.Loading }); } }, []);
- return virtualDom.h(cover, [
- this._getCoverBackgroundVNode(configuration),
- coverIndicator,
- coverButton,
- coverLogo,
- ]);
- }
- _getCoverBackgroundVNode(conf) {
- const properties = {
- style: { backgroundImage: `url(${conf.src})` },
- };
- const children = [];
- if (conf.state === CoverState.Loading) {
- children.push(virtualDom.h("div.mapillary-cover-spinner", {}, []));
- }
- return virtualDom.h("div.mapillary-cover-background", properties, children);
- }
- _getImageSrc$(id) {
- return Observable.create((subscriber) => {
- this._navigator.api.getImages$([id])
- .subscribe((items) => {
- for (const item of items) {
- if (item.node_id !== id) {
- continue;
- }
- this._navigator.api.data
- .getImageBuffer(item.node.thumb.url)
- .then((buffer) => {
- const image = new Image();
- image.crossOrigin = "Anonymous";
- image.onload = () => {
- subscriber.next(image.src);
- subscriber.complete();
- };
- image.onerror = () => {
- subscriber.error(new Error(`Failed to load cover ` +
- `image (${id})`));
- };
- const blob = new Blob([buffer]);
- image.src = window.URL
- .createObjectURL(blob);
- }, (error) => {
- subscriber.error(error);
- });
- return;
- }
- subscriber.error(new MapillaryError(`Non existent cover key: ${id}`));
- }, (error) => {
- subscriber.error(error);
- });
- });
- }
-}
-CoverComponent.componentName = "cover";
-
-class AttributionComponent extends Component {
- _activate() {
- this._subscriptions.push(combineLatest(this._container.configurationService.exploreUrl$, this._navigator.stateService.currentImage$, this._container.renderService.size$).pipe(map(([exploreUrl, image, size]) => {
- const attribution = this._makeAttribution(image.creatorUsername, exploreUrl, image.id, image.capturedAt, size.width);
- return {
- name: this._name,
- vNode: attribution,
- };
- }))
- .subscribe(this._container.domRenderer.render$));
- }
- _deactivate() {
- this._subscriptions.unsubscribe();
- }
- _getDefaultConfiguration() {
- return {};
- }
- makeImageUrl(exploreUrl, id) {
- return `${exploreUrl}/app/?pKey=${id}&focus=photo`;
- }
- _makeAttribution(creatorUsername, exploreUrl, imageId, capturedAt, viewportWidth) {
- const compact = viewportWidth <= 640;
- const date = this._makeDate(capturedAt, compact);
- const by = this._makeBy(creatorUsername, exploreUrl, imageId, compact);
- const compactClass = compact ?
- ".mapillary-attribution-compact" : "";
- return virtualDom.h("div.mapillary-attribution-container" + compactClass, {}, [...by, date]);
- }
- _makeBy(creatorUsername, exploreUrl, imageId, compact) {
- const icon = virtualDom.h("div.mapillary-attribution-logo", []);
- return creatorUsername ?
- this._makeCreatorBy(icon, creatorUsername, exploreUrl, imageId, compact) :
- this._makeGeneralBy(icon, exploreUrl, imageId, compact);
- }
- _makeCreatorBy(icon, creatorUsername, exploreUrl, imageId, compact) {
- const mapillary = virtualDom.h("a.mapillary-attribution-icon-container", { href: exploreUrl, rel: "noreferrer", target: "_blank" }, [icon]);
- const content = compact ?
- `${creatorUsername}` : `image by ${creatorUsername}`;
- const imageBy = virtualDom.h("div.mapillary-attribution-username", { textContent: content }, []);
- const image = virtualDom.h("a.mapillary-attribution-image-container", {
- href: this.makeImageUrl(exploreUrl, imageId),
- rel: "noreferrer",
- target: "_blank",
- }, [imageBy]);
- return [mapillary, image];
- }
- _makeGeneralBy(icon, exploreUrl, imageId, compact) {
- const imagesBy = virtualDom.h("div.mapillary-attribution-username", { textContent: 'images by' }, []);
- const mapillary = virtualDom.h("div.mapillary-attribution-icon-container", {}, [icon]);
- const contributors = virtualDom.h("div.mapillary-attribution-username", { textContent: 'contributors' }, []);
- const children = [mapillary, contributors];
- if (!compact) {
- children.unshift(imagesBy);
- }
- const image = virtualDom.h("a.mapillary-attribution-image-container", {
- href: this.makeImageUrl(exploreUrl, imageId),
- rel: "noreferrer",
- target: "_blank",
- }, children);
- return [image];
- }
- _makeDate(capturedAt, compact) {
- const date = new Date(capturedAt)
- .toDateString()
- .split(" ");
- const formatted = (date.length > 3 ?
- compact ?
- [date[3]] :
- [date[1], date[2] + ",", date[3]] :
- date).join(" ");
- return virtualDom.h("div.mapillary-attribution-date", { textContent: formatted }, []);
- }
-}
-AttributionComponent.componentName = "attribution";
-
-/**
- * @class ViewportCoords
- *
- * @classdesc Provides methods for calculating 2D coordinate conversions
- * as well as 3D projection and unprojection.
- *
- * Basic coordinates are 2D coordinates on the [0, 1] interval and
- * have the origin point, (0, 0), at the top left corner and the
- * maximum value, (1, 1), at the bottom right corner of the original
- * image.
- *
- * Viewport coordinates are 2D coordinates on the [-1, 1] interval and
- * have the origin point in the center. The bottom left corner point is
- * (-1, -1) and the top right corner point is (1, 1).
- *
- * Canvas coordiantes are 2D pixel coordinates on the [0, canvasWidth] and
- * [0, canvasHeight] intervals. The origin point (0, 0) is in the top left
- * corner and the maximum value is (canvasWidth, canvasHeight) is in the
- * bottom right corner.
- *
- * 3D coordinates are in the topocentric world reference frame.
- */
-class ViewportCoords {
- constructor() {
- this._unprojectDepth = 200;
- }
- /**
- * Convert basic coordinates to canvas coordinates.
- *
- * @description Transform origin and camera position needs to be the
- * equal for reliable return value.
- *
- * @param {number} basicX - Basic X coordinate.
- * @param {number} basicY - Basic Y coordinate.
- * @param {HTMLElement} container - The viewer container.
- * @param {Transform} transform - Transform of the image to unproject from.
- * @param {THREE.Camera} camera - Camera used in rendering.
- * @returns {Array<number>} 2D canvas coordinates.
- */
- basicToCanvas(basicX, basicY, container, transform, camera) {
- const point3d = transform.unprojectBasic([basicX, basicY], this._unprojectDepth);
- const canvas = this.projectToCanvas(point3d, container, camera);
- return canvas;
- }
- /**
- * Convert basic coordinates to canvas coordinates safely. If 3D point is
- * behind camera null will be returned.
- *
- * @description Transform origin and camera position needs to be the
- * equal for reliable return value.
- *
- * @param {number} basicX - Basic X coordinate.
- * @param {number} basicY - Basic Y coordinate.
- * @param {HTMLElement} container - The viewer container.
- * @param {Transform} transform - Transform of the image to unproject from.
- * @param {THREE.Camera} camera - Camera used in rendering.
- * @returns {Array<number>} 2D canvas coordinates if the basic point represents a 3D point
- * in front of the camera, otherwise null.
- */
- basicToCanvasSafe(basicX, basicY, container, transform, camera) {
- const viewport = this.basicToViewportSafe(basicX, basicY, transform, camera);
- if (viewport === null) {
- return null;
- }
- const canvas = this.viewportToCanvas(viewport[0], viewport[1], container);
- return canvas;
- }
- /**
- * Convert basic coordinates to viewport coordinates.
- *
- * @description Transform origin and camera position needs to be the
- * equal for reliable return value.
- *
- * @param {number} basicX - Basic X coordinate.
- * @param {number} basicY - Basic Y coordinate.
- * @param {Transform} transform - Transform of the image to unproject from.
- * @param {THREE.Camera} camera - Camera used in rendering.
- * @returns {Array<number>} 2D viewport coordinates.
- */
- basicToViewport(basicX, basicY, transform, camera) {
- const point3d = transform.unprojectBasic([basicX, basicY], this._unprojectDepth);
- const viewport = this.projectToViewport(point3d, camera);
- return viewport;
- }
- /**
- * Convert basic coordinates to viewport coordinates safely. If 3D point is
- * behind camera null will be returned.
- *
- * @description Transform origin and camera position needs to be the
- * equal for reliable return value.
- *
- * @param {number} basicX - Basic X coordinate.
- * @param {number} basicY - Basic Y coordinate.
- * @param {Transform} transform - Transform of the image to unproject from.
- * @param {THREE.Camera} camera - Camera used in rendering.
- * @returns {Array<number>} 2D viewport coordinates.
- */
- basicToViewportSafe(basicX, basicY, transform, camera) {
- const point3d = transform.unprojectBasic([basicX, basicY], this._unprojectDepth);
- const pointCamera = this.worldToCamera(point3d, camera);
- if (pointCamera[2] > 0) {
- return null;
- }
- const viewport = this.projectToViewport(point3d, camera);
- return viewport;
- }
- /**
- * Convert camera 3D coordinates to viewport coordinates.
- *
- * @param {number} pointCamera - 3D point in camera coordinate system.
- * @param {THREE.Camera} camera - Camera used in rendering.
- * @returns {Array<number>} 2D viewport coordinates.
- */
- cameraToViewport(pointCamera, camera) {
- const viewport = new Vector3().fromArray(pointCamera)
- .applyMatrix4(camera.projectionMatrix);
- return [viewport.x, viewport.y];
- }
- /**
- * Get canvas pixel position from event.
- *
- * @param {Event} event - Event containing clientX and clientY properties.
- * @param {HTMLElement} element - HTML element.
- * @returns {Array<number>} 2D canvas coordinates.
- */
- canvasPosition(event, element) {
- const clientRect = element.getBoundingClientRect();
- const canvasX = event.clientX - clientRect.left - element.clientLeft;
- const canvasY = event.clientY - clientRect.top - element.clientTop;
- return [canvasX, canvasY];
- }
- /**
- * Convert canvas coordinates to basic coordinates.
- *
- * @description Transform origin and camera position needs to be the
- * equal for reliable return value.
- *
- * @param {number} canvasX - Canvas X coordinate.
- * @param {number} canvasY - Canvas Y coordinate.
- * @param {HTMLElement} container - The viewer container.
- * @param {Transform} transform - Transform of the image to unproject from.
- * @param {THREE.Camera} camera - Camera used in rendering.
- * @returns {Array<number>} 2D basic coordinates.
- */
- canvasToBasic(canvasX, canvasY, container, transform, camera) {
- const point3d = this.unprojectFromCanvas(canvasX, canvasY, container, camera)
- .toArray();
- const basic = transform.projectBasic(point3d);
- return basic;
- }
- /**
- * Convert canvas coordinates to viewport coordinates.
- *
- * @param {number} canvasX - Canvas X coordinate.
- * @param {number} canvasY - Canvas Y coordinate.
- * @param {HTMLElement} container - The viewer container.
- * @returns {Array<number>} 2D viewport coordinates.
- */
- canvasToViewport(canvasX, canvasY, container) {
- const [canvasWidth, canvasHeight] = this.containerToCanvas(container);
- const viewportX = 2 * canvasX / canvasWidth - 1;
- const viewportY = 1 - 2 * canvasY / canvasHeight;
- return [viewportX, viewportY];
- }
- /**
- * Determines the width and height of the container in canvas coordinates.
- *
- * @param {HTMLElement} container - The viewer container.
- * @returns {Array<number>} 2D canvas coordinates.
- */
- containerToCanvas(container) {
- return [container.offsetWidth, container.offsetHeight];
- }
- /**
- * Determine basic distances from image to canvas corners.
- *
- * @description Transform origin and camera position needs to be the
- * equal for reliable return value.
- *
- * Determines the smallest basic distance for every side of the canvas.
- *
- * @param {Transform} transform - Transform of the image to unproject from.
- * @param {THREE.Camera} camera - Camera used in rendering.
- * @returns {Array<number>} Array of basic distances as [top, right, bottom, left].
- */
- getBasicDistances(transform, camera) {
- const topLeftBasic = this.viewportToBasic(-1, 1, transform, camera);
- const topRightBasic = this.viewportToBasic(1, 1, transform, camera);
- const bottomRightBasic = this.viewportToBasic(1, -1, transform, camera);
- const bottomLeftBasic = this.viewportToBasic(-1, -1, transform, camera);
- let topBasicDistance = 0;
- let rightBasicDistance = 0;
- let bottomBasicDistance = 0;
- let leftBasicDistance = 0;
- if (topLeftBasic[1] < 0 && topRightBasic[1] < 0) {
- topBasicDistance = topLeftBasic[1] > topRightBasic[1] ?
- -topLeftBasic[1] :
- -topRightBasic[1];
- }
- if (topRightBasic[0] > 1 && bottomRightBasic[0] > 1) {
- rightBasicDistance = topRightBasic[0] < bottomRightBasic[0] ?
- topRightBasic[0] - 1 :
- bottomRightBasic[0] - 1;
- }
- if (bottomRightBasic[1] > 1 && bottomLeftBasic[1] > 1) {
- bottomBasicDistance = bottomRightBasic[1] < bottomLeftBasic[1] ?
- bottomRightBasic[1] - 1 :
- bottomLeftBasic[1] - 1;
- }
- if (bottomLeftBasic[0] < 0 && topLeftBasic[0] < 0) {
- leftBasicDistance = bottomLeftBasic[0] > topLeftBasic[0] ?
- -bottomLeftBasic[0] :
- -topLeftBasic[0];
- }
- return [topBasicDistance, rightBasicDistance, bottomBasicDistance, leftBasicDistance];
- }
- /**
- * Determine pixel distances from image to canvas corners.
- *
- * @description Transform origin and camera position needs to be the
- * equal for reliable return value.
- *
- * Determines the smallest pixel distance for every side of the canvas.
- *
- * @param {HTMLElement} container - The viewer container.
- * @param {Transform} transform - Transform of the image to unproject from.
- * @param {THREE.Camera} camera - Camera used in rendering.
- * @returns {Array<number>} Array of pixel distances as [top, right, bottom, left].
- */
- getPixelDistances(container, transform, camera) {
- const topLeftBasic = this.viewportToBasic(-1, 1, transform, camera);
- const topRightBasic = this.viewportToBasic(1, 1, transform, camera);
- const bottomRightBasic = this.viewportToBasic(1, -1, transform, camera);
- const bottomLeftBasic = this.viewportToBasic(-1, -1, transform, camera);
- let topPixelDistance = 0;
- let rightPixelDistance = 0;
- let bottomPixelDistance = 0;
- let leftPixelDistance = 0;
- const [canvasWidth, canvasHeight] = this.containerToCanvas(container);
- if (topLeftBasic[1] < 0 && topRightBasic[1] < 0) {
- const basicX = topLeftBasic[1] > topRightBasic[1] ?
- topLeftBasic[0] :
- topRightBasic[0];
- const canvas = this.basicToCanvas(basicX, 0, container, transform, camera);
- topPixelDistance = canvas[1] > 0 ? canvas[1] : 0;