Last active
August 29, 2015 13:56
-
-
Save benknight/9011428 to your computer and use it in GitHub Desktop.
ReviewBoard CSS rewrites
This file contains 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
// ==UserScript== | |
// @name Better ReviewBoard styles | |
// @version 1.1 | |
// @description Rewrites some ReviewBoard styles | |
// @match https://reviewboard.yelpcorp.com/* | |
// @copyright 2014 Benjamin Knight <[email protected]> | |
// ==/UserScript== | |
(function () { | |
var cssRewrites = 'button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}html{position:relative;min-height:100%}#container{margin-bottom:120px}body{height:100%;padding:10px;font-family:Helvetica Neue, Lucida Grande, Verdana, sans-serif;font-size:13px;background-attachment:scroll;background-size:100px;background-position:20px calc(100% - 20px)}pre,textarea{font-family:Menlo, monospace;font-size:14px}table.sidebyside{color:rgba(0,0,0,0.8)}table.sidebyside .insert td,table.sidebyside .delete td,table.sidebyside .replace td{outline:1px solid rgba(0,0,0,0.05);outline-offset:-1px}table.sidebyside pre{font-size:13px}#headerbar{height:30px}#headerbar #logo{display:none}#headerbar #title{font-size:20px}#headerbar #title .version{font-size:16px}#headerbar #accountnav{float:right;padding:13px}#headerbar #rbinfo{float:left;padding:0.8em}#headerbar br{display:none}.box-container,#navbar-outer,#accountnav{border:none}#navbar,.box,#dashboard-main{border:1px rgba(0,0,0,0.33) solid}#dashboard-navbar{width:200px}#dashboard-main{border-width:0 0 0 1px;margin-left:200px}.review-request .box-inner{background:#FFFADB !important}#details{background:rgba(0,0,0,0.03)}.marquee-container{position:absolute;bottom:0px;width:100px;height:100px;left:15px}.random-source-code{pointer-events:none;opacity:0;position:fixed;bottom:0;left:140px;height:1000px;color:green;-moz-transition:opacity 0.3s ease;-o-transition:opacity 0.3s ease;-webkit-transition:opacity 0.3s ease;transition:opacity 0.3s ease}.marquee-container:hover .random-source-code{opacity:0.5}'; | |
var randomSourceCode = "from __future__ import absolute_import\nfrom __future__ import print_function\n\nfrom functools import partial\nimport logging\nimport operator\nimport re\n\nimport six\n\nimport scss.config as config\nfrom scss.cssdefs import COLOR_NAMES, is_builtin_css_function, _expr_glob_re, _interpolate_re\nfrom scss.errors import SassError, SassEvaluationError, SassParseError\nfrom scss.rule import Namespace\nfrom scss.types import Boolean, Color, List, Map, Null, Number, String, Undefined, Value\nfrom scss.util import dequote, normalize_var\n\n################################################################################\n# Load C acceleration modules\nScanner = None\ntry:\n from scss._speedups import Scanner\nexcept ImportError:\n from scss._native import Scanner\n\nlog = logging.getLogger(__name__)\n\n\nclass Calculator(object):\n \"\"\"Expression evaluator.\"\"\"\n\n ast_cache = {}\n\n def __init__(self, namespace=None):\n if namespace is None:\n self.namespace = Namespace()\n else:\n self.namespace = namespace\n\n def _pound_substitute(self, result):\n expr = result.group(1)\n value = self.evaluate_expression(expr)\n\n if value is None:\n return self.apply_vars(expr)\n elif value.is_null:\n return \"\"\n else:\n return dequote(value.render())\n\n def do_glob_math(self, cont):\n \"\"\"Performs #{}-interpolation. The result is always treated as a fixed\n syntactic unit and will not be re-evaluated.\n \"\"\"\n # TODO that's a lie! this should be in the parser for most cases.\n cont = str(cont)\n if '#{' not in cont:\n return cont\n cont = _expr_glob_re.sub(self._pound_substitute, cont)\n return cont\n\n def apply_vars(self, cont):\n # TODO this is very complicated. it should go away once everything\n # valid is actually parseable.\n if isinstance(cont, six.string_types) and '$' in cont:\n try:\n # Optimization: the full cont is a variable in the context,\n cont = self.namespace.variable(cont)\n except KeyError:\n # Interpolate variables:\n def _av(m):\n v = None\n n = m.group(2)\n try:\n v = self.namespace.variable(n)\n except KeyError:\n if config.FATAL_UNDEFINED:\n raise SyntaxError(\"Undefined variable: '%s'.\" % n)\n else:\n if config.VERBOSITY > 1:\n log.error(\"Undefined variable '%s'\", n, extra={'stack': True})\n return n\n else:\n if v:\n if not isinstance(v, six.string_types):\n v = v.render()\n # TODO this used to test for _dequote\n if m.group(1):\n v = dequote(v)\n else:\n v = m.group(0)\n return v\n\n cont = _interpolate_re.sub(_av, cont)\n # TODO this is surprising and shouldn't be here\n cont = self.do_glob_math(cont)\n return cont\n\n def calculate(self, _base_str, divide=False):\n better_expr_str = _base_str\n\n better_expr_str = self.do_glob_math(better_expr_str)\n\n better_expr_str = self.evaluate_expression(better_expr_str, divide=divide)\n\n if better_expr_str is None:\n better_expr_str = String.unquoted(self.apply_vars(_base_str))\n\n return better_expr_str\n\n # TODO only used by magic-import...?\n def interpolate(self, var):\n value = self.namespace.variable(var)\n if var != value and isinstance(value, six.string_types):\n _vi = self.evaluate_expression(value)\n if _vi is not None:\n value = _vi\n return value\n\n def evaluate_expression(self, expr, divide=False):\n try:\n ast = self.parse_expression(expr)\n except SassError:\n if config.DEBUG:\n raise\n else:\n return None\n\n try:\n return ast.evaluate(self, divide=divide)\n except Exception as e:\n raise SassEvaluationError(e, expression=expr)\n\n def parse_expression(self, expr, target='goal'):\n if not isinstance(expr, six.string_types):\n raise TypeError(\"Expected string, got %r\" % (expr,))\n\n key = (target, expr)\n if key in self.ast_cache:\n return self.ast_cache[key]\n\n try:\n parser = SassExpression(SassExpressionScanner(expr))\n ast = getattr(parser, target)()\n except SyntaxError as e:\n raise SassParseError(e, expression=expr, expression_pos=parser._char_pos)\n\n self.ast_cache[key] = ast\n return ast\n\n\n# ------------------------------------------------------------------------------\n# Expression classes -- the AST resulting from a parse\n\nclass Expression(object):\n def __repr__(self):\n return '<%s()>' % (self.__class__.__name__)\n\n def evaluate(self, calculator, divide=False):\n \"\"\"Evaluate this AST node, and return a Sass value.\n\n `divide` indicates whether a descendant node representing a division\n should be forcibly treated as a division. See the commentary in\n `BinaryOp`.\n \"\"\"\n raise NotImplementedError\n\n\nclass Parentheses(Expression):\n \"\"\"An expression of the form `(foo)`.\n\n Only exists to force a slash to be interpreted as division when contained\n within parentheses.\n \"\"\"\n def __repr__(self):\n return '<%s(%s)>' % (self.__class__.__name__, repr(self.contents))\n\n def __init__(self, contents):\n self.contents = contents\n\n def evaluate(self, calculator, divide=False):\n return self.contents.evaluate(calculator, divide=True)\n\n\nclass UnaryOp(Expression):\n def __repr__(self):\n return '<%s(%s, %s)>' % (self.__class__.__name__, repr(self.op), repr(self.operand))\n\n def __init__(self, op, operand):\n self.op = op\n self.operand = operand\n\n def evaluate(self, calculator, divide=False):\n return self.op(self.operand.evaluate(calculator, divide=True))\n\n\nclass BinaryOp(Expression):\n def __repr__(self):\n return '<%s(%s, %s, %s)>' % (self.__class__.__name__, repr(self.op), repr(self.left), repr(self.right))\n\n def __init__(self, op, left, right):\n self.op = op\n self.left = left\n self.right = right\n\n def evaluate(self, calculator, divide=False):\n left = self.left.evaluate(calculator, divide=True)\n right = self.right.evaluate(calculator, divide=True)\n\n # Special handling of division: treat it as a literal slash if both\n # operands are literals, there are parentheses, or this is part of a\n # bigger expression.\n # The first condition is covered by the type check. The other two are\n # covered by the `divide` argument: other nodes that perform arithmetic\n # will pass in True, indicating that this should always be a division.\n if (\n self.op is operator.truediv\n and not divide\n and isinstance(self.left, Literal)\n and isinstance(self.right, Literal)\n ):\n return String(left.render() + ' / ' + right.render(), quotes=None)\n\n return self.op(left, right)\n\n\nclass AnyOp(Expression):\n def __repr__(self):\n return '<%s(*%s)>' % (self.__class__.__name__, repr(self.op), repr(self.operands))\n\n def __init__(self, *operands):\n self.operands = operands\n\n def evaluate(self, calculator, divide=False):\n for operand in self.operands:\n value = operand.evaluate(calculator, divide=True)\n if value:\n return value\n return value\n\n\nclass AllOp(Expression):\n def __repr__(self):\n return '<%s(*%s)>' % (self.__class__.__name__, repr(self.operands))\n\n def __init__(self, *operands):\n self.operands = operands\n\n def evaluate(self, calculator, divide=False):\n for operand in self.operands:\n value = operand.evaluate(calculator, divide=True)\n if not value:\n return value\n return value\n\n\nclass NotOp(Expression):\n def __repr__(self):\n return '<%s(%s)>' % (self.__class__.__name__, repr(self.operand))\n\n def __init__(self, operand):\n self.operand = operand\n\n def evaluate(self, calculator, divide=False):\n operand = self.operand.evaluate(calculator, divide=True)\n return Boolean(not(operand))\n\n\nclass CallOp(Expression):\n def __repr__(self):\n return '<%s(%s, %s)>' % (self.__class__.__name__, repr(self.func_name), repr(self.argspec))\n\n def __init__(self, func_name, argspec):\n self.func_name = func_name\n self.argspec = argspec\n\n def evaluate(self, calculator, divide=False):\n # TODO bake this into the context and options \"dicts\", plus library\n func_name = normalize_var(self.func_name)\n\n argspec_node = self.argspec\n\n # Turn the pairs of arg tuples into *args and **kwargs\n # TODO unclear whether this is correct -- how does arg, kwarg, arg\n # work?\n args, kwargs = argspec_node.evaluate_call_args(calculator)\n argspec_len = len(args) + len(kwargs)\n\n # Translate variable names to Python identifiers\n # TODO what about duplicate kw names? should this happen in argspec?\n # how does that affect mixins?\n kwargs = dict(\n (key.lstrip('$').replace('-', '_'), value)\n for key, value in kwargs.items())\n\n # TODO merge this with the library\n funct = None\n try:\n funct = calculator.namespace.function(func_name, argspec_len)\n # @functions take a ns as first arg. TODO: Python functions possibly\n # should too\n if getattr(funct, '__name__', None) == '__call':\n funct = partial(funct, calculator.namespace)\n except KeyError:\n try:\n # DEVIATION: Fall back to single parameter\n funct = calculator.namespace.function(func_name, 1)\n args = [List(args, use_comma=True)]\n except KeyError:\n if not is_builtin_css_function(func_name):\n log.error(\"Function not found: %s:%s\", func_name, argspec_len, extra={'stack': True})\n\n if funct:\n ret = funct(*args, **kwargs)\n if not isinstance(ret, Value):\n raise TypeError(\"Expected Sass type as return value, got %r\" % (ret,))\n return ret\n\n # No matching function found, so render the computed values as a CSS\n # function call. Slurpy arguments are expanded and named arguments are\n # unsupported.\n if kwargs:\n raise TypeError(\"The CSS function %s doesn't support keyword arguments.\" % (func_name,))\n\n # TODO another candidate for a \"function call\" sass type\n rendered_args = [arg.render() for arg in args]\n\n return String(\n u\"%s(%s)\" % (func_name, u\", \".join(rendered_args)),\n quotes=None)\n\n\nclass Literal(Expression):\n def __repr__(self):\n return '<%s(%s)>' % (self.__class__.__name__, repr(self.value))\n\n def __init__(self, value):\n if isinstance(value, Undefined) and config.FATAL_UNDEFINED:\n raise SyntaxError(\"Undefined literal.\")\n else:\n self.value = value\n\n def evaluate(self, calculator, divide=False):\n return self.value\n\n\nclass Variable(Expression):\n def __repr__(self):\n return '<%s(%s)>' % (self.__class__.__name__, repr(self.name))\n\n def __init__(self, name):\n self.name = name\n\n def evaluate(self, calculator, divide=False):\n try:\n value = calculator.namespace.variable(self.name)\n except KeyError:\n if config.FATAL_UNDEFINED:\n raise SyntaxError(\"Undefined variable: '%s'.\" % self.name)\n else:\n if config.VERBOSITY > 1:\n log.error(\"Undefined variable '%s'\", self.name, extra={'stack': True})\n return Undefined()\n else:\n if isinstance(value, six.string_types):\n evald = calculator.evaluate_expression(value)\n if evald is not None:\n return evald\n return value\n\n\nclass ListLiteral(Expression):\n def __repr__(self):\n return '<%s(%s, comma=%s)>' % (self.__class__.__name__, repr(self.items), repr(self.comma))\n\n def __init__(self, items, comma=True):\n self.items = items\n self.comma = comma\n\n def evaluate(self, calculator, divide=False):\n items = [item.evaluate(calculator, divide=divide) for item in self.items]\n\n # Whether this is a \"plain\" literal matters for null removal: nulls are\n # left alone if this is a completely vanilla CSS property\n is_literal = True\n if divide:\n # TODO sort of overloading \"divide\" here... rename i think\n is_literal = False\n elif not all(isinstance(item, Literal) for item in self.items):\n is_literal = False\n\n return List(items, use_comma=self.comma, is_literal=is_literal)\n\n\nclass MapLiteral(Expression):\n def __repr__(self):\n return '<%s(%s)>' % (self.__class__.__name__, repr(self.pairs))\n\n def __init__(self, pairs):\n self.pairs = tuple((var, value) for var, value in pairs if value is not None)\n\n def evaluate(self, calculator, divide=False):\n scss_pairs = []\n for key, value in self.pairs:\n scss_pairs.append((\n key.evaluate(calculator),\n value.evaluate(calculator),\n ))\n\n return Map(scss_pairs)\n\n\nclass ArgspecLiteral(Expression):\n \"\"\"Contains pairs of argument names and values, as parsed from a function\n definition or function call.\n\n Note that the semantics are somewhat ambiguous. Consider parsing:\n\n $foo, $bar: 3\n\n If this appeared in a function call, $foo would refer to a value; if it\n appeared in a function definition, $foo would refer to an existing\n variable. This it's up to the caller to use the right iteration function.\n \"\"\"\n def __repr__(self):\n return '<%s(%s)>' % (self.__class__.__name__, repr(self.argpairs))\n\n def __init__(self, argpairs, slurp=None):\n # argpairs is a list of 2-tuples, parsed as though this were a function\n # call, so (variable name as string or None, default value as AST\n # node).\n # slurp is the name of a variable to receive slurpy arguments.\n self.argpairs = tuple(argpairs)\n if slurp is all:\n # DEVIATION: special syntax to allow injecting arbitrary arguments\n # from the caller to the callee\n self.inject = True\n self.slurp = None\n elif slurp:\n self.inject = False\n self.slurp = Variable(slurp)\n else:\n self.inject = False\n self.slurp = None\n\n def iter_list_argspec(self):\n yield None, ListLiteral(zip(*self.argpairs)[1])\n\n def iter_def_argspec(self):\n \"\"\"Interpreting this literal as a function definition, yields pairs of\n (variable name as a string, default value as an AST node or None).\n \"\"\"\n started_kwargs = False\n seen_vars = set()\n\n for var, value in self.argpairs:\n if var is None:\n # value is actually the name\n var = value\n value = None\n\n if started_kwargs:\n raise SyntaxError(\n \"Required argument %r must precede optional arguments\"\n % (var.name,))\n\n else:\n started_kwargs = True\n\n if not isinstance(var, Variable):\n raise SyntaxError(\"Expected variable name, got %r\" % (var,))\n\n if var.name in seen_vars:\n raise SyntaxError(\"Duplicate argument %r\" % (var.name,))\n seen_vars.add(var.name)\n\n yield var.name, value\n\n def evaluate_call_args(self, calculator):\n \"\"\"Interpreting this literal as a function call, return a 2-tuple of\n ``(args, kwargs)``.\n \"\"\"\n args = []\n kwargs = {}\n for var_node, value_node in self.argpairs:\n value = value_node.evaluate(calculator, divide=True)\n if var_node is None:\n # Positional\n args.append(value)\n else:\n # Named\n if not isinstance(var_node, Variable):\n raise SyntaxError(\"Expected variable name, got %r\" % (var_node,))\n kwargs[var_node.name] = value\n\n # Slurpy arguments go on the end of the args\n if self.slurp:\n args.extend(self.slurp.evaluate(calculator, divide=True))\n\n return args, kwargs\n\n\ndef parse_bareword(word):\n if word in COLOR_NAMES:\n return Color.from_name(word)\n elif word == 'null':\n return Null()\n elif word == 'undefined':\n return Undefined()\n elif word == 'true':\n return Boolean(True)\n elif word == 'false':\n return Boolean(False)\n else:\n return String(word, quotes=None)\n\n\nclass Parser(object):\n def __init__(self, scanner):\n self._scanner = scanner\n self._pos = 0\n self._char_pos = 0\n\n def reset(self, input):\n self._scanner.reset(input)\n self._pos = 0\n self._char_pos = 0\n\n def _peek(self, types):\n \"\"\"\n Returns the token type for lookahead; if there are any args\n then the list of args is the set of token types to allow\n \"\"\"\n try:\n tok = self._scanner.token(self._pos, types)\n return tok[2]\n except SyntaxError:\n return None\n\n def _scan(self, type):\n \"\"\"\n Returns the matched text, and moves to the next token\n \"\"\"\n tok = self._scanner.token(self._pos, set([type]))\n self._char_pos = tok[0]\n if tok[2] != type:\n raise SyntaxError(\"SyntaxError[@ char %s: %s]\" % (repr(tok[0]), \"Trying to find \" + type))\n self._pos += 1\n return tok[3]\n\n\n################################################################################\n## Grammar compiled using Yapps:\n\nclass SassExpressionScanner(Scanner):\n patterns = None\n _patterns = [\n ('\":\"', ':'),\n ('\",\"', ','),\n ('[ \r\t\n]+', '[ \r\t\n]+'),\n ('LPAR', '\\(|\\['),\n ('RPAR', '\\)|\\]'),\n ('END', '$'),\n ('MUL', '[*]'),\n ('DIV', '/'),\n ('ADD', '[+]'),\n ('SUB', '-\\s'),\n ('SIGN', '-(?![a-zA-Z_])'),\n ('AND', '(?<![-\\w])and(?![-\\w])'),\n ('OR', '(?<![-\\w])or(?![-\\w])'),\n ('NOT', '(?<![-\\w])not(?![-\\w])'),\n ('NE', '!='),\n ('INV', '!'),\n ('EQ', '=='),\n ('LE', '<='),\n ('GE', '>='),\n ('LT', '<'),\n ('GT', '>'),\n ('DOTDOTDOT', '[.]{3}'),\n ('KWSTR', \"'[^']*'(?=\\s*:)\"),\n ('STR', \"'[^']*'\"),\n ('KWQSTR', '\"[^\"]*\"(?=\\s*:)'),\n ('QSTR', '\"[^\"]*\"'),\n ('UNITS', '(?<!\\s)(?:[a-zA-Z]+|%)(?![-\\w])'),\n ('KWNUM', '(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?=\\s*:)'),\n ('NUM', '(?:\\d+(?:\\.\\d*)?|\\.\\d+)'),\n ('KWCOLOR', '#(?:[a-fA-F0-9]{6}|[a-fA-F0-9]{3})(?![a-fA-F0-9])(?=\\s*:)'),\n ('COLOR', '#(?:[a-fA-F0-9]{6}|[a-fA-F0-9]{3})(?![a-fA-F0-9])'),\n ('KWVAR', '\\$[-a-zA-Z0-9_]+(?=\\s*:)'),\n ('SLURPYVAR', '\\$[-a-zA-Z0-9_]+(?=[.][.][.])'),\n ('VAR', '\\$[-a-zA-Z0-9_]+'),\n ('FNCT', '[-a-zA-Z_][-a-zA-Z0-9_]*(?=\\()'),\n ('KWID', '[-a-zA-Z_][-a-zA-Z0-9_]*(?=\\s*:)'),\n ('ID', '[-a-zA-Z_][-a-zA-Z0-9_]*'),\n ('BANG_IMPORTANT', '!important'),\n ]\n\n def __init__(self, input=None):\n if hasattr(self, 'setup_patterns'):\n self.setup_patterns(self._patterns)\n elif self.patterns is None:\n self.__class__.patterns = []\n for t, p in self._patterns:\n self.patterns.append((t, re.compile(p)))\n super(SassExpressionScanner, self).__init__(None, ['[ \r\t\n]+'], input)\n\n\nclass SassExpression(Parser):\n def goal(self):\n expr_lst = self.expr_lst()\n END = self._scan('END')\n return expr_lst\n\n def goal_argspec(self):\n argspec = self.argspec()\n END = self._scan('END')\n return argspec\n\n def argspec(self):\n _token_ = self._peek(self.argspec_rsts)\n if _token_ not in self.argspec_chks:\n if self._peek(self.argspec_rsts_) not in self.argspec_chks_:\n argspec_items = self.argspec_items()\n args, slurpy = argspec_items\n return ArgspecLiteral(args, slurp=slurpy)\n return ArgspecLiteral([])\n elif _token_ == 'SLURPYVAR':\n SLURPYVAR = self._scan('SLURPYVAR')\n DOTDOTDOT = self._scan('DOTDOTDOT')\n return ArgspecLiteral([], slurp=SLURPYVAR)\n else: # == 'DOTDOTDOT'\n DOTDOTDOT = self._scan('DOTDOTDOT')\n return ArgspecLiteral([], slurp=all)\n\n def argspec_items(self):\n slurpy = None\n argspec_item = self.argspec_item()\n args = [argspec_item]\n if self._peek(self.argspec_items_rsts) == '\",\"':\n self._scan('\",\"')\n if self._peek(self.argspec_items_rsts_) not in self.argspec_chks_:\n _token_ = self._peek(self.argspec_items_rsts__)\n if _token_ == 'SLURPYVAR':\n SLURPYVAR = self._scan('SLURPYVAR')\n DOTDOTDOT = self._scan('DOTDOTDOT')\n slurpy = SLURPYVAR\n elif _token_ == 'DOTDOTDOT':\n DOTDOTDOT = self._scan('DOTDOTDOT')\n slurpy = all\n else: # in self.argspec_items_chks\n argspec_items = self.argspec_items()\n more_args, slurpy = argspec_items\n args.extend(more_args)\n return args, slurpy\n\n def argspec_item(self):\n _token_ = self._peek(self.argspec_items_chks)\n if _token_ == 'KWVAR':\n KWVAR = self._scan('KWVAR')\n self._scan('\":\"')\n expr_slst = self.expr_slst()\n return (Variable(KWVAR), expr_slst)\n else: # in self.argspec_item_chks\n expr_slst = self.expr_slst()\n return (None, expr_slst)\n\n def expr_map(self):\n map_item = self.map_item()\n pairs = [map_item]\n while self._peek(self.expr_map_rsts) == '\",\"':\n self._scan('\",\"')\n map_item = (None, None)\n if self._peek(self.expr_map_rsts_) not in self.expr_map_rsts:\n map_item = self.map_item()\n pairs.append(map_item)\n return MapLiteral(pairs)\n\n def map_item(self):\n kwatom = self.kwatom()\n self._scan('\":\"')\n expr_slst = self.expr_slst()\n return (kwatom, expr_slst)\n\n def expr_lst(self):\n expr_slst = self.expr_slst()\n v = [expr_slst]\n while self._peek(self.argspec_items_rsts) == '\",\"':\n self._scan('\",\"')\n expr_slst = self.expr_slst()\n v.append(expr_slst)\n return ListLiteral(v) if len(v) > 1 else v[0]\n\n def expr_slst(self):\n or_expr = self.or_expr()\n v = [or_expr]\n while self._peek(self.expr_slst_rsts) not in self.argspec_items_rsts:\n or_expr = self.or_expr()\n v.append(or_expr)\n return ListLiteral(v, comma=False) if len(v) > 1 else v[0]\n\n def or_expr(self):\n and_expr = self.and_expr()\n v = and_expr\n while self._peek(self.or_expr_rsts) == 'OR':\n OR = self._scan('OR')\n and_expr = self.and_expr()\n v = AnyOp(v, and_expr)\n return v\n\n def and_expr(self):\n not_expr = self.not_expr()\n v = not_expr\n while self._peek(self.and_expr_rsts) == 'AND':\n AND = self._scan('AND')\n not_expr = self.not_expr()\n v = AllOp(v, not_expr)\n return v\n\n def not_expr(self):\n _token_ = self._peek(self.argspec_item_chks)\n if _token_ != 'NOT':\n comparison = self.comparison()\n return comparison\n else: # == 'NOT'\n NOT = self._scan('NOT')\n not_expr = self.not_expr()\n return NotOp(not_expr)\n\n def comparison(self):\n a_expr = self.a_expr()\n v = a_expr\n while self._peek(self.comparison_rsts) in self.comparison_chks:\n _token_ = self._peek(self.comparison_chks)\n if _token_ == 'LT':\n LT = self._scan('LT')\n a_expr = self.a_expr()\n v = BinaryOp(operator.lt, v, a_expr)\n elif _token_ == 'GT':\n GT = self._scan('GT')\n a_expr = self.a_expr()\n v = BinaryOp(operator.gt, v, a_expr)\n elif _token_ == 'LE':\n LE = self._scan('LE')\n a_expr = self.a_expr()\n v = BinaryOp(operator.le, v, a_expr)\n elif _token_ == 'GE':\n GE = self._scan('GE')\n a_expr = self.a_expr()\n v = BinaryOp(operator.ge, v, a_expr)\n elif _token_ == 'EQ':\n EQ = self._scan('EQ')\n a_expr = self.a_expr()\n v = BinaryOp(operator.eq, v, a_expr)\n else: # == 'NE'\n NE = self._scan('NE')\n a_expr = self.a_expr()\n v = BinaryOp(operator.ne, v, a_expr)\n return v\n\n def a_expr(self):\n m_expr = self.m_expr()\n v = m_expr\n while self._peek(self.a_expr_rsts) in self.a_expr_chks:\n _token_ = self._peek(self.a_expr_chks)\n if _token_ == 'ADD':\n ADD = self._scan('ADD')\n m_expr = self.m_expr()\n v = BinaryOp(operator.add, v, m_expr)\n else: # == 'SUB'\n SUB = self._scan('SUB')\n m_expr = self.m_expr()\n v = BinaryOp(operator.sub, v, m_expr)\n return v\n\n def m_expr(self):\n u_expr = self.u_expr()\n v = u_expr\n while self._peek(self.m_expr_rsts) in self.m_expr_chks:\n _token_ = self._peek(self.m_expr_chks)\n if _token_ == 'MUL':\n MUL = self._scan('MUL')\n u_expr = self.u_expr()\n v = BinaryOp(operator.mul, v, u_expr)\n else: # == 'DIV'\n DIV = self._scan('DIV')\n u_expr = self.u_expr()\n v = BinaryOp(operator.truediv, v, u_expr)\n return v\n\n def u_expr(self):\n _token_ = self._peek(self.u_expr_rsts)\n if _token_ == 'SIGN':\n SIGN = self._scan('SIGN')\n u_expr = self.u_expr()\n return UnaryOp(operator.neg, u_expr)\n elif _token_ == 'ADD':\n ADD = self._scan('ADD')\n u_expr = self.u_expr()\n return UnaryOp(operator.pos, u_expr)\n else: # in self.u_expr_chks\n atom = self.atom()\n return atom\n\n def atom(self):\n _token_ = self._peek(self.u_expr_chks)\n if _token_ == 'LPAR':\n LPAR = self._scan('LPAR')\n _token_ = self._peek(self.atom_rsts)\n if _token_ not in self.argspec_item_chks:\n expr_map = self.expr_map()\n v = expr_map\n else: # in self.argspec_item_chks\n expr_lst = self.expr_lst()\n v = expr_lst\n RPAR = self._scan('RPAR')\n return Parentheses(v)\n elif _token_ == 'FNCT':\n FNCT = self._scan('FNCT')\n LPAR = self._scan('LPAR')\n argspec = self.argspec()\n RPAR = self._scan('RPAR')\n return CallOp(FNCT, argspec)\n elif _token_ == 'BANG_IMPORTANT':\n BANG_IMPORTANT = self._scan('BANG_IMPORTANT')\n return Literal(String(BANG_IMPORTANT, quotes=None))\n elif _token_ == 'ID':\n ID = self._scan('ID')\n return Literal(parse_bareword(ID))\n elif _token_ == 'NUM':\n NUM = self._scan('NUM')\n UNITS = None\n if self._peek(self.atom_rsts_) == 'UNITS':\n UNITS = self._scan('UNITS')\n return Literal(Number(float(NUM), unit=UNITS))\n elif _token_ == 'STR':\n STR = self._scan('STR')\n return Literal(String(STR[1:-1], quotes=\"'\"))\n elif _token_ == 'QSTR':\n QSTR = self._scan('QSTR')\n return Literal(String(QSTR[1:-1], quotes='\"'))\n elif _token_ == 'COLOR':\n COLOR = self._scan('COLOR')\n return Literal(Color.from_hex(COLOR, literal=True))\n else: # == 'VAR'\n VAR = self._scan('VAR')\n return Variable(VAR)\n\n def kwatom(self):\n _token_ = self._peek(self.kwatom_rsts)\n if _token_ == '\":\"':\n pass\n elif _token_ == 'KWID':\n KWID = self._scan('KWID')\n return Literal(parse_bareword(KWID))\n elif _token_ == 'KWNUM':\n KWNUM = self._scan('KWNUM')\n UNITS = None\n if self._peek(self.kwatom_rsts_) == 'UNITS':\n UNITS = self._scan('UNITS')\n return Literal(Number(float(KWNUM), unit=UNITS))\n elif _token_ == 'KWSTR':\n KWSTR = self._scan('KWSTR')\n return Literal(String(KWSTR[1:-1], quotes=\"'\"))\n elif _token_ == 'KWQSTR':\n KWQSTR = self._scan('KWQSTR')\n return Literal(String(KWQSTR[1:-1], quotes='\"'))\n elif _token_ == 'KWCOLOR':\n KWCOLOR = self._scan('KWCOLOR')\n return Literal(Color.from_hex(COLOR, literal=True))\n else: # == 'KWVAR'\n KWVAR = self._scan('KWVAR')\n return Variable(KWVAR)\n\n u_expr_chks = set(['LPAR', 'COLOR', 'QSTR', 'NUM', 'FNCT', 'STR', 'VAR', 'BANG_IMPORTANT', 'ID'])\n m_expr_rsts = set(['LPAR', 'SUB', 'QSTR', 'RPAR', 'MUL', 'DIV', 'BANG_IMPORTANT', 'LE', 'COLOR', 'NE', 'LT', 'NUM', 'GT', 'END', 'SIGN', 'GE', 'FNCT', 'STR', 'VAR', 'EQ', 'ID', 'AND', 'ADD', 'NOT', 'OR', '\",\"'])\n argspec_items_rsts = set(['RPAR', 'END', '\",\"'])\n expr_map_rsts = set(['RPAR', '\",\"'])\n argspec_items_rsts__ = set(['KWVAR', 'LPAR', 'QSTR', 'SLURPYVAR', 'COLOR', 'DOTDOTDOT', 'SIGN', 'VAR', 'ADD', 'NUM', 'FNCT', 'STR', 'NOT', 'BANG_IMPORTANT', 'ID'])\n kwatom_rsts = set(['KWVAR', 'KWID', 'KWSTR', 'KWQSTR', 'KWCOLOR', '\":\"', 'KWNUM'])\n argspec_item_chks = set(['LPAR', 'COLOR', 'QSTR', 'SIGN', 'VAR', 'ADD', 'NUM', 'FNCT', 'STR', 'NOT', 'BANG_IMPORTANT', 'ID'])\n a_expr_chks = set(['ADD', 'SUB'])\n expr_slst_rsts = set(['LPAR', 'END', 'COLOR', 'QSTR', 'SIGN', 'VAR', 'ADD', 'NUM', 'RPAR', 'FNCT', 'STR', 'NOT', 'BANG_IMPORTANT', 'ID', '\",\"'])\n or_expr_rsts = set(['LPAR', 'END', 'COLOR', 'QSTR', 'SIGN', 'VAR', 'ADD', 'NUM', 'RPAR', 'FNCT', 'STR', 'NOT', 'ID', 'BANG_IMPORTANT', 'OR', '\",\"'])\n and_expr_rsts = set(['AND', 'LPAR', 'END', 'COLOR', 'QSTR', 'SIGN', 'VAR', 'ADD', 'NUM', 'RPAR', 'FNCT', 'STR', 'NOT', 'ID', 'BANG_IMPORTANT', 'OR', '\",\"'])\n comparison_rsts = set(['LPAR', 'QSTR', 'RPAR', 'BANG_IMPORTANT', 'LE', 'COLOR', 'NE', 'LT', 'NUM', 'GT', 'END', 'SIGN', 'ADD', 'FNCT', 'STR', 'VAR', 'EQ', 'ID', 'AND', 'GE', 'NOT', 'OR', '\",\"'])\n argspec_chks = set(['DOTDOTDOT', 'SLURPYVAR'])\n atom_rsts_ = set(['LPAR', 'SUB', 'QSTR', 'RPAR', 'VAR', 'MUL', 'DIV', 'BANG_IMPORTANT', 'LE', 'COLOR', 'NE', 'LT', 'NUM', 'GT', 'END', 'SIGN', 'GE', 'FNCT', 'STR', 'UNITS', 'EQ', 'ID', 'AND', 'ADD', 'NOT', 'OR', '\",\"'])\n expr_map_rsts_ = set(['KWVAR', 'KWID', 'KWSTR', 'KWQSTR', 'RPAR', 'KWCOLOR', '\":\"', 'KWNUM', '\",\"'])\n u_expr_rsts = set(['LPAR', 'COLOR', 'QSTR', 'SIGN', 'ADD', 'NUM', 'FNCT', 'STR', 'VAR', 'BANG_IMPORTANT', 'ID'])\n comparison_chks = set(['GT', 'GE', 'NE', 'LT', 'LE', 'EQ'])\n argspec_items_rsts_ = set(['KWVAR', 'LPAR', 'QSTR', 'END', 'SLURPYVAR', 'COLOR', 'DOTDOTDOT', 'SIGN', 'VAR', 'ADD', 'NUM', 'RPAR', 'FNCT', 'STR', 'NOT', 'BANG_IMPORTANT', 'ID'])\n a_expr_rsts = set(['LPAR', 'SUB', 'QSTR', 'RPAR', 'BANG_IMPORTANT', 'LE', 'COLOR', 'NE', 'LT', 'NUM', 'GT', 'END', 'SIGN', 'GE', 'FNCT', 'STR', 'VAR', 'EQ', 'ID', 'AND', 'ADD', 'NOT', 'OR', '\",\"'])\n m_expr_chks = set(['MUL', 'DIV'])\n kwatom_rsts_ = set(['UNITS', '\":\"'])\n argspec_items_chks = set(['KWVAR', 'LPAR', 'COLOR', 'QSTR', 'SIGN', 'VAR', 'ADD', 'NUM', 'FNCT', 'STR', 'NOT', 'BANG_IMPORTANT', 'ID'])\n argspec_rsts = set(['KWVAR', 'LPAR', 'BANG_IMPORTANT', 'END', 'SLURPYVAR', 'COLOR', 'DOTDOTDOT', 'RPAR', 'VAR', 'ADD', 'NUM', 'FNCT', 'STR', 'NOT', 'QSTR', 'SIGN', 'ID'])\n atom_rsts = set(['KWVAR', 'KWID', 'KWSTR', 'BANG_IMPORTANT', 'LPAR', 'COLOR', 'KWQSTR', 'SIGN', 'KWCOLOR', 'VAR', 'ADD', 'NUM', '\":\"', 'STR', 'NOT', 'QSTR', 'KWNUM', 'ID', 'FNCT'])\n argspec_chks_ = set(['END', 'RPAR'])\n argspec_rsts_ = set(['KWVAR', 'LPAR', 'BANG_IMPORTANT', 'END', 'COLOR', 'QSTR', 'SIGN', 'VAR', 'ADD', 'NUM', 'FNCT', 'STR', 'NOT', 'RPAR', 'ID'])\n\n\n### Grammar ends.\n################################################################################\n\n__all__ = ('Calculator',)"; | |
var style = document.createElement('style'); | |
style.innerHTML = cssRewrites; | |
document.head.appendChild(style); | |
var p = document.createElement('pre'); | |
p.innerHTML = randomSourceCode; | |
var m = document.createElement('marquee'); | |
m.classList.add('random-source-code'); | |
m.setAttribute('direction', 'up'); | |
m.setAttribute('behavior', 'scroll'); | |
m.setAttribute('scrollamount', '15'); | |
m.appendChild(p); | |
var container = document.createElement('div'); | |
container.classList.add('marquee-container'); | |
container.appendChild(m); | |
document.body.appendChild(container); | |
})(); |
This file contains 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
// ---- | |
// Sass (v3.3.4) | |
// Compass (v1.0.0.alpha.18) | |
// ---- | |
@import "compass/css3/transition"; | |
/** Stuff from normalize.css */ | |
button, | |
input, | |
optgroup, | |
select, | |
textarea { | |
color: inherit; | |
font: inherit; | |
margin: 0; | |
} | |
button, | |
html input[type="button"], | |
input[type="reset"], | |
input[type="submit"] { | |
-webkit-appearance: button; | |
cursor: pointer; | |
} | |
/** Base rewrites */ | |
$dashboard-sidebar-width: 200px; | |
html { | |
position: relative; | |
min-height: 100%; | |
} | |
#container { | |
margin-bottom: 120px; | |
} | |
body { | |
height: 100%; | |
padding: 10px; | |
font-family: Helvetica Neue, Lucida Grande, Verdana, sans-serif; | |
font-size: 13px; | |
background-attachment: scroll; | |
background-size: 100px; | |
background-position: 20px calc(100% - 20px); | |
} | |
pre, | |
textarea { | |
font-family: Menlo, monospace; | |
font-size: 14px; | |
} | |
/** | |
* Diff styles | |
* 1. Show a border around whole lines. | |
*/ | |
table.sidebyside { | |
color: rgba(0, 0, 0, 0.8); | |
.insert, | |
.delete, | |
.replace { | |
td { | |
outline: 1px solid rgba(0, 0, 0, 0.05); // 1 | |
outline-offset: -1px; | |
} | |
} | |
pre { | |
font-size: 13px; | |
} | |
} | |
/** | |
* Header Bar styles | |
* Slim down the header to make more content show above the fold. | |
*/ | |
#headerbar { | |
height: 30px; | |
#logo { | |
display: none; | |
} | |
#title { | |
font-size: 20px; | |
.version { | |
font-size: 16px; | |
} | |
} | |
#accountnav { | |
float: right; | |
padding: 13px; | |
} | |
#rbinfo { | |
float: left; | |
padding: 0.8em; | |
} | |
br { | |
display: none; | |
} | |
} | |
.box-container, | |
#navbar-outer, | |
#accountnav { | |
border: none; | |
} | |
#navbar, | |
.box, | |
#dashboard-main { | |
border: 1px rgba(0, 0, 0, 0.33) solid | |
} | |
#dashboard-navbar { | |
width: $dashboard-sidebar-width; | |
} | |
#dashboard-main { | |
border-width: 0 0 0 1px; | |
margin-left: $dashboard-sidebar-width; | |
} | |
.review-request .box-inner { | |
background: #FFFADB !important; | |
} | |
#details { | |
background: rgba(0, 0, 0, 0.03) | |
} | |
/** The "Easter Egg" hehe */ | |
.marquee-container { | |
position: absolute; | |
bottom: 0px; | |
width: 100px; | |
height: 100px; | |
left: 15px; | |
} | |
.random-source-code { | |
pointer-events: none; | |
opacity: 0; | |
position: fixed; | |
bottom: 0; | |
left: 140px; | |
height: 1000px; | |
color: green; | |
@include transition(opacity 0.3s ease); | |
.marquee-container:hover & { | |
opacity: 0.5; | |
} | |
} |
This file contains 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
button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}html{position:relative;min-height:100%}#container{margin-bottom:120px}body{height:100%;padding:10px;font-family:Helvetica Neue, Lucida Grande, Verdana, sans-serif;font-size:13px;background-attachment:scroll;background-size:100px;background-position:20px calc(100% - 20px)}pre,textarea{font-family:Menlo, monospace;font-size:14px}table.sidebyside{color:rgba(0,0,0,0.8)}table.sidebyside .insert td,table.sidebyside .delete td,table.sidebyside .replace td{outline:1px solid rgba(0,0,0,0.05);outline-offset:-1px}table.sidebyside pre{font-size:13px}#headerbar{height:30px}#headerbar #logo{display:none}#headerbar #title{font-size:20px}#headerbar #title .version{font-size:16px}#headerbar #accountnav{float:right;padding:13px}#headerbar #rbinfo{float:left;padding:0.8em}#headerbar br{display:none}.box-container,#navbar-outer,#accountnav{border:none}#navbar,.box,#dashboard-main{border:1px rgba(0,0,0,0.33) solid}#dashboard-navbar{width:200px}#dashboard-main{border-width:0 0 0 1px;margin-left:200px}.review-request .box-inner{background:#FFFADB !important}#details{background:rgba(0,0,0,0.03)}.marquee-container{position:absolute;bottom:0px;width:100px;height:100px;left:15px}.random-source-code{pointer-events:none;opacity:0;position:fixed;bottom:0;left:140px;height:1000px;color:green;-moz-transition:opacity 0.3s ease;-o-transition:opacity 0.3s ease;-webkit-transition:opacity 0.3s ease;transition:opacity 0.3s ease}.marquee-container:hover .random-source-code{opacity:0.5} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment