Skip to content
Browse files

setup editor for hacking

  • Loading branch information...
1 parent 90b7457 commit 109856bce06889caec01488a2e485efc744f6001 @tobi committed Nov 8, 2009
Showing with 873 additions and 0 deletions.
  1. +151 −0 public/index.html
  2. +366 −0 public/javascripts/parseliquid.js
  3. +285 −0 public/stylesheets/application.css
  4. +71 −0 public/stylesheets/liquidcolors.css
View
151 public/index.html
@@ -0,0 +1,151 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="imagetoolbar" content="no" />
+ <meta name="MSSmartTagsPreventParsing" content="true" />
+
+ <title>Liquid Test</title>
+
+ <link href="/stylesheets/application.css" media="screen" rel="stylesheet" type="text/css" />
+</head>
+
+<body>
+
+ <div id="header">
+ <h1><a href="/">Liquid Editor</a></h1>
+
+ </div>
+
+ <div id="container" class="clearfix">
+
+ <ul id="tabs">
+ <li><a href="/" id="current">Home</a></li>
+ <li><a href="/home/design">Design Help</a></li>
+ </ul>
+
+ <!-- Flash error & notice-->
+
+
+
+ <!-- begin div.main-->
+ <div id="main">
+
+<div>
+ <textarea id="code" cols="140" rows="40">
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <title>{{shop.name}} — {{page_title}}</title>
+
+ {{ 'layout.css' | asset_url | stylesheet_tag }}
+ {{ 'lightbox/v2/lightbox.css' | global_asset_url | stylesheet_tag }}
+ {{ 'lightbox/v2/lightbox.js' | global_asset_url | script_tag }}
+
+ {{content_for_header }}
+ </head>
+ <body>
+ <div id="demostore">
+ This is a {{ 'Shopify' | link_to: 'http://www.shopify.com' }} demo store. We do not have the products advertised here and we don't really charge money upon order completion.
+ </div><div id="main">
+
+ <div id="container">
+ <div id="header">
+ <ul id="sitelinks">
+ {% for link in linklists.footer.links %}
+ <li>{{ link.title | link_to: link.url }}</li>
+ {% endfor %}
+ <li class="cartlink">
+ {% if cart['item_count'] == 0 %}
+ <strong>Shopping Cart</strong> <img src="{{ 'cart.gif' | asset_url }}" alt="Shopping Cart" height="26" width="26" />
+ {% else %}
+ <strong><a href="/cart">Shopping Cart</a></strong> ({{cart.item_count}} {{ cart.item_count | pluralize: 'item', 'items' }})<img src="{{ 'cart.gif' | asset_url }}" alt="Shopping Cart" height="26" width="26" />
+ {% endif %}
+ </li>
+ </ul>
+ </div>
+
+ <div id="side" class="left">
+ <div class="menubar">
+ <ul id="nav">
+ {% for link in linklists.main-menu.links %}
+ <li class="{%if forloop.first%}home first{%endif%}{%if forloop.last%}last{%endif%}"><strong>{{ link.title | link_to: link.url }}</strong></li>
+ {% endfor %}
+ </ul>
+ </div>
+
+
+ <div id="searchbox">
+ <form method="get" action="/search">
+ <input type="text" size="16" name="q" onfocus="if(this.value='Search...'){this.value = ''}" value="Search..." />
+ </form>
+ </div>
+
+
+ <div id="featurebox">
+
+ <ul id="feature">
+ <li class="first"><strong>Blowout Deals</strong></li>
+ {% for link in linklists.deals.links %}
+ <li class="">{{ link.title | link_to: link.url }}</li>
+ {% endfor %}
+ </ul>
+ </div>
+
+ </div>
+
+ <div id="content" class="content">
+ {{content_for_layout}}
+ </div>
+
+ <div id="footer">
+
+ <p><span>All rights reserved.</span><br /><br />
+ <span> Copyright {{ 'now' | date: "2005-%Y"}} Snowdevil.</span> <span>All sales are final. All prices in Canadian dollars.</span><br/>
+ <span class="partners">Please visit our partner pages: <a target="_blank" href="http://www.hoppels.com">Windsurf </a > <a target="_blank" href="http://www.brett-ist-brett.de">Funsport Photo Community</a></span></p>
+ </div>
+
+
+ </div>
+ </div>
+ </body>
+</html>
+ </textarea>
+
+ <script src="codemirror/js/codemirror.js" type="text/javascript"></script>
+
+ <style type="text/css">
+ .CodeMirror-line-numbers {
+ width: 2.2em;
+ color: #aaa;
+ background-color: #eee;
+ text-align: right;
+ padding-right: .3em;
+ font-size: 10pt;
+ font-family: monospace;
+ padding-top: .4em;
+ }
+ </style>
+
+ <script type="text/javascript">
+ var editor = CodeMirror.fromTextArea('code', {
+ height: "600px",
+ parserfile: "parsexml.js",
+ stylesheet: "codemirror/css/xmlcolors.css",
+ path: "codemirror/js/",
+ continuousScanning: 500,
+
+ lineNumbers: true
+ });
+ </script>
+
+</div>
+ </div>
+ <!-- end div.main -->
+
+ </div>
+
+</body>
+</html>
View
366 public/javascripts/parseliquid.js
@@ -0,0 +1,366 @@
+/* This file defines an XML parser, with a few kludges to make it
+ * useable for HTML. autoSelfClosers defines a set of tag names that
+ * are expected to not have a closing tag, and doNotIndent specifies
+ * the tags inside of which no indentation should happen (see Config
+ * object). These can be disabled by passing the editor an object like
+ * {useHTMLKludges: false} as parserConfig option.
+ */
+
+var XMLParser = Editor.Parser = (function() {
+ var Kludges = {
+ autoSelfClosers: {"br": true, "img": true, "hr": true, "link": true, "input": true,
+ "meta": true, "col": true, "frame": true, "base": true, "area": true},
+ doNotIndent: {"pre": true, "!cdata": true}
+ };
+ var NoKludges = {autoSelfClosers: {}, doNotIndent: {"!cdata": true}};
+ var UseKludges = Kludges;
+ var alignCDATA = false;
+
+ // Simple stateful tokenizer for XML documents. Returns a
+ // MochiKit-style iterator, with a state property that contains a
+ // function encapsulating the current state. See tokenize.js.
+ var tokenizeXML = (function() {
+ function inText(source, setState) {
+ var ch = source.next();
+ if (ch == "<") {
+ if (source.equals("!")) {
+ source.next();
+ if (source.equals("[")) {
+ if (source.lookAhead("[CDATA[", true)) {
+ setState(inBlock("xml-cdata", "]]>"));
+ return null;
+ }
+ else {
+ return "xml-text";
+ }
+ }
+ else if (source.lookAhead("--", true)) {
+ setState(inBlock("xml-comment", "-->"));
+ return null;
+ }
+ else {
+ return "xml-text";
+ }
+ }
+ else if (source.equals("?")) {
+ source.next();
+ source.nextWhileMatches(/[\w\._\-]/);
+ setState(inBlock("xml-processing", "?>"));
+ return "xml-processing";
+ }
+ else {
+ if (source.equals("/")) source.next();
+ setState(inTag);
+ return "xml-punctuation";
+ }
+ }
+ else if (ch == "{") {
+ if (source.equals("{")) {
+ source.next();
+ setState(inLiquidVariable);
+ return 'liquid-punctuation';
+ }
+ if (source.equals("%")) {
+ source.next();
+ setState(inLiquidTag);
+ return 'liquid-punctuation';
+ }
+ else {
+ return "xml-text";
+ }
+ }
+ else if (ch == "&") {
+ while (!source.endOfLine()) {
+ if (source.next() == ";")
+ break;
+ }
+ return "xml-entity";
+ }
+ else {
+ source.nextWhileMatches(/[^{&<\n]/);
+ return "xml-text";
+ }
+ }
+
+ function inTag(source, setState) {
+ var ch = source.next();
+ if (ch == ">") {
+ setState(inText);
+ return "xml-punctuation";
+ }
+ else if (/[?\/]/.test(ch) && source.equals(">")) {
+ source.next();
+ setState(inText);
+ return "xml-punctuation";
+ }
+ else if (ch == "=") {
+ return "xml-punctuation";
+ }
+ else if (/[\'\"]/.test(ch)) {
+ setState(inAttribute(ch));
+ return null;
+ }
+ else {
+ source.nextWhileMatches(/[^\s\u00a0=<>\"\'\/?]/);
+ return "xml-name";
+ }
+ }
+
+ function inLiquidVariable(source, setState) {
+ var ch = source.next();
+ if (ch == "}") {
+ if (source.equals('}')) {
+ source.next()
+ setState(inText);
+ return "liquid-punctuation";
+ }
+ }
+ else if (/[\'\"]/.test(ch)) {
+ setState(inLiquidString(ch, inLiquidVariable));
+ return null;
+ }
+ else if (/[\|\=\:]/.test(ch)) {
+ return "liquid-punctuation";
+ }
+ else {
+ source.nextWhileMatches(/[\s\n]/);
+ return "liquid-text";
+ }
+ }
+
+ function inLiquidTag(source, setState) {
+ var ch = source.next();
+ if (ch == "%") {
+ if (source.equals('}')) {
+ source.next()
+ setState(inText);
+ return "liquid-punctuation";
+ }
+ }
+ else if (/[\'\"]/.test(ch)) {
+ setState(inLiquidString(ch, inLiquidTag));
+ return null;
+ }
+ else if (/[\|\=\:]/.test(ch)) {
+ return "liquid-punctuation";
+ }
+ else {
+ source.nextWhileMatches(/ \n/);
+ return "liquid-text";
+ }
+ }
+
+ function inLiquidString(quote, outer) {
+ return function(source, setState) {
+ while (!source.endOfLine()) {
+ if (source.next() == quote) {
+ setState(outer);
+ break;
+ }
+ }
+ return "liquid-string";
+ };
+ }
+
+
+ function inAttribute(quote) {
+ return function(source, setState) {
+ while (!source.endOfLine()) {
+ if (source.next() == quote) {
+ setState(inTag);
+ break;
+ }
+ }
+ return "xml-attribute";
+ };
+ }
+
+ function inBlock(style, terminator) {
+ return function(source, setState) {
+ while (!source.endOfLine()) {
+ if (source.lookAhead(terminator, true)) {
+ setState(inText);
+ break;
+ }
+ source.next();
+ }
+ return style;
+ };
+ }
+
+ return function(source, startState) {
+ return tokenizer(source, startState || inText);
+ };
+ })();
+
+ // The parser. The structure of this function largely follows that of
+ // parseJavaScript in parsejavascript.js (there is actually a bit more
+ // shared code than I'd like), but it is quite a bit simpler.
+ function parseXML(source) {
+ var tokens = tokenizeXML(source);
+ var cc = [base];
+ var tokenNr = 0, indented = 0;
+ var currentTag = null, context = null;
+ var consume, marked;
+
+ function push(fs) {
+ for (var i = fs.length - 1; i >= 0; i--)
+ cc.push(fs[i]);
+ }
+ function cont() {
+ push(arguments);
+ consume = true;
+ }
+ function pass() {
+ push(arguments);
+ consume = false;
+ }
+
+ function mark(style) {
+ marked = style;
+ }
+ function expect(text) {
+ return function(style, content) {
+ if (content == text) cont();
+ else mark("xml-error") || cont(arguments.callee);
+ };
+ }
+
+ function pushContext(tagname, startOfLine) {
+ var noIndent = UseKludges.doNotIndent.hasOwnProperty(tagname) || (context && context.noIndent);
+ context = {prev: context, name: tagname, indent: indented, startOfLine: startOfLine, noIndent: noIndent};
+ }
+ function popContext() {
+ context = context.prev;
+ }
+ function computeIndentation(baseContext) {
+ return function(nextChars, current) {
+ var context = baseContext;
+ if (context && context.noIndent)
+ return current;
+ if (alignCDATA && /<!\[CDATA\[/.test(nextChars))
+ return 0;
+ if (context && /^<\//.test(nextChars))
+ context = context.prev;
+ while (context && !context.startOfLine)
+ context = context.prev;
+ if (context)
+ return context.indent + indentUnit;
+ else
+ return 0;
+ };
+ }
+
+ function base() {
+ return pass(element, base);
+ }
+ var harmlessTokens = {"xml-text": true, "xml-entity": true, "xml-comment": true, "xml-processing": true};
+ var liquidTokens = {"liquid-punctuation": true, "liquid-variable": true, "liquid-text": true, "liquid-string": true};
+ function element(style, content) {
+ if (content == "<") cont(tagname, attributes, endtag(tokenNr == 1));
+ else if (content == "</") cont(closetagname, expect(">"));
+ else if (style == "xml-cdata") {
+ if (!context || context.name != "!cdata") pushContext("!cdata");
+ if (/\]\]>$/.test(content)) popContext();
+ cont();
+ }
+ else if (harmlessTokens.hasOwnProperty(style)) cont();
+ else if (liquidTokens.hasOwnProperty(style)) cont();
+ else mark("xml-error") || cont();
+ }
+ function tagname(style, content) {
+ if (style == "xml-name") {
+ currentTag = content.toLowerCase();
+ mark("xml-tagname");
+ cont();
+ }
+ else {
+ currentTag = null;
+ pass();
+ }
+ }
+ function closetagname(style, content) {
+ if (style == "xml-name" && context && content.toLowerCase() == context.name) {
+ popContext();
+ mark("xml-tagname");
+ }
+ else {
+ mark("xml-error");
+ }
+ cont();
+ }
+ function endtag(startOfLine) {
+ return function(style, content) {
+ if (content == "/>" || (content == ">" && UseKludges.autoSelfClosers.hasOwnProperty(currentTag))) cont();
+ else if (content == ">") pushContext(currentTag, startOfLine) || cont();
+ else mark("xml-error") || cont(arguments.callee);
+ };
+ }
+ function attributes(style) {
+ if (style == "xml-name") mark("xml-attname") || cont(attribute, attributes);
+ else pass();
+ }
+ function attribute(style, content) {
+ if (content == "=") cont(value);
+ else if (content == ">" || content == "/>") pass(endtag);
+ else pass();
+ }
+ function value(style) {
+ if (style == "xml-attribute") cont(value);
+ else pass();
+ }
+
+ return {
+ indentation: function() {return indented;},
+
+ next: function(){
+ var token = tokens.next();
+ if (token.style == "whitespace" && tokenNr == 0)
+ indented = token.value.length;
+ else
+ tokenNr++;
+ if (token.content == "\n") {
+ indented = tokenNr = 0;
+ token.indentation = computeIndentation(context);
+ }
+
+ if (token.style == "whitespace" || token.type == "xml-comment")
+ return token;
+
+ while(true){
+ consume = marked = false;
+ cc.pop()(token.style, token.content);
+ if (consume){
+ if (marked)
+ token.style = marked;
+ return token;
+ }
+ }
+ },
+
+ copy: function(){
+ var _cc = cc.concat([]), _tokenState = tokens.state, _context = context;
+ var parser = this;
+
+ return function(input){
+ cc = _cc.concat([]);
+ tokenNr = indented = 0;
+ context = _context;
+ tokens = tokenizeXML(input, _tokenState);
+ return parser;
+ };
+ }
+ };
+ }
+
+ return {
+ make: parseXML,
+ electricChars: "/",
+ configure: function(config) {
+ if (config.useHTMLKludges != null)
+ UseKludges = config.useHTMLKludges ? Kludges : NoKludges;
+ if (config.alignCDATA)
+ alignCDATA = config.alignCDATA;
+ }
+ };
+})();
View
285 public/stylesheets/application.css
@@ -0,0 +1,285 @@
+body {
+ margin: 0;
+ font: 0.8em/1.3em "Lucida Grande", Arial, Arial, sans-serif;
+ background: #ededed;
+}
+
+h1 { font-weight: normal; font-size: 24px; }
+h1 a { color: #FFFAD5; text-decoration: none; }
+h2 { font-weight: normal; margin-top: 24px; }
+h3 { margin-top: 24px; }
+
+#header {
+ background: #2d3337 url('../images/shopify-logo.png') 20px 50% no-repeat;
+ padding: 25px 25px 25px 70px;
+ border-top: 5px solid #1f2326;
+ border-bottom: 1px solid #252a2e;
+}
+
+#header h1 { color: #fffad5; }
+
+#login-link {
+ float: right;
+ position: relative;
+ bottom: 43px;
+ right: 15px;
+ color: #ededed;
+}
+
+#login-link a { color: #ebff7c; }
+#login-link a:hover { text-decoration: underline; }
+#login-link a.shop_name { color: inherit; text-decoration: none; }
+#login-link a.shop_name:hover { text-decoration: underline; }
+
+#container {
+ width: 90%;
+ min-width: 800px;
+ margin: 40px auto;
+ background: #fff;
+ border-right: 1px solid #e5e5e5;
+ border-bottom: 1px solid #e5e5e5;
+}
+
+#container h1 { margin: 18px 0 27px 0; }
+
+#main { padding: 18px; }
+
+#tabs {
+ margin: 0;
+ padding: 0;
+ height: 20px;
+ position: absolute;
+ top: 123px;
+}
+
+#tabs li {
+ margin: 0;
+ padding: 0;
+ display: inline;
+ list-style-type: none;
+}
+
+#tabs a:link, #tabs a:visited {
+ float: left;
+ padding: 3px 8px ;
+ margin: 0 10px 4px 0px;
+ text-decoration: none;
+ color: #888;
+ background: #ddd;
+}
+
+#tabs a:link#current, #tabs a:visited#current, #tabs a:hover { color: #000 !important; }
+#tabs a:link#current, #tabs a:visited#current { font-weight: bold; background: #fff; }
+
+a { color: #22658b; }
+a:hover { color: #359cd7; }
+
+dl { margin: 10px 15px; }
+dt { margin: 10px 0; }
+dd { margin: 5px 0 15px 0; }
+dl input { margin: 0 !important; }
+
+code { font-size: 140%; }
+
+/* UTILITY CLASSES */
+
+.clearfix:after {
+ content: ".";
+ display: block;
+ height: 0;
+ clear: both;
+ visibility: hidden;
+}
+
+.clearfix {display: inline-table;}
+
+/* Hides from IE-mac \*/
+* html .clearfix {height: 1%;}
+.clearfix {display: block;}
+/* End hide from IE-mac */
+
+.ta-left { text-align: left; }
+.ta-right { text-align: right; }
+.ta-center { text-align: center; }
+.pl { padding-left: 10px !important; }
+.note { color: #777; font-size: 85%; }
+.highlight { background: #ffc; }
+
+/*
+ * LOGIN / WELCOME
+ */
+
+#left, #right {
+ width: 40%;
+ float: left;
+ margin: 0 2% 30px 2%;
+}
+
+#left { min-width: 390px; }
+
+#logout { float: right; margin: 10px; }
+#logout a { color: #330; }
+
+/*
+ * DASHBOARD
+ */
+
+.order, .product { width: 55%; }
+.product { margin: 10px; }
+
+.product img {
+ margin: 0 10px 0 0;
+ float: left;
+}
+
+.product h4 {
+ margin: 0 0 12px 0;
+ font-size: 14px;
+}
+
+.price {
+ color: #666;
+ font-size: 15px;
+ font-family: Times, "Times New Roman";
+ font-style: italic;
+}
+
+#orders ul {
+ list-style-type: none;
+ padding: 0 0 0 7px;
+}
+
+#orders li { padding: 3px; }
+
+#sidebar {
+ float: right;
+ width: 280px;
+ background: #f5fbfe;
+ border-left: 1px solid #D7E4EA;
+ color: #003366;
+ padding: 0 20px 20px 20px;
+ margin-bottom: 18px;
+}
+
+#sidebar ul {
+ padding-left: 20px;
+ list-style-type: square;
+}
+
+#sidebar li { margin: 8px 0; }
+
+/* STYLE OVERVIEW */
+
+#style-table { margin: 20px 0; }
+#style-table td * { margin: 0; }
+#style-table td { padding: 10px; border-bottom: 1px dotted #e5e5e5; }
+#style-table td:first-child {
+ background:#Fefefe url('../images/box-bg2.gif') repeat-x scroll left bottom;
+}
+/* Flash */
+
+#flasherrors, #flashnotices {
+ background: #faf7ea;
+ border-bottom: 1px solid #e8e6d9;
+ padding: 10px;
+ font-weight: bold;
+ text-align:center;
+}
+
+#flasherrors { color: #6e290b; }
+#flashnotices { color: #549d19; }
+
+/* CLASSES */
+
+.description {
+ margin: 0px 0px 0px 4px;
+ font-weight: normal;
+}
+
+.box {
+ padding: 0;
+ background:#FAFAFA url('../images/box-bg2.gif') repeat-x scroll left top;
+ border:1px solid #CCCCCC;
+}
+
+.wrapper {
+ border:1px solid #FFFFFF;
+ padding: 10px;
+}
+
+.info {
+ padding: 0;
+ margin: 8px auto;
+ background: #009ad6 url('../images/info-bg.gif') top left repeat-x;
+ border: 1px solid #61abda;
+ font: 1.2em/1.7em "Comic Sans MS";
+ color: #fff;
+ height: 85px;
+}
+
+.info code {
+ font-size: 14px;
+ background: none;
+}
+
+.info a { color: #fff; }
+.info a:hover { color: #dcfaff; }
+
+.grey {
+ background: #eee;
+ border: 1px solid #ccc;
+}
+
+.green, .orange, .blue { padding: 10px; }
+h1.green, h2.green, h3.green, h1.orange, h2.orange, h3.orange, h1.blue, h2.blue, h3.blue { padding: 0; }
+
+.green {
+ background: #61b41e;
+ border: 1px solid #60b31d;
+ color: #ddecd0;
+}
+
+h1.green, h2.green, h3.green {
+ color: #6ece21;
+ background: none;
+ border: none;
+}
+
+.orange {
+ background: #ce6e21;
+ border: 1px solid #bc641e;
+ color: #fce0ca;
+ padding: 10px;
+}
+
+h1.orange, h2.orange, h3.orange {
+ color: #ce6e21;
+ background: none;
+ border: none;
+}
+
+.blue {
+ background: #218bce;
+ border: 1px solid #1e80be;
+ color: #d9ecf8;
+ padding: 10px;
+}
+
+h1.blue, h2.blue, h3.blue {
+ color: #218bce;
+ background: none;
+ border: none;
+}
+
+.light {
+ background: #faf7ea;
+ border: 1px solid #e8e6d9;
+ padding: 18px;
+}
+
+.dark {
+ background: #333;
+ border: 1px solid #000;
+ color: #fff;
+ padding: 10px;
+}
View
71 public/stylesheets/liquidcolors.css
@@ -0,0 +1,71 @@
+.editbox {
+ margin: .4em;
+ padding: 0;
+ font-family: monospace;
+ font-size: 10pt;
+ color: black;
+}
+
+.editbox p {
+ margin: 0;
+}
+
+span.xml-tagname {
+ color: #A0B;
+}
+
+span.xml-attribute {
+ color: #281;
+}
+
+span.xml-punctuation {
+ color: black;
+}
+
+span.xml-attname {
+ color: #00F;
+}
+
+span.xml-comment {
+ color: #A70;
+}
+
+span.xml-cdata {
+ color: #48A;
+}
+
+span.xml-processing {
+ color: #999;
+}
+
+span.xml-entity {
+ color: #A22;
+}
+
+span.xml-error {
+ color: #F00;
+}
+
+span.xml-text {
+ color: black;
+}
+
+span.liquid-punctuation {
+ color: pink;
+ background-color: #eee;
+}
+
+span.liquid-text {
+ color: purple;
+ background-color: #eee;
+}
+
+span.liquid-variable {
+ color: magenta;
+ background-color: #eee;
+}
+
+span.liquid-string {
+ color: green;
+ background-color: #eee;
+}

0 comments on commit 109856b

Please sign in to comment.
Something went wrong with that request. Please try again.