/** * modules in this bundle * @license * * smartphoto: * license: mit (http://opensource.org/licenses/mit) * author: appleple * homepage: http://developer.a-blogcms.jp * version: 0.5.9 * * a-template: * license: mit (http://opensource.org/licenses/mit) * author: steelydylan * maintainers: steelydylan * version: 0.2.0 * * delegate: * license: mit (http://opensource.org/licenses/mit) * maintainers: zenorocha * homepage: https://github.com/zenorocha/delegate#readme * version: 3.1.2 * * morphdom: * license: mit (http://opensource.org/licenses/mit) * author: patrick steele-idem * maintainers: mlrawlings , pnidem * homepage: https://github.com/patrick-steele-idem/morphdom#readme * version: 2.3.2 * * this header is generated by licensify (https://github.com/twada/licensify) */ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.smartphoto = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new error("cannot find module '"+o+"'");throw f.code="module_not_found",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o>> 0; var thisarg = arguments[1]; var value = void 0; for (var i = 0; i < length; i++) { value = list[i]; if (predicate.call(thisarg, value, i, list)) { return value; } } return undefined; }; } if (!element.prototype.matches) { element.prototype.matches = element.prototype.matchesselector || element.prototype.mozmatchesselector || element.prototype.msmatchesselector || element.prototype.omatchesselector || element.prototype.webkitmatchesselector || function (s) { var matches = (this.document || this.ownerdocument).queryselectorall(s), i = matches.length; while (--i >= 0 && matches.item(i) !== this) {} return i > -1; }; } var selector = function selector(_selector) { return document.queryselector(_selector); }; var getobjectbyid = function getobjectbyid(id) { for (var i = 0, n = objs.length; i < n; i++) { var obj = objs[i]; var templates = obj.templates; for (var t = 0, m = templates.length; t < m; t++) { if (templates[t] == id) { return obj; } } } return null; }; var findancestor = function findancestor(element, selector) { if (typeof element.closest === 'function') { return element.closest(selector) || null; } while (element) { if (element.matches(selector)) { return element; } element = element.parentelement; } return null; }; var on = function on(element, query, e, fn) { var events = e.split(' '); events.foreach(function (event) { delegate(element, query, event, fn); }); }; if (typeof document !== "undefined") { //data binding on(document, '[data-bind]', 'input change click', function (e) { var target = e.delegatetarget; var data = target.getattribute('data-bind'); var attr = target.getattribute('href'); var id = findancestor(target, '[data-id]').getattribute('data-id'); var value = target.value; if (attr) { value = value.replace('#', ''); } if (id) { var obj = getobjectbyid(id); if (target.getattribute('type') === 'radio') {} else if (target.getattribute('type') === 'checkbox') { (function () { var arr = []; var items = document.queryselectorall('[data-bind="' + data + '"]'); [].foreach.call(items, function (item) { if (item.checked) { arr.push(item.value); } }); })(); } else { obj.updatedatabystring(data, value); } } }); //action on(document, dataaction, eventtype, function (e) { var target = e.delegatetarget; if (e.type === "click" && target.tagname === 'select') { return; } if (e.type === "input" && target.getattribute("type") === "button") { return; } var events = eventtype.split(" "); var action = "action"; events.foreach(function (event) { if (target.getattribute("data-action-" + event)) { if (e.type === event) { action += "-" + event; } } }); var string = target.getattribute('data-' + action); if (!string) { return; } var method = string.replace(/\(.*?\);?/, ""); var parameter = string.replace(/(.*?)\((.*?)\);?/, "$2"); var pts = parameter.split(","); //引き数 var id = findancestor(target, '[data-id]').getattribute('data-id'); if (!id) { return; } var obj = getobjectbyid(id); obj.e = e; if (obj.method && obj.method[method]) { obj.method[method].apply(obj, pts); } else if (obj[method]) { obj[method].apply(obj, pts); } }); } var atemplate = function () { function atemplate(opt) { _classcallcheck(this, atemplate); this.atemplate = []; objs.push(this); for (var i in opt) { this[i] = opt[i]; } if (!this.data) { this.data = {}; } if (!this.templates) { this.templates = []; } var templates = this.templates; var length = templates.length; for (var _i = 0, n = length; _i < n; _i++) { var template = this.templates[_i]; var html = selector('#' + template).innerhtml; this.atemplate.push({ id: template, html: html }); } this.setid(); } _createclass(atemplate, [{ key: 'addtemplate', value: function addtemplate(id, html) { this.atemplate.push({ id: id, html: html }); this.templates.push(id); } }, { key: 'loadhtml', value: function loadhtml() { var templates = this.templates; var promises = []; templates.foreach(function (template) { var d = new $.deferred(); promises.push(d); var src = selector('#' + template).getattribute('src'); $.ajax({ url: src, type: 'get', datatype: 'text' }).success(function (data) { selector('#' + template).innerhtml = data; d.resolve(); }); }); return $.when.apply($, promises); } }, { key: 'getdata', value: function getdata() { return json.parse(json.stringify(this.data)); } }, { key: 'savedata', value: function savedata(key) { var data = json.stringify(this.data); localstorage.setitem(key, data); } }, { key: 'setdata', value: function setdata(val) { for (var i in val) { if (typeof val[i] !== "function") { this.data[i] = val[i]; } } } }, { key: 'loaddata', value: function loaddata(key) { var data = json.parse(localstorage.getitem(key)); if (data) { for (var i in data) { if (typeof data[i] !== "function") { this.data[i] = data[i]; } } } } }, { key: 'getrand', value: function getrand(a, b) { return ~~(math.random() * (b - a + 1)) + a; } }, { key: 'getrandtext', value: function getrandtext(limit) { var ret = ""; var strings = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789"; var length = strings.length; for (var i = 0; i < limit; i++) { ret += strings.charat(math.floor(this.getrand(0, length))); } return ret; } }, { key: 'setid', value: function setid() { var text = void 0; var ids = atemplate.ids; var flag = false; while (1) { text = this.getrandtext(10); for (var i = 0, n = atemplate.ids; i < n; i++) { if (atemplate.ids[i] === text) { flag = true; } } if (flag === false) { break; } } this.data.atemplate_id = text; } }, { key: 'getdatafromobj', value: function getdatafromobj(s, o) { s = s.replace(/\[([a-za-z0-9._-]+)\]/g, '.$1'); // convert indexes to properties s = s.replace(/^\./, ''); // strip leading dot var a = s.split('.'); while (a.length) { var n = a.shift(); if (n in o) { o = o[n]; } else { return; } } return o; } }, { key: 'getdatabystring', value: function getdatabystring(s) { var o = this.data; return this.getdatafromobj(s, o); } }, { key: 'updatedatabystring', value: function updatedatabystring(path, newvalue) { var object = this.data; var stack = path.split('.'); while (stack.length > 1) { object = object[stack.shift()]; } object[stack.shift()] = newvalue; } }, { key: 'removedatabystring', value: function removedatabystring(path) { var object = this.data; var stack = path.split('.'); while (stack.length > 1) { object = object[stack.shift()]; } var shift = stack.shift(); if (shift.match(/^\d+$/)) { object.splice(number(shift), 1); } else { delete object[shift]; } } }, { key: 'resolveblock', value: function resolveblock(html, item, i) { var that = this; var touchs = html.match(//g); var touchnots = html.match(//g); var exists = html.match(//g); var empties = html.match(//g); /*タッチブロック解決*/ if (touchs) { for (var k = 0, n = touchs.length; k < n; k++) { var start = touchs[k]; start = start.replace(/([a-za-z0-9._-]+):touch#([a-za-z0-9._-]+)/, "($1):touch#($2)"); var end = start.replace(/begin/, "end"); var reg = new regexp(start + "(([\\n\\r\\t]|.)*?)" + end, "g"); html = html.replace(reg, function (m, key2, val, next) { var itemkey = typeof item[key2] === "function" ? item[key2].apply(that) : that.getdatafromobj(key2, item); if (itemkey == val) { return next; } else { return ""; } }); } } /*タッチノットブロック解決*/ if (touchnots) { for (var _k = 0, _n = touchnots.length; _k < _n; _k++) { var _start = touchnots[_k]; _start = _start.replace(/([a-za-z0-9._-]+):touchnot#([a-za-z0-9._-]+)/, "($1):touchnot#($2)"); var _end = _start.replace(/begin/, "end"); var _reg = new regexp(_start + "(([\\n\\r\\t]|.)*?)" + _end, "g"); html = html.replace(_reg, function (m, key2, val, next) { var itemkey = typeof item[key2] === "function" ? item[key2].apply(that) : that.getdatafromobj(key2, item); if (itemkey != val) { return next; } else { return ""; } }); } } /*existブロックを解決*/ if (exists) { for (var _k2 = 0, _n2 = exists.length; _k2 < _n2; _k2++) { var _start2 = exists[_k2]; _start2 = _start2.replace(/([a-za-z0-9._-]+):exist/, "($1):exist"); var _end2 = _start2.replace(/begin/, "end"); var _reg2 = new regexp(_start2 + "(([\\n\\r\\t]|.)*?)" + _end2, "g"); html = html.replace(_reg2, function (m, key2, next) { var itemkey = typeof item[key2] === "function" ? item[key2].apply(that) : that.getdatafromobj(key2, item); if (itemkey || itemkey === 0) { return next; } else { return ""; } }); } } /*emptyブロックを解決*/ if (empties) { for (var _k3 = 0, _n3 = empties.length; _k3 < _n3; _k3++) { var _start3 = empties[_k3]; _start3 = _start3.replace(/([a-za-z0-9._-]+):empty/, "($1):empty"); var _end3 = _start3.replace(/begin/, "end"); var empty = new regexp(_start3 + "(([\\n\\r\\t]|.)*?)" + _end3, "g"); html = html.replace(empty, function (m, key2, next) { var itemkey = typeof item[key2] === "function" ? item[key2].apply(that) : that.getdatafromobj(key2, item); if (!itemkey && itemkey !== 0) { return next; } else { return ""; } }); } } /*変数解決*/ html = html.replace(/{([a-za-z0-9._-]+)}(\[([a-za-z0-9._-]+)\])*/g, function (n, key3, key4, converter) { var data = void 0; if (key3 == "i") { data = i; } else { if (item[key3] || item[key3] === 0) { if (typeof item[key3] === "function") { data = item[key3].apply(that); } else { data = item[key3]; } } else { if (converter && that.convert && that.convert[converter]) { return that.convert[converter].call(that, ""); } else { return ""; } } } if (converter && that.convert && that.convert[converter]) { return that.convert[converter].call(that, data); } else { return data; } }); return html; } /*絶対パス形式の変数を解決*/ }, { key: 'resolveabsblock', value: function resolveabsblock(html) { var that = this; html = html.replace(/{(.*?)}/g, function (n, key3) { var data = that.getdatabystring(key3); if (typeof data !== "undefined") { if (typeof data === "function") { return data.apply(that); } else { return data; } } else { return n; } }); return html; } }, { key: 'resolveinclude', value: function resolveinclude(html) { var include = //g; html = html.replace(include, function (m, key) { return selector('#' + key).innerhtml; }); return html; } }, { key: 'resolvewith', value: function resolvewith(html) { var width = /(([\n\r\t]|.)*?)/g; html = html.replace(width, function (m, key, val) { m = m.replace(/data\-bind=['"](.*?)['"]/g, "data-bind='" + key + ".$1'"); return m; }); return html; } }, { key: 'resolveloop', value: function resolveloop(html) { var loop = /(([\n\r\t]|.)*?)/g; var that = this; /*ループ文解決*/ html = html.replace(loop, function (m, key, val) { var keyitem = that.getdatabystring(key); var keys = []; if (typeof keyitem === "function") { keys = keyitem.apply(that); } else { keys = keyitem; } var ret = ""; if (keys instanceof array) { for (var i = 0, n = keys.length; i < n; i++) { ret += that.resolveblock(val, keys[i], i); } } /*エスケープ削除*/ ret = ret.replace(/\\([^\\])/g, "$1"); return ret; }); return html; } }, { key: 'removedata', value: function removedata(arr) { var data = this.data; for (var i in data) { for (var t = 0, n = arr.length; t < n; t++) { if (i === arr[t]) { delete data[i]; } } } return this; } }, { key: 'hasloop', value: function hasloop(txt) { var loop = /(([\n\r\t]|.)*?)/g; if (txt.match(loop)) { return true; } else { return false; } } }, { key: 'gethtml', value: function gethtml(selector, row) { var template = this.atemplate.find(function (item) { return item.id === selector; }); var html = ""; if (template && template.html) { html = template.html; } if (row) { html = selector; } if (!html) { return ""; } var data = this.data; /*インクルード解決*/ html = this.resolveinclude(html); /*with解決*/ html = this.resolvewith(html); /*ループ解決*/ while (this.hasloop(html)) { html = this.resolveloop(html); } /*変数解決*/ html = this.resolveblock(html, data); /*エスケープ削除*/ html = html.replace(/\\([^\\])/g, "$1"); /*絶対パスで指定された変数を解決*/ html = this.resolveabsblock(html); /*空行削除*/ return html.replace(/^([\t ])*\n/gm, ""); } }, { key: 'update', value: function update(txt, part) { var html = this.gethtml(); var templates = this.templates; var renderway = txt || "html"; if (this.beforeupdated) { this.beforeupdated(); } for (var i = 0, n = templates.length; i < n; i++) { var tem = templates[i]; var query = "#" + tem; var _html = this.gethtml(tem); var target = selector('[data-id=\'' + tem + '\']'); if (!part || part == tem) { if (!target) { selector(query).insertadjacenthtml('afterend', '
'); if (renderway === 'text') { selector('[data-id=\'' + tem + '\']').innertext = _html; } else { selector('[data-id=\'' + tem + '\']').innerhtml = _html; } } else { if (renderway === 'text') { target.innertext = _html; } else { morphdom(target, '
' + _html + '
'); } } if (part) { break; } } } this.updatebindingdata(part); if (this.onupdated) { this.onupdated(part); } return this; } }, { key: 'updatebindingdata', value: function updatebindingdata(part) { var _this = this; var templates = this.templates; for (var i = 0, n = templates.length; i < n; i++) { var temp = templates[i]; if (!part || part == temp) { var template = selector('[data-id=\'' + temp + '\']'); var binds = template.queryselectorall('[data-bind]'); [].foreach.call(binds, function (item) { var data = _this.getdatabystring(item.getattribute("data-bind")); if (item.getattribute("type") === "checkbox" || item.getattribute("type") === "radio") { if (data == item.value) { item.checked = true; } } else { item.value = data; } }); if (part) { break; } } } return this; } }, { key: 'applymethod', value: function applymethod(method) { var args = [].splice.call(arguments, 0); args.shift(); return this.method[method].apply(this, args); } }, { key: 'getcomputedprop', value: function getcomputedprop(prop) { return this.data[prop].apply(this); } }, { key: 'remove', value: function remove(path) { var object = this.data; var stack = path.split('.'); while (stack.length > 1) { object = object[stack.shift()]; } var shift = stack.shift(); if (shift.match(/^\d+$/)) { object.splice(number(shift), 1); } else { delete object[shift]; } return this; } }]); return atemplate; }(); module.exports = atemplate; },{"delegate":3,"morphdom":4}],2:[function(require,module,exports){ var document_node_type = 9; /** * a polyfill for element.matches() */ if (typeof element !== 'undefined' && !element.prototype.matches) { var proto = element.prototype; proto.matches = proto.matchesselector || proto.mozmatchesselector || proto.msmatchesselector || proto.omatchesselector || proto.webkitmatchesselector; } /** * finds the closest parent that matches a selector. * * @param {element} element * @param {string} selector * @return {function} */ function closest (element, selector) { while (element && element.nodetype !== document_node_type) { if (element.matches(selector)) return element; element = element.parentnode; } } module.exports = closest; },{}],3:[function(require,module,exports){ var closest = require('./closest'); /** * delegates event to a selector. * * @param {element} element * @param {string} selector * @param {string} type * @param {function} callback * @param {boolean} usecapture * @return {object} */ function delegate(element, selector, type, callback, usecapture) { var listenerfn = listener.apply(this, arguments); element.addeventlistener(type, listenerfn, usecapture); return { destroy: function() { element.removeeventlistener(type, listenerfn, usecapture); } } } /** * finds closest match and invokes callback. * * @param {element} element * @param {string} selector * @param {string} type * @param {function} callback * @return {function} */ function listener(element, selector, type, callback) { return function(e) { e.delegatetarget = closest(e.target, selector); if (e.delegatetarget) { callback.call(element, e); } } } module.exports = delegate; },{"./closest":2}],4:[function(require,module,exports){ 'use strict'; var range; // create a range object for efficently rendering strings to elements. var ns_xhtml = 'http://www.w3.org/1999/xhtml'; var doc = typeof document === 'undefined' ? undefined : document; var testel = doc ? doc.body || doc.createelement('div') : {}; // fixes // (ie7+ support) <=ie7 does not support el.hasattribute(name) var actualhasattributens; if (testel.hasattributens) { actualhasattributens = function(el, namespaceuri, name) { return el.hasattributens(namespaceuri, name); }; } else if (testel.hasattribute) { actualhasattributens = function(el, namespaceuri, name) { return el.hasattribute(name); }; } else { actualhasattributens = function(el, namespaceuri, name) { return el.getattributenode(namespaceuri, name) != null; }; } var hasattributens = actualhasattributens; function toelement(str) { if (!range && doc.createrange) { range = doc.createrange(); range.selectnode(doc.body); } var fragment; if (range && range.createcontextualfragment) { fragment = range.createcontextualfragment(str); } else { fragment = doc.createelement('body'); fragment.innerhtml = str; } return fragment.childnodes[0]; } /** * returns true if two node's names are the same. * * note: we don't bother checking `namespaceuri` because you will never find two html elements with the same * nodename and different namespace uris. * * @param {element} a * @param {element} b the target element * @return {boolean} */ function comparenodenames(fromel, toel) { var fromnodename = fromel.nodename; var tonodename = toel.nodename; if (fromnodename === tonodename) { return true; } if (toel.actualize && fromnodename.charcodeat(0) < 91 && /* from tag name is upper case */ tonodename.charcodeat(0) > 90 /* target tag name is lower case */) { // if the target element is a virtual dom node then we may need to normalize the tag name // before comparing. normal html elements that are in the "http://www.w3.org/1999/xhtml" // are converted to upper case return fromnodename === tonodename.touppercase(); } else { return false; } } /** * create an element, optionally with a known namespace uri. * * @param {string} name the element name, e.g. 'div' or 'svg' * @param {string} [namespaceuri] the element's namespace uri, i.e. the value of * its `xmlns` attribute or its inferred namespace. * * @return {element} */ function createelementns(name, namespaceuri) { return !namespaceuri || namespaceuri === ns_xhtml ? doc.createelement(name) : doc.createelementns(namespaceuri, name); } /** * copies the children of one dom element to another dom element */ function movechildren(fromel, toel) { var curchild = fromel.firstchild; while (curchild) { var nextchild = curchild.nextsibling; toel.appendchild(curchild); curchild = nextchild; } return toel; } function morphattrs(fromnode, tonode) { var attrs = tonode.attributes; var i; var attr; var attrname; var attrnamespaceuri; var attrvalue; var fromvalue; for (i = attrs.length - 1; i >= 0; --i) { attr = attrs[i]; attrname = attr.name; attrnamespaceuri = attr.namespaceuri; attrvalue = attr.value; if (attrnamespaceuri) { attrname = attr.localname || attrname; fromvalue = fromnode.getattributens(attrnamespaceuri, attrname); if (fromvalue !== attrvalue) { fromnode.setattributens(attrnamespaceuri, attrname, attrvalue); } } else { fromvalue = fromnode.getattribute(attrname); if (fromvalue !== attrvalue) { fromnode.setattribute(attrname, attrvalue); } } } // remove any extra attributes found on the original dom element that // weren't found on the target element. attrs = fromnode.attributes; for (i = attrs.length - 1; i >= 0; --i) { attr = attrs[i]; if (attr.specified !== false) { attrname = attr.name; attrnamespaceuri = attr.namespaceuri; if (attrnamespaceuri) { attrname = attr.localname || attrname; if (!hasattributens(tonode, attrnamespaceuri, attrname)) { fromnode.removeattributens(attrnamespaceuri, attrname); } } else { if (!hasattributens(tonode, null, attrname)) { fromnode.removeattribute(attrname); } } } } } function syncbooleanattrprop(fromel, toel, name) { if (fromel[name] !== toel[name]) { fromel[name] = toel[name]; if (fromel[name]) { fromel.setattribute(name, ''); } else { fromel.removeattribute(name, ''); } } } var specialelhandlers = { /** * needed for ie. apparently ie doesn't think that "selected" is an * attribute when reading over the attributes using selectel.attributes */ option: function(fromel, toel) { syncbooleanattrprop(fromel, toel, 'selected'); }, /** * the "value" attribute is special for the element since it sets * the initial value. changing the "value" attribute without changing the * "value" property will have no effect since it is only used to the set the * initial value. similar for the "checked" attribute, and "disabled". */ input: function(fromel, toel) { syncbooleanattrprop(fromel, toel, 'checked'); syncbooleanattrprop(fromel, toel, 'disabled'); if (fromel.value !== toel.value) { fromel.value = toel.value; } if (!hasattributens(toel, null, 'value')) { fromel.removeattribute('value'); } }, textarea: function(fromel, toel) { var newvalue = toel.value; if (fromel.value !== newvalue) { fromel.value = newvalue; } var firstchild = fromel.firstchild; if (firstchild) { // needed for ie. apparently ie sets the placeholder as the // node value and vise versa. this ignores an empty update. var oldvalue = firstchild.nodevalue; if (oldvalue == newvalue || (!newvalue && oldvalue == fromel.placeholder)) { return; } firstchild.nodevalue = newvalue; } }, select: function(fromel, toel) { if (!hasattributens(toel, null, 'multiple')) { var selectedindex = -1; var i = 0; var curchild = toel.firstchild; while(curchild) { var nodename = curchild.nodename; if (nodename && nodename.touppercase() === 'option') { if (hasattributens(curchild, null, 'selected')) { selectedindex = i; break; } i++; } curchild = curchild.nextsibling; } fromel.selectedindex = i; } } }; var element_node = 1; var text_node = 3; var comment_node = 8; function noop() {} function defaultgetnodekey(node) { return node.id; } function morphdomfactory(morphattrs) { return function morphdom(fromnode, tonode, options) { if (!options) { options = {}; } if (typeof tonode === 'string') { if (fromnode.nodename === '#document' || fromnode.nodename === 'html') { var tonodehtml = tonode; tonode = doc.createelement('html'); tonode.innerhtml = tonodehtml; } else { tonode = toelement(tonode); } } var getnodekey = options.getnodekey || defaultgetnodekey; var onbeforenodeadded = options.onbeforenodeadded || noop; var onnodeadded = options.onnodeadded || noop; var onbeforeelupdated = options.onbeforeelupdated || noop; var onelupdated = options.onelupdated || noop; var onbeforenodediscarded = options.onbeforenodediscarded || noop; var onnodediscarded = options.onnodediscarded || noop; var onbeforeelchildrenupdated = options.onbeforeelchildrenupdated || noop; var childrenonly = options.childrenonly === true; // this object is used as a lookup to quickly find all keyed elements in the original dom tree. var fromnodeslookup = {}; var keyedremovallist; function addkeyedremoval(key) { if (keyedremovallist) { keyedremovallist.push(key); } else { keyedremovallist = [key]; } } function walkdiscardedchildnodes(node, skipkeyednodes) { if (node.nodetype === element_node) { var curchild = node.firstchild; while (curchild) { var key = undefined; if (skipkeyednodes && (key = getnodekey(curchild))) { // if we are skipping keyed nodes then we add the key // to a list so that it can be handled at the very end. addkeyedremoval(key); } else { // only report the node as discarded if it is not keyed. we do this because // at the end we loop through all keyed elements that were unmatched // and then discard them in one final pass. onnodediscarded(curchild); if (curchild.firstchild) { walkdiscardedchildnodes(curchild, skipkeyednodes); } } curchild = curchild.nextsibling; } } } /** * removes a dom node out of the original dom * * @param {node} node the node to remove * @param {node} parentnode the nodes parent * @param {boolean} skipkeyednodes if true then elements with keys will be skipped and not discarded. * @return {undefined} */ function removenode(node, parentnode, skipkeyednodes) { if (onbeforenodediscarded(node) === false) { return; } if (parentnode) { parentnode.removechild(node); } onnodediscarded(node); walkdiscardedchildnodes(node, skipkeyednodes); } // // treewalker implementation is no faster, but keeping this around in case this changes in the future // function indextree(root) { // var treewalker = document.createtreewalker( // root, // nodefilter.show_element); // // var el; // while((el = treewalker.nextnode())) { // var key = getnodekey(el); // if (key) { // fromnodeslookup[key] = el; // } // } // } // // nodeiterator implementation is no faster, but keeping this around in case this changes in the future // // function indextree(node) { // var nodeiterator = document.createnodeiterator(node, nodefilter.show_element); // var el; // while((el = nodeiterator.nextnode())) { // var key = getnodekey(el); // if (key) { // fromnodeslookup[key] = el; // } // } // } function indextree(node) { if (node.nodetype === element_node) { var curchild = node.firstchild; while (curchild) { var key = getnodekey(curchild); if (key) { fromnodeslookup[key] = curchild; } // walk recursively indextree(curchild); curchild = curchild.nextsibling; } } } indextree(fromnode); function handlenodeadded(el) { onnodeadded(el); var curchild = el.firstchild; while (curchild) { var nextsibling = curchild.nextsibling; var key = getnodekey(curchild); if (key) { var unmatchedfromel = fromnodeslookup[key]; if (unmatchedfromel && comparenodenames(curchild, unmatchedfromel)) { curchild.parentnode.replacechild(unmatchedfromel, curchild); morphel(unmatchedfromel, curchild); } } handlenodeadded(curchild); curchild = nextsibling; } } function morphel(fromel, toel, childrenonly) { var toelkey = getnodekey(toel); var curfromnodekey; if (toelkey) { // if an element with an id is being morphed then it is will be in the final // dom so clear it out of the saved elements collection delete fromnodeslookup[toelkey]; } if (tonode.issamenode && tonode.issamenode(fromnode)) { return; } if (!childrenonly) { if (onbeforeelupdated(fromel, toel) === false) { return; } morphattrs(fromel, toel); onelupdated(fromel); if (onbeforeelchildrenupdated(fromel, toel) === false) { return; } } if (fromel.nodename !== 'textarea') { var curtonodechild = toel.firstchild; var curfromnodechild = fromel.firstchild; var curtonodekey; var fromnextsibling; var tonextsibling; var matchingfromel; outer: while (curtonodechild) { tonextsibling = curtonodechild.nextsibling; curtonodekey = getnodekey(curtonodechild); while (curfromnodechild) { fromnextsibling = curfromnodechild.nextsibling; if (curtonodechild.issamenode && curtonodechild.issamenode(curfromnodechild)) { curtonodechild = tonextsibling; curfromnodechild = fromnextsibling; continue outer; } curfromnodekey = getnodekey(curfromnodechild); var curfromnodetype = curfromnodechild.nodetype; var iscompatible = undefined; if (curfromnodetype === curtonodechild.nodetype) { if (curfromnodetype === element_node) { // both nodes being compared are element nodes if (curtonodekey) { // the target node has a key so we want to match it up with the correct element // in the original dom tree if (curtonodekey !== curfromnodekey) { // the current element in the original dom tree does not have a matching key so // let's check our lookup to see if there is a matching element in the original // dom tree if ((matchingfromel = fromnodeslookup[curtonodekey])) { if (curfromnodechild.nextsibling === matchingfromel) { // special case for single element removals. to avoid removing the original // dom node out of the tree (since that can break css transitions, etc.), // we will instead discard the current node and wait until the next // iteration to properly match up the keyed target element with its matching // element in the original tree iscompatible = false; } else { // we found a matching keyed element somewhere in the original dom tree. // let's moving the original dom node into the current position and morph // it. // note: we use insertbefore instead of replacechild because we want to go through // the `removenode()` function for the node that is being discarded so that // all lifecycle hooks are correctly invoked fromel.insertbefore(matchingfromel, curfromnodechild); fromnextsibling = curfromnodechild.nextsibling; if (curfromnodekey) { // since the node is keyed it might be matched up later so we defer // the actual removal to later addkeyedremoval(curfromnodekey); } else { // note: we skip nested keyed nodes from being removed since there is // still a chance they will be matched up later removenode(curfromnodechild, fromel, true /* skip keyed nodes */); } curfromnodechild = matchingfromel; } } else { // the nodes are not compatible since the "to" node has a key and there // is no matching keyed node in the source tree iscompatible = false; } } } else if (curfromnodekey) { // the original has a key iscompatible = false; } iscompatible = iscompatible !== false && comparenodenames(curfromnodechild, curtonodechild); if (iscompatible) { // we found compatible dom elements so transform // the current "from" node to match the current // target dom node. morphel(curfromnodechild, curtonodechild); } } else if (curfromnodetype === text_node || curfromnodetype == comment_node) { // both nodes being compared are text or comment nodes iscompatible = true; // simply update nodevalue on the original node to // change the text value curfromnodechild.nodevalue = curtonodechild.nodevalue; } } if (iscompatible) { // advance both the "to" child and the "from" child since we found a match curtonodechild = tonextsibling; curfromnodechild = fromnextsibling; continue outer; } // no compatible match so remove the old node from the dom and continue trying to find a // match in the original dom. however, we only do this if the from node is not keyed // since it is possible that a keyed node might match up with a node somewhere else in the // target tree and we don't want to discard it just yet since it still might find a // home in the final dom tree. after everything is done we will remove any keyed nodes // that didn't find a home if (curfromnodekey) { // since the node is keyed it might be matched up later so we defer // the actual removal to later addkeyedremoval(curfromnodekey); } else { // note: we skip nested keyed nodes from being removed since there is // still a chance they will be matched up later removenode(curfromnodechild, fromel, true /* skip keyed nodes */); } curfromnodechild = fromnextsibling; } // if we got this far then we did not find a candidate match for // our "to node" and we exhausted all of the children "from" // nodes. therefore, we will just append the current "to" node // to the end if (curtonodekey && (matchingfromel = fromnodeslookup[curtonodekey]) && comparenodenames(matchingfromel, curtonodechild)) { fromel.appendchild(matchingfromel); morphel(matchingfromel, curtonodechild); } else { var onbeforenodeaddedresult = onbeforenodeadded(curtonodechild); if (onbeforenodeaddedresult !== false) { if (onbeforenodeaddedresult) { curtonodechild = onbeforenodeaddedresult; } if (curtonodechild.actualize) { curtonodechild = curtonodechild.actualize(fromel.ownerdocument || doc); } fromel.appendchild(curtonodechild); handlenodeadded(curtonodechild); } } curtonodechild = tonextsibling; curfromnodechild = fromnextsibling; } // we have processed all of the "to nodes". if curfromnodechild is // non-null then we still have some from nodes left over that need // to be removed while (curfromnodechild) { fromnextsibling = curfromnodechild.nextsibling; if ((curfromnodekey = getnodekey(curfromnodechild))) { // since the node is keyed it might be matched up later so we defer // the actual removal to later addkeyedremoval(curfromnodekey); } else { // note: we skip nested keyed nodes from being removed since there is // still a chance they will be matched up later removenode(curfromnodechild, fromel, true /* skip keyed nodes */); } curfromnodechild = fromnextsibling; } } var specialelhandler = specialelhandlers[fromel.nodename]; if (specialelhandler) { specialelhandler(fromel, toel); } } // end: morphel(...) var morphednode = fromnode; var morphednodetype = morphednode.nodetype; var tonodetype = tonode.nodetype; if (!childrenonly) { // handle the case where we are given two dom nodes that are not // compatible (e.g.
--> or
--> text) if (morphednodetype === element_node) { if (tonodetype === element_node) { if (!comparenodenames(fromnode, tonode)) { onnodediscarded(fromnode); morphednode = movechildren(fromnode, createelementns(tonode.nodename, tonode.namespaceuri)); } } else { // going from an element node to a text node morphednode = tonode; } } else if (morphednodetype === text_node || morphednodetype === comment_node) { // text or comment node if (tonodetype === morphednodetype) { morphednode.nodevalue = tonode.nodevalue; return morphednode; } else { // text node to something else morphednode = tonode; } } } if (morphednode === tonode) { // the "to node" was not compatible with the "from node" so we had to // toss out the "from node" and use the "to node" onnodediscarded(fromnode); } else { morphel(morphednode, tonode, childrenonly); // we now need to loop over any keyed nodes that might need to be // removed. we only do the removal if we know that the keyed node // never found a match. when a keyed node is matched up we remove // it out of fromnodeslookup and we use fromnodeslookup to determine // if a keyed node has been matched up or not if (keyedremovallist) { for (var i=0, len=keyedremovallist.length; i
'); [].foreach.call(_this.elements, function (element) { _this.addnewitem(element); }); var currentitem = _this._getcurrentitembyhash(); if (currentitem) { util.triggerevent(currentitem.element, 'click'); } _this.update(); _this._geteachimagesize().then(function () { _this._fireevent('loadall'); }); setinterval(function () { _this._doanim(); }, _this.data.forceinterval); if (!_this.data.issmartphone) { window.addeventlistener('resize', function () { _this._resettranslate(); _this._setposbycurrentindex(); _this._setsizebyscreen(); _this.update(); }); window.addeventlistener('keydown', function (e) { var code = e.keycode || e.which; if (_this.data.hide === true) { return; } if (code === 37) { _this.gotoslide(_this.data.prev); } else if (code === 39) { _this.gotoslide(_this.data.next); } else if (code === 27) { _this.hidephoto(); } }); return _possibleconstructorreturn(_this); } window.addeventlistener('orientationchange', function () { _this._resettranslate(); _this._setposbycurrentindex(); _this._sethashbycurrentindex(); _this._setsizebyscreen(); _this.update(); }); if (!_this.data.useorientationapi) { return _possibleconstructorreturn(_this); } window.addeventlistener('deviceorientation', function (e) { var orientation = window.orientation; if (!e || !e.gamma || _this.data.appeareffect) { return; } if (!_this.isbeingzoomed && !_this.photoswipable && !_this.data.elastic && _this.data.scale) { if (orientation === 0) { _this._calcgravity(e.gamma, e.beta); } else if (orientation === 90) { _this._calcgravity(e.beta, e.gamma); } else if (orientation === -90) { _this._calcgravity(-e.beta, -e.gamma); } else if (orientation === 180) { _this._calcgravity(-e.gamma, -e.beta); } } }); return _this; } _createclass(smartphoto, [{ key: 'on', value: function on(event, fn) { var _this2 = this; var photo = this._getelementbyclass(this.data.classnames.smartphoto); photo.addeventlistener(event, function (e) { fn.call(_this2, e); }); } }, { key: 'increment', value: function increment(item) { return item + 1; } }, { key: 'virtualpos', value: function virtualpos(pos) { pos = parseint(pos, 10); var item = this._getselecteditem(); return pos / item.scale / this.data.scalesize; } }, { key: 'groupitems', value: function groupitems() { return this.data.group[this.data.currentgroup]; } }, { key: '_geteachimagesize', value: function _geteachimagesize() { var arr = []; var group = this.data.group; var loaditems = function loaditems(item) { var promise = new promise(function (resolve, reject) { var img = new image(); img.onload = function () { item.width = img.width; item.height = img.height; item.loaded = true; resolve(); }; img.onerror = function () { reject(); }; img.src = item.src; }); arr.push(promise); }; object.keys(group).foreach(function (key) { group[key].foreach(loaditems); }); return promise.all(arr); } }, { key: '_resettranslate', value: function _resettranslate() { var _this3 = this; var items = this.groupitems(); items.foreach(function (item, index) { item.translatex = _this3._getwindowwidth() * index; }); } }, { key: 'addnewitem', value: function addnewitem(element) { var _this4 = this; var groupid = element.getattribute('data-group') || 'nogroup'; var group = this.data.group; if (groupid === 'nogroup') { element.setattribute('data-group', 'nogroup'); } if (!group[groupid]) { group[groupid] = []; } var index = group[groupid].length; var item = { src: element.getattribute('href'), caption: element.getattribute('data-caption'), groupid: groupid, translatex: this._getwindowwidth() * index, index: index, translatey: 0, width: 50, height: 50, id: element.getattribute('data-id') || index, loaded: false, processed: false, element: element }; group[groupid].push(item); this.data.currentgroup = groupid; var id = element.getattribute('data-id'); if (!id) { element.setattribute('data-id', index); } element.setattribute('data-index', index); element.addeventlistener('click', function (event) { event.preventdefault(); _this4.data.currentgroup = element.getattribute('data-group'); _this4.data.currentindex = parseint(element.getattribute('data-index'), 10); _this4._sethashbycurrentindex(); var currentitem = _this4._getselecteditem(); if (currentitem.loaded) { _this4._initphoto(); _this4.addappeareffect(element); _this4.clicked = true; _this4.update(); _this4._fireevent('open'); } else { _this4._loaditem(currentitem).then(function () { _this4._initphoto(); _this4.addappeareffect(element); _this4.clicked = true; _this4.update(); _this4._fireevent('open'); }); } }); } }, { key: '_initphoto', value: function _initphoto() { this.data.total = this.groupitems().length; this.data.hide = false; this.data.photoposx = 0; this.data.photoposy = 0; this._setposbycurrentindex(); this._setsizebyscreen(); this.setarrow(); if (this.data.resizestyle === 'fill' && this.data.issmartphone) { this.data.scale = true; this.data.hideui = true; this.data.scalesize = this._getscaleboarder(); } } }, { key: 'onupdated', value: function onupdated() { var _this5 = this; if (this.data.appeareffect && this.data.appeareffect.once) { this.data.appeareffect.once = false; this.execeffect().then(function () { _this5.data.appeareffect = null; _this5.data.appear = true; _this5.update(); }); } if (this.clicked) { this.clicked = false; var classnames = this.data.classnames; var caption = this._getelementbyclass(classnames.smartphotocaption); caption.focus(); } } }, { key: 'execeffect', value: function execeffect() { var _this6 = this; return new promise(function (resolve) { var appeareffect = _this6.data.appeareffect; var classnames = _this6.data.classnames; var effect = _this6._getelementbyclass(classnames.smartphotoimgclone); var handler = function handler() { effect.removeeventlistener('transitionend', handler, true); resolve(); }; effect.addeventlistener('transitionend', handler, true); settimeout(function () { effect.style.transform = 'translate(' + appeareffect.afterx + 'px, ' + appeareffect.aftery + 'px) scale(' + appeareffect.scale + ')'; }, 10); }); } }, { key: 'addappeareffect', value: function addappeareffect(element) { var img = element.queryselector('img'); var pos = util.getviewpos(img); var appear = {}; var scale = 1; appear.width = img.offsetwidth; appear.height = img.offsetheight; appear.top = pos.top; appear.left = pos.left; appear.once = true; appear.img = img.getattribute('src'); var windowx = this._getwindowwidth(); var windowy = this._getwindowheight(); var screeny = windowy - this.data.headerheight - this.data.footerheight; if (this.data.resizestyle === 'fill' && this.data.issmartphone) { if (img.offsetwidth > img.offsetheight) { scale = windowy / img.offsetheight; } else { scale = windowx / img.offsetwidth; } } else { scale = screeny / img.offsetheight; if (scale * img.offsetwidth > windowx) { scale = windowx / img.offsetwidth; } } var x = (scale - 1) / 2 * img.offsetwidth + (windowx - img.offsetwidth * scale) / 2; var y = (scale - 1) / 2 * img.offsetheight + (windowy - img.offsetheight * scale) / 2; appear.afterx = x; appear.aftery = y; appear.scale = scale; this.data.appeareffect = appear; } }, { key: 'hidephoto', value: function hidephoto() { var _this7 = this; this.data.hide = true; this.data.appear = false; this.data.appeareffect = null; this.data.hideui = false; this.data.scale = false; this.data.scalesize = 1; var scrollx = window.scrollx; var scrolly = window.scrolly; if (location.hash) { this._sethash(''); } window.scroll(scrollx, scrolly); this._dohideeffect().then(function () { _this7.update(); _this7._fireevent('close'); }); } }, { key: '_dohideeffect', value: function _dohideeffect() { var _this8 = this; return new promise(function (resolve) { var classnames = _this8.data.classnames; var photo = _this8._getelementbyclass(classnames.smartphoto); var img = _this8._getelementbyquery('.current .' + classnames.smartphotoimg); var height = _this8._getwindowheight(); var handler = function handler() { photo.removeeventlistener('transitionend', handler, true); resolve(); }; photo.style.opacity = 0; img.style.transform = 'translatey(' + height + 'px)'; photo.addeventlistener('transitionend', handler, true); }); } }, { key: '_getelementbyclass', value: function _getelementbyclass(classname) { return document.queryselector('[data-id="' + this.id + '"] .' + classname); } }, { key: '_getelementbyquery', value: function _getelementbyquery(query) { return document.queryselector('[data-id="' + this.id + '"] ' + query); } }, { key: '_gettouchpos', value: function _gettouchpos() { var x = 0; var y = 0; var e = typeof event === 'undefined' ? this.e : event; if (this._istouched(e)) { x = e.touches[0].pagex; y = e.touches[0].pagey; } else if (e.pagex) { x = e.pagex; y = e.pagey; } return { x: x, y: y }; } }, { key: '_getgesturepos', value: function _getgesturepos(e) { var touches = e.touches; return [{ x: touches[0].pagex, y: touches[0].pagey }, { x: touches[1].pagex, y: touches[1].pagey }]; } }, { key: '_setposbycurrentindex', value: function _setposbycurrentindex() { var _this9 = this; var items = this.groupitems(); var movex = -1 * items[this.data.currentindex].translatex; this.pos.x = movex; settimeout(function () { _this9.data.translatex = movex; _this9.data.translatey = 0; _this9._listupdate(); }, 1); } }, { key: '_sethashbycurrentindex', value: function _sethashbycurrentindex() { var scrollx = window.scrollx; var scrolly = window.scrolly; var items = this.groupitems(); var id = items[this.data.currentindex].id; var group = this.data.currentgroup; var hash = 'group=' + group + '&photo=' + id; this._sethash(hash); window.scroll(scrollx, scrolly); } }, { key: '_sethash', value: function _sethash(hash) { if (!(window.history && window.history.pushstate)) { return; } if (hash) { window.history.replacestate(null, null, location.pathname + '#' + hash); } else { window.history.replacestate(null, null, '' + location.pathname); } } }, { key: '_getcurrentitembyhash', value: function _getcurrentitembyhash() { var group = this.data.group; var hash = location.hash.substr(1); var hashobj = util.parsequery(hash); var currentitem = null; var getcurrentitem = function getcurrentitem(item) { if (hashobj.group === item.groupid && hashobj.photo === item.id) { currentitem = item; } }; object.keys(group).foreach(function (key) { group[key].foreach(getcurrentitem); }); return currentitem; } }, { key: '_loaditem', value: function _loaditem(item) { return new promise(function (resolve) { var img = new image(); img.onload = function () { item.width = img.width; item.height = img.height; item.loaded = true; resolve(); }; img.onerror = function () { resolve(); }; img.src = item.src; }); } }, { key: '_setsizebyscreen', value: function _setsizebyscreen() { var windowx = this._getwindowwidth(); var windowy = this._getwindowheight(); var headerheight = this.data.headerheight; var footerheight = this.data.footerheight; var screeny = windowy - (headerheight + footerheight); var items = this.groupitems(); items.foreach(function (item) { if (!item.loaded) { return; } item.processed = true; item.scale = screeny / item.height; item.x = (item.scale - 1) / 2 * item.width + (windowx - item.width * item.scale) / 2; item.y = (item.scale - 1) / 2 * item.height + (windowy - item.height * item.scale) / 2; if (item.width * item.scale > windowx) { item.scale = windowx / item.width; item.x = (item.scale - 1) / 2 * item.width; } }); } }, { key: '_slidelist', value: function _slidelist() { var _this10 = this; this.data.scalesize = 1; this.isbeingzoomed = false; this.data.hideui = false; this.data.scale = false; this.data.photoposx = 0; this.data.photoposy = 0; this.data.onmoveclass = true; this._setposbycurrentindex(); this._sethashbycurrentindex(); this._setsizebyscreen(); settimeout(function () { _this10.data.onmoveclass = false; _this10.setarrow(); _this10.update(); if (_this10.data.oldindex !== _this10.data.currentindex) { _this10._fireevent('change'); } _this10.data.oldindex = _this10.data.currentindex; }, 200); } }, { key: 'gotoslide', value: function gotoslide(index) { if (this.e && this.e.preventdefault) { this.e.preventdefault(); } this.data.currentindex = parseint(index, 10); if (!this.data.currentindex) { this.data.currentindex = 0; } this._slidelist(); } }, { key: 'setarrow', value: function setarrow() { var items = this.groupitems(); var length = items.length; var next = this.data.currentindex + 1; var prev = this.data.currentindex - 1; this.data.shownextarrow = false; this.data.showprevarrow = false; if (next !== length) { this.data.next = next; this.data.shownextarrow = true; } if (prev !== -1) { this.data.prev = prev; this.data.showprevarrow = true; } } }, { key: 'beforedrag', value: function beforedrag() { if (this._isgestured(this.e)) { this.beforegesture(); return; } this.isbeingzoomed = false; if (this.data.scale) { this.beforephotodrag(); return; } var pos = this._gettouchpos(); this.isswipable = true; this.dragstart = true; this.firstpos = pos; this.oldpos = pos; } }, { key: 'afterdrag', value: function afterdrag() { var items = this.groupitems(); var date = new date(); var tapsecond = date.gettime(); var offset = this.tapsecond - tapsecond; var swipewidth = 0; var swipeheight = 0; this.isswipable = false; this.onlistmove = false; if (this.oldpos) { swipewidth = this.oldpos.x - this.firstpos.x; swipeheight = this.oldpos.y - this.firstpos.y; } if (this.isbeingzoomed) { this.aftergesture(); return; } if (this.data.scale) { this.afterphotodrag(); return; } else if (!util.issmartphone() && swipewidth === 0 && swipeheight === 0) { this.zoomphoto(); return; } if (math.abs(offset) <= 500 && swipewidth === 0 && swipeheight === 0) { this.e.preventdefault(); this.zoomphoto(); return; } this.tapsecond = tapsecond; this._fireevent('swipeend'); if (this.movedir === 'horizontal') { if (swipewidth >= this.data.swipeoffset && this.data.currentindex !== 0) { this.data.currentindex -= 1; } else if (swipewidth <= -this.data.swipeoffset && this.data.currentindex !== items.length - 1) { this.data.currentindex += 1; } this._slidelist(); } if (this.movedir === 'vertical') { if (swipeheight >= this.data.swipeoffset) { this.hidephoto(); } else { this.data.translatey = 0; this._slidelist(); } } } }, { key: 'ondrag', value: function ondrag() { this.e.preventdefault(); if (this._isgestured(this.e) && this.onlistmove === false) { this.ongesture(); return; } if (this.isbeingzoomed) { return; } if (this.data.scale) { this.onphotodrag(); return; } if (!this.isswipable) { return; } var pos = this._gettouchpos(); var x = pos.x - this.oldpos.x; var y = pos.y - this.firstpos.y; if (this.dragstart) { this._fireevent('swipestart'); this.dragstart = false; if (math.abs(x) > math.abs(y)) { this.movedir = 'horizontal'; } else { this.movedir = 'vertical'; } } if (this.movedir === 'horizontal') { this.pos.x += x; this.data.translatex = this.pos.x; } else { this.data.translatey = y; } this.onlistmove = true; this.oldpos = pos; this._listupdate(); } }, { key: 'zoomphoto', value: function zoomphoto() { var _this11 = this; this.data.hideui = true; this.data.scalesize = this._getscaleboarder(); this.data.photoposx = 0; this.data.photoposy = 0; this._photoupdate(); settimeout(function () { _this11.data.scale = true; _this11._photoupdate(); _this11._fireevent('zoomin'); }, 300); } }, { key: 'zoomoutphoto', value: function zoomoutphoto() { this.data.scalesize = 1; this.isbeingzoomed = false; this.data.hideui = false; this.data.scale = false; this.data.photoposx = 0; this.data.photoposy = 0; this._photoupdate(); this._fireevent('zoomout'); } }, { key: 'beforephotodrag', value: function beforephotodrag() { var pos = this._gettouchpos(); this.photoswipable = true; if (!this.data.photoposx) { this.data.photoposx = 0; } if (!this.data.photoposy) { this.data.photoposy = 0; } this.oldphotopos = pos; this.firstphotopos = pos; } }, { key: 'onphotodrag', value: function onphotodrag() { if (!this.photoswipable) { return; } this.e.preventdefault(); var pos = this._gettouchpos(); var x = pos.x - this.oldphotopos.x; var y = pos.y - this.oldphotopos.y; var movex = this._round(this.data.scalesize * x, 6); var movey = this._round(this.data.scalesize * y, 6); if (typeof movex === 'number') { this.data.photoposx += movex; this.photovx = movex; } if (typeof movey === 'number') { this.data.photoposy += movey; this.photovy = movey; } this.oldphotopos = pos; this._photoupdate(); } }, { key: 'afterphotodrag', value: function afterphotodrag() { if (this.oldphotopos.x === this.firstphotopos.x && this.photoswipable) { this.photoswipable = false; this.zoomoutphoto(); } else { this.photoswipable = false; var item = this._getselecteditem(); var bound = this._makebound(item); var offset = this.data.swipeoffset * this.data.scalesize; var flagx = 0; var flagy = 0; if (this.data.photoposx > bound.maxx) { flagx = -1; } else if (this.data.photoposx < bound.minx) { flagx = 1; } if (this.data.photoposy > bound.maxy) { flagy = -1; } else if (this.data.photoposy < bound.miny) { flagy = 1; } if (this.data.photoposx - bound.maxx > offset && this.data.currentindex !== 0) { this.gotoslide(this.data.prev); return; } if (bound.minx - this.data.photoposx > offset && this.data.currentindex + 1 !== this.data.total) { this.gotoslide(this.data.next); return; } // todo // if(this.data.photoposy - bound.maxy > offset) { // this.hidephoto(); // return; // } if (flagx === 0 && flagy === 0) { this.vx = this.photovx / 5; this.vy = this.photovy / 5; } else { this._registerelasticforce(flagx, flagy); } } } }, { key: 'beforegesture', value: function beforegesture() { this._fireevent('gesturestart'); var pos = this._getgesturepos(this.e); var distance = this._getdistance(pos[0], pos[1]); this.isbeingzoomed = true; this.olddistance = distance; this.data.scale = true; this.e.preventdefault(); } }, { key: 'ongesture', value: function ongesture() { var pos = this._getgesturepos(this.e); var distance = this._getdistance(pos[0], pos[1]); var size = (distance - this.olddistance) / 100; var oldscalesize = this.data.scalesize; var posx = this.data.photoposx; var posy = this.data.photoposy; this.isbeingzoomed = true; this.data.scalesize += this._round(size, 6); if (this.data.scalesize < 0.2) { this.data.scalesize = 0.2; } // todo if (this.data.scalesize < oldscalesize) { this.data.photoposx = (1 + this.data.scalesize - oldscalesize) * posx; this.data.photoposy = (1 + this.data.scalesize - oldscalesize) * posy; } if (this.data.scalesize < 1 || this.data.scalesize > this._getscaleboarder()) { this.data.hideui = true; } else { this.data.hideui = false; } this.olddistance = distance; this.e.preventdefault(); this._photoupdate(); } }, { key: 'aftergesture', value: function aftergesture() { if (this.data.scalesize > this._getscaleboarder()) { return; } this.data.photoposx = 0; this.data.photoposy = 0; this.data.scale = false; this.data.scalesize = 1; this.data.hideui = false; this._fireevent('gestureend'); this._photoupdate(); } }, { key: '_getforceandtheta', value: function _getforceandtheta(vx, vy) { return { force: math.sqrt(vx * vx + vy * vy), theta: math.atan2(vy, vx) }; } }, { key: '_getscaleboarder', value: function _getscaleboarder() { var item = this._getselecteditem(); var windowwidth = this._getwindowwidth(); var windowheight = this._getwindowheight(); if (!util.issmartphone()) { return 1 / item.scale; } if (item.width > item.height) { return windowheight / (item.height * item.scale); } return windowwidth / (item.width * item.scale); } }, { key: '_makebound', value: function _makebound(item) { var width = item.width * item.scale * this.data.scalesize; var height = item.height * item.scale * this.data.scalesize; var minx = void 0; var miny = void 0; var maxx = void 0; var maxy = void 0; var windowwidth = this._getwindowwidth(); var windowheight = this._getwindowheight(); if (windowwidth > width) { maxx = (windowwidth - width) / 2; minx = -1 * maxx; } else { maxx = (width - windowwidth) / 2; minx = -1 * maxx; } if (windowheight > height) { maxy = (windowheight - height) / 2; miny = -1 * maxy; } else { maxy = (height - windowheight) / 2; miny = -1 * maxy; } return { minx: this._round(minx, 6) * this.data.scalesize, miny: this._round(miny, 6) * this.data.scalesize, maxx: this._round(maxx, 6) * this.data.scalesize, maxy: this._round(maxy, 6) * this.data.scalesize }; } }, { key: '_registerelasticforce', value: function _registerelasticforce(x, y) { var _this12 = this; var item = this._getselecteditem(); var bound = this._makebound(item); this.data.elastic = true; if (x === 1) { this.data.photoposx = bound.minx; } else if (x === -1) { this.data.photoposx = bound.maxx; } if (y === 1) { this.data.photoposy = bound.miny; } else if (y === -1) { this.data.photoposy = bound.maxy; } this._photoupdate(); settimeout(function () { _this12.data.elastic = false; _this12._photoupdate(); }, 300); } }, { key: '_getselecteditem', value: function _getselecteditem() { var data = this.data; var index = data.currentindex; return data.group[data.currentgroup][index]; } }, { key: '_getuniqid', value: function _getuniqid() { return (date.now().tostring(36) + math.random().tostring(36).substr(2, 5)).touppercase(); } }, { key: '_getdistance', value: function _getdistance(point1, point2) { var x = point1.x - point2.x; var y = point1.y - point2.y; return math.sqrt(x * x + y * y); } }, { key: '_round', value: function _round(val, precision) { var digit = math.pow(10, precision); val *= digit; val = math.round(val); val /= digit; return val; } }, { key: '_istouched', value: function _istouched(e) { if (e && e.touches) { return true; } return false; } }, { key: '_isgestured', value: function _isgestured(e) { if (e && e.touches && e.touches.length > 1) { return true; } return false; } }, { key: '_issmartphone', value: function _issmartphone() { var agent = navigator.useragent; if (agent.indexof('iphone') > 0 || agent.indexof('ipad') > 0 || agent.indexof('ipod') > 0 || agent.indexof('android') > 0) { return true; } return false; } }, { key: '_calcgravity', value: function _calcgravity(gamma, beta) { if (gamma > 5 || gamma < -5) { this.vx += gamma * 0.05; } if (this.data.verticalgravity === false) { return; } if (beta > 5 || beta < -5) { this.vy += beta * 0.05; } } }, { key: '_photoupdate', value: function _photoupdate() { var classnames = this.data.classnames; var current = this._getelementbyquery('.current'); var img = current.queryselector('.' + classnames.smartphotoimg); var nav = this._getelementbyquery('.' + classnames.smartphotonav); var arrows = this._getelementbyquery('.' + classnames.smartphotoarrows); var photoposx = this.virtualpos(this.data.photoposx); var photoposy = this.virtualpos(this.data.photoposy); var scalesize = this.data.scalesize; var transform = 'translate(' + photoposx + 'px,' + photoposy + 'px) scale(' + scalesize + ')'; img.style.transform = transform; if (this.data.scale) { util.addclass(img, classnames.smartphotoimgonmove); } else { util.removeclass(img, classnames.smartphotoimgonmove); } if (this.data.elastic) { util.addclass(img, classnames.smartphotoimgelasticmove); } else { util.removeclass(img, classnames.smartphotoimgelasticmove); } if (this.data.hideui) { if (nav) { nav.setattribute('aria-hidden', 'true'); } if (arrows) { arrows.setattribute('aria-hidden', 'true'); } } else { if (nav) { nav.setattribute('aria-hidden', 'false'); } if (arrows) { arrows.setattribute('aria-hidden', 'false'); } } } }, { key: '_getwindowwidth', value: function _getwindowwidth() { return document.documentelement.clientwidth; } }, { key: '_getwindowheight', value: function _getwindowheight() { return window.innerheight; } }, { key: '_listupdate', value: function _listupdate() { var classnames = this.data.classnames; var list = this._getelementbyquery('.' + classnames.smartphotolist); var transform = 'translate(' + this.data.translatex + 'px,' + this.data.translatey + 'px)'; list.style.transform = transform; // $list if (this.data.onmoveclass) { util.addclass(list, classnames.smartphotolistonmove); } else { util.removeclass(list, classnames.smartphotolistonmove); } } }, { key: '_fireevent', value: function _fireevent(eventname) { var photo = this._getelementbyclass(this.data.classnames.smartphoto); util.triggerevent(photo, eventname); } }, { key: '_doanim', value: function _doanim() { if (this.isbeingzoomed || this.isswipable || this.photoswipable || this.data.elastic || !this.data.scale) { return; } this.data.photoposx += this.vx; this.data.photoposy += this.vy; var item = this._getselecteditem(); var bound = this._makebound(item); if (this.data.photoposx < bound.minx) { this.data.photoposx = bound.minx; this.vx *= -0.2; } else if (this.data.photoposx > bound.maxx) { this.data.photoposx = bound.maxx; this.vx *= -0.2; } if (this.data.photoposy < bound.miny) { this.data.photoposy = bound.miny; this.vy *= -0.2; } else if (this.data.photoposy > bound.maxy) { this.data.photoposy = bound.maxy; this.vy *= -0.2; } var power = this._getforceandtheta(this.vx, this.vy); var force = power.force; var theta = power.theta; force -= this.data.registance; if (math.abs(force) < 0.5) { return; } this.vx = math.cos(theta) * force; this.vy = math.sin(theta) * force; this._photoupdate(); } }]); return smartphoto; }(_atemplate3.default); module.exports = smartphoto; },{"../lib/util":7,"a-template":1}],6:[function(require,module,exports){ 'use strict'; module.exports = require('./core/'); },{"./core/":5}],7:[function(require,module,exports){ 'use strict'; var _typeof = typeof symbol === "function" && typeof symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof symbol === "function" && obj.constructor === symbol && obj !== symbol.prototype ? "symbol" : typeof obj; }; module.exports.issmartphone = function () { var agent = navigator.useragent; if (agent.indexof('iphone') > 0 || agent.indexof('ipad') > 0 || agent.indexof('ipod') > 0 || agent.indexof('android') > 0) { return true; } else { return false; } }; function deepextend(out) { out = out || {}; for (var i = 1; i < arguments.length; i++) { var obj = arguments[i]; if (!obj) { continue; } for (var key in obj) { if (obj.hasownproperty(key)) { if (_typeof(obj[key]) === 'object') out[key] = deepextend(out[key], obj[key]);else out[key] = obj[key]; } } } return out; }; module.exports.extend = deepextend; module.exports.triggerevent = function (el, eventname, options) { var event = void 0; if (window.customevent) { event = new customevent(eventname, { cancelable: true }); } else { event = document.createevent('customevent'); event.initcustomevent(eventname, false, false, options); } el.dispatchevent(event); }; module.exports.parsequery = function (query) { var s = query.split('&'), data = {}, i = 0, iz = s.length, param, key, value; for (; i < iz; i++) { param = s[i].split('='); if (param[0] !== void 0) { key = param[0]; value = param[1] !== void 0 ? param.slice(1).join('=') : key; data[key] = decodeuricomponent(value); } } return data; }; module.exports.getviewpos = function (element) { return { left: element.getboundingclientrect().left, top: element.getboundingclientrect().top }; }; module.exports.removeelement = function (element) { if (element && element.parentnode) { element.parentnode.removechild(element); } }; module.exports.append = function (element, string) { var parser = new domparser(); var doc = parser.parsefromstring(string, 'text/html'); element.appendchild(doc.queryselector('body').childnodes[0]); }; module.exports.addclass = function (element, classname) { if (element.classlist) { element.classlist.add(classname); } else { element.classname += ' ' + classname; } }; module.exports.removeclass = function (element, classname) { if (element.classlist) { element.classlist.remove(classname); } else { element.classname = element.classname.replace(new regexp('(^|\\b)' + classname.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); } }; },{}]},{},[6])(6) });