Last active
March 28, 2017 07:11
-
-
Save dentmaged/550c10d1f6b9b983400ed65c16bd65e1 to your computer and use it in GitHub Desktop.
Vertigo - a Javascript library that allows for rapid web development.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| jQuery.fn.outerHTML = function(s) { | |
| return s ? this.before(s).remove() : jQuery("<p>").append(this.eq(0).clone()).html(); | |
| }; | |
| jQuery.fn.extend({ | |
| getPath: function () { | |
| var path, node = this; | |
| while (node.length) { | |
| var realNode = node[0], name = realNode.localName; | |
| if (!name) break; | |
| name = name.toLowerCase(); | |
| var parent = node.parent(); | |
| var sameTagSiblings = parent.children(name); | |
| if (sameTagSiblings.length > 1) { | |
| allSiblings = parent.children(); | |
| var index = allSiblings.index(realNode) + 1; | |
| if (index > 1) { | |
| name += ':nth-child(' + index + ')'; | |
| } | |
| } | |
| path = name + (path ? '>' + path : ''); | |
| node = parent; | |
| } | |
| return path; | |
| } | |
| }); | |
| String.prototype.replaceAll = function(search, replacement) { | |
| var target = this; | |
| return target.replace(new RegExp(search, 'g'), replacement); | |
| }; | |
| function nano(template, data) { | |
| return template.replace(/\{\{([^\}]*)\}\}/g, function(str, key) { | |
| var keys = key.split('.'), val = data, k; | |
| while (key = keys.shift()) { | |
| key = key.split('['); | |
| val = val[key.shift()]; | |
| while (k = key.shift()) { | |
| val = val[k.slice(0, -1)]; | |
| } | |
| } | |
| return ("undefined" !== typeof val && val !== null) ? val : ""; | |
| }); | |
| } | |
| function getFromObject(obj, prop) { | |
| if (typeof obj === 'undefined') { | |
| return false; | |
| } | |
| var _index = prop.indexOf('.'); | |
| var _indexBracket = prop.indexOf('['); | |
| if (_indexBracket > -1 && _index == -1) { | |
| return obj[prop.substring(0, _indexBracket)][prop.substring(_indexBracket + 1, prop.length - 1)]; | |
| } else if (_indexBracket > -1 && _index > -1) { | |
| return getFromObject(obj[prop.substring(0, _indexBracket)][prop.substring(_indexBracket + 1, _index - 1)], prop.substring(_index + 1)); | |
| } | |
| if (_index > -1) { | |
| return getFromObject(obj[prop.substring(0, _index)], prop.substr(_index + 1)); | |
| } | |
| return obj[prop]; | |
| } | |
| function setFromObject(obj, prop, val) { | |
| if (typeof obj === 'undefined') { | |
| return false; | |
| } | |
| var _index = prop.indexOf('.'); | |
| var _indexBracket = prop.indexOf('['); | |
| if (_indexBracket > -1 && _index == -1) { | |
| obj[prop.substring(0, _indexBracket)][prop.substring(_indexBracket + 1, prop.length - 1)] = val; | |
| return; | |
| } else if (_indexBracket > -1 && _index > -1) { | |
| setFromObject(obj[prop.substring(0, _indexBracket)][prop.substring(_indexBracket + 1, _index - 1)], prop.substring(_index + 1), val); | |
| return; | |
| } | |
| if (_index > -1) { | |
| setFromObject(obj[prop.substring(0, _index)], prop.substr(_index + 1), val); | |
| } | |
| obj[prop] = val; | |
| } | |
| function Vertigo(options) { | |
| this.el = $(options.el) || $('#app'); | |
| this.originalHtml = "<html>" + $("html").html() + "</html>"; | |
| this.$vrbinds = {}; | |
| this.$textReplacements = {}; | |
| this.$listeners = {}; | |
| this.$data = options.data; | |
| this.$methods = options.methods; | |
| var self = this; | |
| this.completeDocument = function() { | |
| self.el.find("*").each(function(index) { | |
| var $this = $(this); | |
| $.each(this.attributes, function() { | |
| if (this.specified) { | |
| var attributeSelf = this; | |
| var directiveName = this.name.toLowerCase().replace('vr-', ''); | |
| var this_path = $this.getPath(); | |
| if (typeof Vertigo.directives[directiveName] != 'undefined') { | |
| Vertigo.directiveStore[directiveName][this_path] = { html: $this.html(), name: attributeSelf.name, value: attributeSelf.value, elementTag: $this.outerHTML().replace($this.html(), ''), outerHTML: $this.outerHTML(), before: $this.prevAll().length }; | |
| Vertigo.directiveStore[directiveName][this_path].action = Vertigo.directives[directiveName](self, $this, this.value, self.$data); | |
| } | |
| if (this.name.toLowerCase().startsWith("vr-bind:")) { | |
| self.$vrbinds[this_path] = { name: attributeSelf.name, value: attributeSelf.value }; | |
| $this.attr(this.name.split(":")[1], getFromObject(self.$data, this.value)); | |
| $this.removeAttr(this.name); | |
| } | |
| if (this.name.toLowerCase().startsWith("vr-on:")) { | |
| if (typeof self.$listeners[this_path] == 'undefined') { | |
| self.$listeners[this_path] = []; | |
| } | |
| self.$listeners[this_path].push(this.name.split(":")[1]); | |
| var oneself = this; | |
| $this.on(this.name.split(":")[1], function(event) { | |
| with (self.$methods) { | |
| if (!eval(oneself.value)) { | |
| event.preventDefault(); | |
| } | |
| } | |
| }); | |
| } | |
| } | |
| }); | |
| var shouldIgnore = false; | |
| for (var i in Vertigo.ignoreByTextReplacement) { | |
| var ignore = Vertigo.ignoreByTextReplacement[i]; | |
| if (typeof $this.attr('vr-' + ignore) != 'undefined' || typeof $this.parent().attr('vr-' + ignore) != 'undefined') { | |
| shouldIgnore = true; | |
| } | |
| } | |
| if (!shouldIgnore) { | |
| var originalPageHtml = $this.html(); | |
| $this.html(nano($this.html(), self.$data)); | |
| self.$textReplacements[$this.getPath()] = { original: originalPageHtml, now: $this.html() }; | |
| } | |
| }); | |
| } | |
| this.set = function(prop, value) { | |
| setFromObject(self.$data, prop, value); | |
| self.reset(); | |
| } | |
| this.get = function(prop) { | |
| return getFromObject(self.$data, prop); | |
| } | |
| this.reset = function() { | |
| for (var addition in Vertigo.additions) { | |
| var xpath = Vertigo.additions[addition]; | |
| if (xpath.endsWith(")")) { | |
| var tmpX = xpath.substring(0, xpath.length - 1).split("("); | |
| xpath = tmpX[0] + "(" + (parseInt(tmpX[1] - 1) - (addition)) + ")"; | |
| } | |
| $(xpath).remove(); | |
| } | |
| for (var path in self.$listeners) { | |
| for (var listener in self.$listeners[path]) { | |
| $(path).off(self.$listeners[path][listener]); | |
| } | |
| } | |
| for (var directive in Vertigo.directiveStore) { | |
| for (var _path in Vertigo.directiveStore[directive]) { | |
| var path = Vertigo.directiveStore[directive][_path]; | |
| if (path.action == 'remove') { | |
| var tmpY = _path.split(">"); | |
| tmpY.pop(); | |
| $(tmpY.join(">") + ">*:nth-child(" + path.before + ")").after(path.outerHTML); | |
| } else if (path.action.startsWith("listener")) { | |
| var arr = path.action.split(" "); | |
| if (arr.length == 1) { | |
| console.warn(directive + " has an invalid action."); | |
| return; | |
| } | |
| for (var i = 1; i < arr.length; i++) { | |
| $(_path).off(arr[i].replaceAll('_', ' ')); | |
| } | |
| } else { | |
| $(_path).outerHTML(path.outerHTML); | |
| } | |
| } | |
| } | |
| for (var _path in self.$vrbinds) { | |
| var path = self.$vrbinds[_path]; | |
| var replaced = path.name.split(":")[1]; | |
| $(_path).removeAttr(replaced); | |
| $(_path).attr(path.name, path.value); | |
| } | |
| for (var _path in self.$textReplacements) { | |
| var path = self.$textReplacements[_path]; | |
| $(_path).html(path.original); | |
| } | |
| Vertigo.additions = []; | |
| self.$vrbinds = {}; | |
| self.$textReplacements = {}; | |
| self.$listeners = {}; | |
| self.completeDocument(); | |
| } | |
| this.completeDocument(); | |
| } | |
| Vertigo.directives = {}; | |
| Vertigo.directiveStore = {}; | |
| Vertigo.ignoreByTextReplacement = []; | |
| Vertigo.additions = []; | |
| Vertigo.registerDirective = function(name, callback, ignoreByTextReplacement) { | |
| Vertigo.directives[name.toLowerCase()] = callback; | |
| Vertigo.directiveStore[name] = {}; | |
| if (ignoreByTextReplacement) { | |
| Vertigo.ignoreByTextReplacement.push(name); | |
| } | |
| }; | |
| Vertigo.registerDirective('if', function(app, element, value, data) { | |
| with (data) { | |
| if (!eval(value)) { | |
| element.remove(); | |
| return 'remove'; | |
| } | |
| } | |
| return 'keep'; | |
| }, false); | |
| Vertigo.registerDirective('for', function(app, element, value, data) { | |
| var name = value.split("in")[0].trim(); | |
| var list = value.split("in")[1].trim(); | |
| var arr = getFromObject(data, list); | |
| var originalHtml = element.outerHTML(), html; | |
| for (var i = 0; i < arr.length; i++) { | |
| html = originalHtml.replaceAll(name, list + '[' + i + ']'); | |
| html = nano(html, data); | |
| var inserted = element.before(html); | |
| Vertigo.additions.push(inserted.getPath()); | |
| } | |
| element.remove(); | |
| return 'remove'; | |
| }, true); | |
| Vertigo.registerDirective('model', function(app, element, value, data) { | |
| if (element.is('input')) { | |
| var contents; | |
| element.val(contents = app.get(value)); | |
| element.on('keyup', function(event) { | |
| if (contents != element.val()) { | |
| contents = element.val(); | |
| app.set(value, element.val()); | |
| } | |
| }); | |
| } | |
| return 'listener keyup'; | |
| }, false); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function nano(e,t){return e.replace(/\{\{([^\}]*)\}\}/g,function(e,i){for(var r,n=i.split("."),s=t;i=n.shift();)for(i=i.split("["),s=s[i.shift()];r=i.shift();)s=s[r.slice(0,-1)];return"undefined"!=typeof s&&null!==s?s:""})}function getFromObject(e,t){if("undefined"==typeof e)return!1;var i=t.indexOf("."),r=t.indexOf("[");return r>-1&&-1==i?e[t.substring(0,r)][t.substring(r+1,t.length-1)]:r>-1&&i>-1?getFromObject(e[t.substring(0,r)][t.substring(r+1,i-1)],t.substring(i+1)):i>-1?getFromObject(e[t.substring(0,i)],t.substr(i+1)):e[t]}function setFromObject(e,t,i){if("undefined"==typeof e)return!1;var r=t.indexOf("."),n=t.indexOf("[");return n>-1&&-1==r?void(e[t.substring(0,n)][t.substring(n+1,t.length-1)]=i):n>-1&&r>-1?void setFromObject(e[t.substring(0,n)][t.substring(n+1,r-1)],t.substring(r+1),i):(r>-1&&setFromObject(e[t.substring(0,r)],t.substr(r+1),i),void(e[t]=i))}function Vertigo(options){this.el=$(options.el)||$("#app"),this.originalHtml="<html>"+$("html").html()+"</html>",this.$vrbinds={},this.$textReplacements={},this.$listeners={},this.$data=options.data,this.$methods=options.methods;var self=this;this.completeDocument=function(){self.el.find("*").each(function(index){var $this=$(this);$.each(this.attributes,function(){if(this.specified){var attributeSelf=this,directiveName=this.name.toLowerCase().replace("vr-",""),this_path=$this.getPath();if("undefined"!=typeof Vertigo.directives[directiveName]&&(Vertigo.directiveStore[directiveName][this_path]={html:$this.html(),name:attributeSelf.name,value:attributeSelf.value,elementTag:$this.outerHTML().replace($this.html(),""),outerHTML:$this.outerHTML(),before:$this.prevAll().length},Vertigo.directiveStore[directiveName][this_path].action=Vertigo.directives[directiveName](self,$this,this.value,self.$data)),this.name.toLowerCase().startsWith("vr-bind:")&&(self.$vrbinds[this_path]={name:attributeSelf.name,value:attributeSelf.value},$this.attr(this.name.split(":")[1],getFromObject(self.$data,this.value)),$this.removeAttr(this.name)),this.name.toLowerCase().startsWith("vr-on:")){"undefined"==typeof self.$listeners[this_path]&&(self.$listeners[this_path]=[]),self.$listeners[this_path].push(this.name.split(":")[1]);var oneself=this;$this.on(this.name.split(":")[1],function(event){with(self.$methods)eval(oneself.value)||event.preventDefault()})}}});var shouldIgnore=!1;for(var i in Vertigo.ignoreByTextReplacement){var ignore=Vertigo.ignoreByTextReplacement[i];("undefined"!=typeof $this.attr("vr-"+ignore)||"undefined"!=typeof $this.parent().attr("vr-"+ignore))&&(shouldIgnore=!0)}if(!shouldIgnore){var originalPageHtml=$this.html();$this.html(nano($this.html(),self.$data)),self.$textReplacements[$this.getPath()]={original:originalPageHtml,now:$this.html()}}})},this.set=function(e,t){setFromObject(self.$data,e,t),self.reset()},this.get=function(e){return getFromObject(self.$data,e)},this.reset=function(){for(var e in Vertigo.additions){var t=Vertigo.additions[e];if(t.endsWith(")")){var i=t.substring(0,t.length-1).split("(");t=i[0]+"("+(parseInt(i[1]-1)-e)+")"}$(t).remove()}for(var r in self.$listeners)for(var n in self.$listeners[r])$(r).off(self.$listeners[r][n]);for(var s in Vertigo.directiveStore)for(var o in Vertigo.directiveStore[s]){var r=Vertigo.directiveStore[s][o];if("remove"==r.action){var a=o.split(">");a.pop(),$(a.join(">")+">*:nth-child("+r.before+")").after(r.outerHTML)}else if(r.action.startsWith("listener")){var l=r.action.split(" ");if(1==l.length)return void console.warn(s+" has an invalid action.");for(var f=1;f<l.length;f++)$(o).off(l[f].replaceAll("_"," "))}else $(o).outerHTML(r.outerHTML)}for(var o in self.$vrbinds){var r=self.$vrbinds[o],h=r.name.split(":")[1];$(o).removeAttr(h),$(o).attr(r.name,r.value)}for(var o in self.$textReplacements){var r=self.$textReplacements[o];$(o).html(r.original)}Vertigo.additions=[],self.$vrbinds={},self.$textReplacements={},self.$listeners={},self.completeDocument()},this.completeDocument()}jQuery.fn.outerHTML=function(e){return e?this.before(e).remove():jQuery("<p>").append(this.eq(0).clone()).html()},jQuery.fn.extend({getPath:function(){for(var e,t=this;t.length;){var i=t[0],r=i.localName;if(!r)break;r=r.toLowerCase();var n=t.parent(),s=n.children(r);if(s.length>1){allSiblings=n.children();var o=allSiblings.index(i)+1;o>1&&(r+=":nth-child("+o+")")}e=r+(e?">"+e:""),t=n}return e}}),String.prototype.replaceAll=function(e,t){var i=this;return i.replace(new RegExp(e,"g"),t)},Vertigo.directives={},Vertigo.directiveStore={},Vertigo.ignoreByTextReplacement=[],Vertigo.additions=[],Vertigo.registerDirective=function(e,t,i){Vertigo.directives[e.toLowerCase()]=t,Vertigo.directiveStore[e]={},i&&Vertigo.ignoreByTextReplacement.push(e)},Vertigo.registerDirective("if",function(app,element,value,data){with(data)if(!eval(value))return element.remove(),"remove";return"keep"},!1),Vertigo.registerDirective("for",function(e,t,i,r){for(var n,s=i.split("in")[0].trim(),o=i.split("in")[1].trim(),a=getFromObject(r,o),l=t.outerHTML(),f=0;f<a.length;f++){n=l.replaceAll(s,o+"["+f+"]"),n=nano(n,r);var h=t.before(n);Vertigo.additions.push(h.getPath())}return t.remove(),"remove"},!0),Vertigo.registerDirective("model",function(e,t,i,r){if(t.is("input")){var n;t.val(n=e.get(i)),t.on("keyup",function(r){n!=t.val()&&(n=t.val(),e.set(i,t.val()))})}return"listener keyup"},!1); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment