├── .gitignore ├── LICENSE.txt ├── production └── uilang.js ├── README.md └── development └── uilang-1.0.1.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2015 Benjamin De Cock 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /production/uilang.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("DOMContentLoaded",function(){function n(a){var b=a.charAt(0);a=a.split(b);this.clickSelector=a[1];this.classBehavior=a[2].trim().split(" ")[0];this.classValue=a[3];this.targetSelector=a[5]}function f(a,b,c,d){this.clickSelector=a;this.classBehavior="s"==b.charAt(b.length-1)?b.substring(0,b.length-1):b;this.classValue="."==c.charAt(0)?c.substring(1,c.length):c;this.targetSelector=d;this.createEventListener()}for(var g=document.getElementsByTagName("code"),h=g.length,e,k;h--;){var l= 2 | g[h],m=l.textContent.trim();if(0===m.lastIndexOf("clicking on",0)){e=l;k=m;break}}e&&(e.parentNode.removeChild(e),f.prototype.createEventListener=function(){function a(a){switch(b.targetSelector){case "target":case "this":case "it":case "itself":case void 0:a.target.classList[b.classBehavior](b.classValue);break;default:for(var c=document.querySelectorAll(b.targetSelector),d=c.length;d--;)c.item(d).classList[b.classBehavior](b.classValue)}"a"==a.target.nodeName.toLowerCase()&&a.preventDefault()}var b= 3 | this,c=document.querySelectorAll(b.clickSelector),d=c.length;if(1>d)throw Error("There's no element matching your \""+b.clickSelector+'" CSS selector.');for(;d--;)c.item(d).addEventListener("click",a)},k.split("clicking on").forEach(function(a){a&&(a=new n(a.trim()),new f(a.clickSelector,a.classBehavior,a.classValue,a.targetSelector))}))}); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # uilang 2 | 3 | uilang is a dead simple programming language for web designers. With uilang, you write your code just like plain English, straight into your HTML using a `` element. uilang's logic relies on manipulating classes on HTML elements and using these classes in CSS to show, hide, animate and transform elements when a click occurs. This simple logic lets designers create most of the typical user interface behaviours: tabs, popovers, overlays, sliding menus, etc. 4 | 5 | ## Getting started 6 | 7 | The first thing to do is to include `uilang.js` on your page. [Download](https://github.com/bendc/uilang/blob/master/production/uilang.js) the minified version (1KB) and insert it anywhere in your HTML: 8 | 9 | ```html 10 | 11 | ``` 12 | You're now ready to write some uilang. Your code should be inserted in a `` element, preferably at the very end of your page (just before ``). The syntax looks like this: 13 | 14 | ```html 15 | 16 | clicking on ".hide" adds class "hidden" on "div" 17 | 18 | ``` 19 | This is pretty much the only syntax you'll have to learn. This code is straightforward: when you click on an element with a `hide` class, a `hidden` class will be added to every `div`. 20 | 21 | Now, this `hidden` class can be used in your CSS to actually hide these `div`s with, for example, a simple fade-out effect: 22 | 23 | ```css 24 | div { 25 | transition: opacity .5s; 26 | } 27 | div.hidden { 28 | opacity: 0; 29 | } 30 | ``` 31 | ## Syntax 32 | 33 | Let's deconstruct the syntax from our previous example: 34 | 35 | ```html 36 | 37 | clicking on ".hide"(1) adds(2) class "hidden"(3) on "div"(4) 38 | 39 | ``` 40 | 1. Any CSS selector. 41 | 2. `adds`, `removes` or `toggles`. 42 | 3. Any class name. 43 | 4. Any CSS selector or the `target` keyword (which selects the clicked element). 44 | 45 | You can add as many instructions as you want into your `` element: 46 | 47 | ```html 48 | 49 | clicking on ".hide" adds class "hidden" on "div" 50 | clicking on "nav .tabs" adds class "active" on "target" 51 | clicking on "img:first-child" toggles class "big" on "target" 52 | 53 | ``` 54 | Don't worry about having other `` elements on your page, uilang will only execute the one containing your uilang code. 55 | 56 | Please note that uilang only supports click events. Hover effects can usually be achieved in CSS and other events are simply out of the scope of this language. By keeping its feature set light and focused, uilang aims to lower the barriers to entry into programming. 57 | 58 | ## Comments 59 | 60 | Keep in mind uilang is basically just HTML, which means that you're already familiar with the syntax for comments: 61 | 62 | ```html 63 | 64 | 65 | clicking on ".hide" adds class "hidden" on "div" 66 | 67 | 68 | clicking on "nav .tabs" adds class "active" on "target" 69 | 70 | ``` 71 | -------------------------------------------------------------------------------- /development/uilang-1.0.1.js: -------------------------------------------------------------------------------- 1 | /* 2 | * uilang v1.0.1 3 | * http://uilang.com 4 | */ 5 | 6 | document.addEventListener("DOMContentLoaded", function() { 7 | "use strict" 8 | 9 | var codeElements = document.getElementsByTagName("code") 10 | var i = codeElements.length 11 | var delimiter = "clicking on" 12 | var codeBlock 13 | var codeBlockContent 14 | 15 | while (i--) { 16 | var code = codeElements[i] 17 | var content = code.textContent.trim() 18 | if (content.lastIndexOf(delimiter, 0) === 0) { 19 | codeBlock = code 20 | codeBlockContent = content 21 | break 22 | } 23 | } 24 | 25 | if (!codeBlock) return 26 | codeBlock.parentNode.removeChild(codeBlock) 27 | 28 | function InstructionParsing(instruction) { 29 | var separator = instruction.charAt(0) 30 | var instructionSplit = instruction.split(separator) 31 | 32 | this.clickSelector = instructionSplit[1] 33 | this.classBehavior = instructionSplit[2].trim().split(" ")[0] 34 | this.classValue = instructionSplit[3] 35 | this.targetSelector = instructionSplit[5] 36 | } 37 | 38 | function UIElement(clickSelector, classBehavior, classValue, targetSelector) { 39 | this.clickSelector = clickSelector 40 | this.classBehavior = classBehavior.charAt(classBehavior.length-1) == "s" 41 | ? classBehavior.substring(0, classBehavior.length-1) 42 | : classBehavior 43 | this.classValue = classValue.charAt(0) == "." 44 | ? classValue.substring(1, classValue.length) 45 | : classValue 46 | this.targetSelector = targetSelector 47 | this.createEventListener() 48 | } 49 | 50 | UIElement.prototype.createEventListener = function() { 51 | var self = this 52 | var clicked = document.querySelectorAll(self.clickSelector) 53 | var i = clicked.length 54 | 55 | if (i < 1) { 56 | throw new Error("There's no element matching your \"" + self.clickSelector + "\" CSS selector.") 57 | } 58 | 59 | while (i--) { 60 | clicked.item(i).addEventListener("click", clickCallback) 61 | } 62 | 63 | function updateClass(el) { 64 | el.classList[self.classBehavior](self.classValue) 65 | } 66 | 67 | function clickCallback(e) { 68 | switch (self.targetSelector) { 69 | case "target" : 70 | case "this" : 71 | case "it" : 72 | case "itself" : 73 | case undefined: 74 | updateClass(e.target) 75 | break 76 | default: 77 | var target = document.querySelectorAll(self.targetSelector) 78 | var i = target.length 79 | while (i--) { 80 | updateClass(target.item(i)) 81 | } 82 | } 83 | if (e.target.nodeName.toLowerCase() == "a") { 84 | e.preventDefault() 85 | } 86 | } 87 | } 88 | 89 | codeBlockContent.split(delimiter).forEach(function(data) { 90 | if (!data) return 91 | var params = new InstructionParsing(data.trim()) 92 | new UIElement( 93 | params.clickSelector, 94 | params.classBehavior, 95 | params.classValue, 96 | params.targetSelector 97 | ) 98 | }) 99 | }) 100 | --------------------------------------------------------------------------------