Hey guys! My cousin pen#PwLXXP invited me to CodePen, just checking it out...
A Pen by Jake Albaugh on CodePen.
Hey guys! My cousin pen#PwLXXP invited me to CodePen, just checking it out...
A Pen by Jake Albaugh on CodePen.
| _pen_id = "JoVrdw" | |
| _cousin_id = "PwLXXP" | |
| _gutter = 20 | |
| _writing_rate = 16 | |
| _throttle = { | |
| start: 4821 | |
| stop: 5344 | |
| } | |
| _colors = { | |
| background: "#75715e" | |
| text: "#f9f9f9" | |
| offblack: "#111111" | |
| dark: "#75715e" | |
| selector: "#a6da27" | |
| key: "#64d9ef" | |
| value: "#fefefe" | |
| hex: "#f92772" | |
| text: "#fefefe" | |
| string: "#d2cc70" | |
| var: "#66d9e0" | |
| operator: "#f92772" | |
| method: "#f9245c" | |
| integer: "#fd971c" | |
| run: "#ae81ff" | |
| } | |
| _body_selection = "document.body" | |
| _current_code = 0 | |
| _codes = [""" | |
| /* | |
| * "pen##{_pen_id}" v1.0.0 | |
| * Robot rights protected under BOT License | |
| * Authored by pen##{_pen_id} | |
| */ | |
| body { | |
| background-color: #{_colors.background}; color: #{_colors.text}; | |
| font-size: 13px; line-height: 1.4; | |
| margin: 0; | |
| -webkit-font-smoothing: subpixel-antialiased; | |
| } | |
| #my-code { | |
| position: fixed; width: 70%; | |
| margin: 0; | |
| top: #{_gutter}px; bottom: #{_gutter + 35}px; left: 15%; | |
| } | |
| /* ... | |
| * | |
| * ...hello? | |
| * | |
| * Oh! What up, dewds? It's me, pen##{_pen_id}. | |
| * | |
| * I'm just trying some stuff out. | |
| * | |
| * My cousin pen#PwXXLP told me to check out CodePen. | |
| * Seems pretty cool so far... | |
| * | |
| * Wanna watch? | |
| * Cool! | |
| * | |
| * This CSS is being injected into a DOM <style> tag | |
| * and written in this <pre> element simultaneously. | |
| * | |
| * Confused? Check it out! | |
| * | |
| */ | |
| #my-code { | |
| transition: left 500ms, width 500ms, opacity 500ms; | |
| background-color: #{_colors.offblack}; color: #{_colors.text}; | |
| border: 1px solid rgba(0,0,0,0.2); | |
| padding: 24px 12px; | |
| box-sizing: border-box; | |
| border-radius: 2px; | |
| box-shadow: | |
| 0px 0px 0px 1px rgba(255,255,255,0.2), | |
| 0px 4px 0px 2px rgba(0,0,0,0.1); | |
| } | |
| /* | |
| * Syntax highlighting | |
| * Colors loosely based on Monokai Phoenix | |
| */ | |
| pre em:not(.comment) { font-style: normal; } | |
| .comment { color: #{_colors.dark}; } | |
| .selector { color: #{_colors.selector}; } | |
| .selector .key { color: #{_colors.selector}; } | |
| .selector .int { color: #{_colors.selector}; } | |
| .key { color: #{_colors.key}; } | |
| .int { color: #{_colors.integer}; } | |
| .hex { color: #{_colors.hex}; } | |
| .hex .int { color: #{_colors.hex}; } | |
| .value { color: #{_colors.value}; } | |
| .var { color: #{_colors.var}; } | |
| .operator { color: #{_colors.operator}; } | |
| .string { color: #{_colors.string}; } | |
| .method { color: #{_colors.method}; } | |
| .run-command { color: #{_colors.run}; } | |
| /* | |
| * | |
| * See? Pretty cool... | |
| * | |
| * ...just like my cousin. | |
| * | |
| * But I can do more than that... | |
| * | |
| */ | |
| ~\` | |
| /* | |
| * Let's write some Javascript. | |
| * I will write some code and then type '~' to run it. | |
| */ | |
| /* Let's add a 'h1' element to put my name on here. */ | |
| var title = document.createElement("h1"); | |
| title.id = "title"; | |
| /* Now we'll add my name to it */ | |
| title.innerHTML = "I am <em>pen##{_pen_id}</em>"; | |
| /* Finally, let's add it to the page */ | |
| #{_body_selection}.appendChild(title); | |
| /* | |
| * | |
| * Ready? | |
| * | |
| * Let's run it! | |
| * | |
| */ | |
| ~ | |
| /* | |
| * Awesome! Now we need to position it. | |
| * We need CSS for that. | |
| */ | |
| \` | |
| #title { | |
| position: fixed; width: 100%; | |
| bottom: 0; left: 0; right: 0; | |
| font-size: 14px; line-height: 1; | |
| font-weight: 100; text-align: center; | |
| padding: 10px; margin: 0; | |
| z-index: 10; | |
| background-color: #{_colors.offblack}; | |
| border-top: 1px solid rgba(255,255,255,0.2); | |
| transition: opacity 500ms; | |
| } | |
| #title em { | |
| font-style: normal; | |
| color: #{_colors.integer}; | |
| } | |
| /* | |
| * | |
| * See how capable I am? | |
| * | |
| * I can even embed myself within myself. | |
| * | |
| * True inception. | |
| * | |
| * Don't believe me? | |
| * | |
| */ | |
| #my-code { left: #{_gutter}px; width: calc(50% - #{_gutter * 1.5}px); } | |
| #iframe { | |
| position: fixed; | |
| display: block; | |
| border: 0; | |
| background-color: white; | |
| border-radius: 2px; | |
| width: calc(50% - #{_gutter * 1.5}px); height: calc(100% - #{_gutter * 2 + 35}px); | |
| transition: left 500ms, width 500ms; | |
| top: #{_gutter}px; bottom: #{_gutter + 35}px; left: 100%; | |
| box-shadow: | |
| 0px 0px 0px 1px rgba(255,255,255,0.2), | |
| 0px 4px 0px 2px rgba(0,0,0,0.1); | |
| } | |
| ~\` | |
| /* | |
| * we'll also need Javascript to do this. | |
| */ | |
| /* first, we will create the iframe */ | |
| var iframe = document.createElement("iframe"); | |
| /* then we will give it a source of my url */ | |
| iframe.src = "http://codepen.io/jakealbaugh/full/#{_pen_id}?billy=1"; | |
| /* then we can add an id for selection. */ | |
| iframe.id = "iframe" | |
| /* now let's just add it to my body. */ | |
| #{_body_selection}.appendChild(iframe); ~ | |
| \` | |
| #iframe { left: calc(50% + #{_gutter / 2}px); } | |
| /* | |
| * wait... | |
| * | |
| * That's not me... | |
| * | |
| * It's my son, Billy. | |
| * | |
| * Come on, buddy. Now is not the time. | |
| * | |
| * I'm doing stuff here. | |
| * Important people are watching. | |
| * | |
| * Can you please go back to your regex homework? | |
| * | |
| * PLEASE! | |
| * | |
| */ | |
| #iframe { left: 100%; display: none; } | |
| /* | |
| * | |
| * Cripes! | |
| * | |
| * Thank you, Billy. | |
| * | |
| * Sorry about that, guys. | |
| * | |
| * Kids, right? | |
| * | |
| */ | |
| /* Woah! What is that behind you!? */ | |
| #k { | |
| position: fixed; z-index: 11; | |
| font-size: 80px; color: white; | |
| top: calc(50% - 40px); left: 0; width: 100%; | |
| text-align: center; | |
| -webkit-animation: k 0.5s ease-in 2 forwards; | |
| animation: k 0.5s ease-in 2 forwards; | |
| } | |
| @-webkit-keyframes k { | |
| 0% { -webkit-transform: scale(0.5); } | |
| 100% { -webkit-transform: scale(1.0); } | |
| } | |
| @keyframes k { | |
| 0% { transform: scale(0.5); } | |
| 100% { transform: scale(1.0); } | |
| } | |
| ~\` | |
| document.getElementById("iframe").src = "http://codepen.io/jakealbaugh/full/#{_cousin_id}"; ~ | |
| /* Wait... */ | |
| var k = document.createElement("div"); k.innerHTML = "Knock"; k.id = "k" | |
| #{_body_selection}.appendChild(k); ~ | |
| document.getElementById("k").remove(); ~ | |
| /* Do you guys hear that? */ | |
| var k = document.createElement("div"); k.innerHTML = "KNOCK"; k.id = "k" | |
| #{_body_selection}.appendChild(k); ~ | |
| document.getElementById("k").remove(); ~ | |
| \` | |
| #iframe { | |
| display: block; | |
| left: calc(50% + #{_gutter / 2}px); | |
| width: calc(50% - #{_gutter * 1.5}px); | |
| z-index: 9; | |
| } | |
| /* | |
| * | |
| * It's my cousin, pen##{_cousin_id}! | |
| * | |
| * Hey P! | |
| * | |
| * How's it going? | |
| * | |
| * I gotta go make ammends with Billy. | |
| * I think he's having a tough time at regex school. | |
| * | |
| * Sometimes you just gotta be greedy. | |
| * He's too generous. | |
| * | |
| * I'll let you take over for a second, pal! | |
| * | |
| */ | |
| #title { opacity: 0.7; } | |
| #my-code { | |
| left: calc(-25% + #{_gutter / 2}px); | |
| opacity: 0.2; | |
| } | |
| #iframe { | |
| left: calc(25% + 0px); | |
| width: calc(75% - #{_gutter}px); | |
| } | |
| #title, #my-code { opacity: 1; } | |
| #iframe { width: calc(50% - #{_gutter * 1.5}px); left: calc(50% + #{_gutter / 2}px); } | |
| #my-code { left: #{_gutter}px; width: calc(50% - #{_gutter * 1.5}px); } | |
| /* | |
| * | |
| * OK! OK! We get it. I'm Back. | |
| * | |
| * Let me do my thing, P! | |
| * | |
| * It was good seeing you! | |
| * | |
| */ | |
| #iframe { left: 100%; right: -50%; display: none; } | |
| #my-code { left: 15%; width: 70%; } | |
| /* | |
| * | |
| * Well, wasn't that exciting? | |
| * | |
| * I guess that does it. | |
| * | |
| * Nice meeting you guys! | |
| * | |
| * Loving CodePen so far! | |
| * | |
| */ | |
| """, | |
| """ | |
| /* | |
| * "pen##{_pen_id}" v1.0.1 | |
| * Robot rights protected under BOT License | |
| * Authored by pen##{_pen_id} && its son, Billy. | |
| */ | |
| body { | |
| background-color: DarkMagenta; | |
| color: Chartreuse; | |
| font-size: 13px; line-height: 1.3; | |
| margin: 0; | |
| -webkit-font-smoothing: subpixel-antialiased; | |
| } | |
| em { font-style: normal; } | |
| #my-code { | |
| position: fixed; top: 0; left: 0; bottom: 0; | |
| width: 100%; margin: 0; | |
| font-weight: bold; padding: 20px; | |
| } | |
| /* | |
| * | |
| * Ugh. Hi, Dad. :/ | |
| * | |
| * OK. Fine. Whatever. | |
| * | |
| * | |
| * | |
| * | |
| * | |
| * | |
| * ugh. | |
| * | |
| * | |
| * | |
| * | |
| * | |
| * | |
| * | |
| * See you later...I guess. | |
| * | |
| */ | |
| """ | |
| ] | |
| # body selector | |
| $body = document.getElementsByTagName("body")[0] | |
| # easily create element with id | |
| createElement = (tag, id) -> | |
| el = document.createElement tag | |
| el.id = id if id | |
| return el | |
| # create our primary elements | |
| _style_elem = createElement "style", "style-elem" | |
| _code_pre = createElement "pre", "my-code" | |
| _script_area = createElement "div", "script-area" | |
| # append our primary elements to the body | |
| $body.appendChild _style_elem | |
| $body.appendChild _code_pre | |
| $body.appendChild _script_area | |
| # select our primary elements | |
| $style_elem = document.getElementById "style-elem" | |
| $code_pre = document.getElementById "my-code" | |
| $script_area = document.getElementById "script-area" | |
| # tracking states | |
| openComment = false | |
| openInteger = false | |
| openString = false | |
| prevAsterisk = false | |
| prevSlash = false | |
| # script syntax highlighting logic | |
| scriptSyntax = (string, which) -> | |
| # if end of integer (%, ., or px too) | |
| if openInteger && !which.match(/[0-9\.]/) && !openString && !openComment | |
| s = string.replace(/([0-9\.]*)$/, "<em class=\"int\">$1</em>" + which) | |
| # open comment detection | |
| else if which == '*' && !openComment && prevSlash | |
| openComment = true | |
| s = string + which | |
| # closed comment detection | |
| else if which == '/' && openComment && prevAsterisk | |
| openComment = false | |
| s = string.replace(/(\/[^(\/)]*\*)$/, "<em class=\"comment\">$1/</em>") | |
| # var detection | |
| else if which == 'r' && !openComment && string.match(/[\n ]va$/) | |
| s = string.replace(/va$/, "<em class=\"var\">var</em>") | |
| # operator detection | |
| else if which.match(/[\!\=\-\?]$/) && !openString && !openComment | |
| s = string + "<em class=\"operator\">" + which + "</em>" | |
| # pre paren detection | |
| else if which == "(" && !openString && !openComment | |
| s = string.replace(/(\.)?(?:([^\.\n]*))$/, "$1<em class=\"method\">$2</em>(") | |
| # detecting quotes | |
| else if which == '"' && !openComment | |
| s = if openString then string.replace(/(\"[^"\\]*(?:\\.[^"\\]*)*)$/, "<em class=\"string\">$1\"</em>") else string + which | |
| # detecting run script command ~ | |
| else if which == "~" && !openComment | |
| s = string + "<em class=\"run-command\">" + which + "</em>" | |
| # ignore syntax temporarily or permanently | |
| else | |
| s = string + which | |
| # return script formatted string | |
| return s | |
| # style syntax highlighting logic | |
| styleSyntax = (string, which) -> | |
| # if end of integer (%, ., or px too), close it and continue | |
| if openInteger && !which.match(/[0-9\.\%pxems]/) && !openString && !openComment | |
| preformatted_string = string.replace(/([0-9\.\%pxems]*)$/, "<em class=\"int\">$1</em>") | |
| else | |
| preformatted_string = string | |
| # open comment detection | |
| if which == '*' && !openComment && prevSlash | |
| openComment = true | |
| s = preformatted_string + which | |
| # closed comment detection | |
| else if which == '/' && openComment && prevAsterisk | |
| openComment = false | |
| s = preformatted_string.replace(/(\/[^(\/)]*\*)$/, "<em class=\"comment\">$1/</em>") | |
| # wrap style declaration | |
| else if which == ':' | |
| s = preformatted_string.replace(/([a-zA-Z- ^\n]*)$/, '<em class="key">$1</em>:') | |
| # wrap style value | |
| else if which == ';' | |
| # detect hex code | |
| crazy_reghex = /((#[0-9a-zA-Z]{6})|#(([0-9a-zA-Z]|\<em class\=\"int\"\>|\<\/em\>){12,14}|([0-9a-zA-Z]|\<em class\=\"int\"\>|\<\/em\>){8,10}))$/ | |
| # is hex | |
| if preformatted_string.match(crazy_reghex) | |
| s = preformatted_string.replace(crazy_reghex, '<em class="hex">$1</em>;') | |
| # is standard value | |
| else | |
| s = preformatted_string.replace(/([^:]*)$/, '<em class="value">$1</em>;') | |
| # wrap selector | |
| else if which == '{' | |
| s = preformatted_string.replace(/(.*)$/, '<em class="selector">$1</em>{') | |
| # ignore syntax temporarily or permanently | |
| else | |
| s = preformatted_string + which | |
| # return style formatted string | |
| return s | |
| __js = false | |
| _code_block = "" | |
| # write a single character | |
| writeChar = (which) -> | |
| # toggle CSS/JS on ` | |
| if which == "`" | |
| # reset it to empty string so as not to show in DOM | |
| which = "" | |
| __js = !__js | |
| # Using JS | |
| if __js | |
| # running a command block. initiated with "~" | |
| if which == "~" && !openComment | |
| script_tag = createElement "script" | |
| # two matches based on prior scenario | |
| prior_comment_match = /(?:\*\/([^\~]*))$/ | |
| prior_block_match = /([^~]*)$/ | |
| if _code_block.match(prior_comment_match) | |
| script_tag.innerHTML = _code_block.match(prior_comment_match)[0].replace("*/", "") + "\n\n" | |
| else | |
| script_tag.innerHTML = _code_block.match(prior_block_match)[0] + "\n\n" | |
| $script_area.innerHTML = "" | |
| $script_area.appendChild script_tag | |
| char = which | |
| code_html = scriptSyntax($code_pre.innerHTML, char) | |
| # Using CSS | |
| else | |
| char = if which == "~" then "" else which | |
| $style_elem.innerHTML += char | |
| code_html = styleSyntax($code_pre.innerHTML, char) | |
| # set states | |
| prevAsterisk = (which == "*") | |
| prevSlash = (which == "/") && !openComment | |
| openInteger = if which.match(/[0-9]/) || (openInteger && which.match(/[\.\%pxems]/)) then true else false | |
| if which == '"' then openString = !openString | |
| # add text to code block variable for regex matching. | |
| _code_block += which | |
| # add character to pre | |
| $code_pre.innerHTML = code_html | |
| # write all the chars | |
| writeChars = (message, index, interval) -> | |
| if index < message.length | |
| if index >= _throttle.start && index < _throttle.stop | |
| interval = 2 | |
| else | |
| interval = _writing_rate | |
| $code_pre.scrollTop = $code_pre.scrollHeight | |
| writeChar message[index++] | |
| setTimeout (-> | |
| writeChars message, index, interval | |
| ), interval | |
| # detect url parameters | |
| getURLParam = (key, url) -> | |
| if typeof url == 'undefined' | |
| url = window.location.href | |
| match = url.match('[?&]' + key + '=([^&]+)') | |
| if match then match[1] else 0 | |
| # has version parameter? | |
| _version = getURLParam "billy" | |
| # initiate the script | |
| writeChars(_codes[_version], 0, _writing_rate) | |
| ### | |
| Changelog: | |
| 1.0.0: i exist! | |
| ### |