Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3268)

Unified Diff: client/layout/GridLayoutParser.dart

Issue 9382027: Move client/{base, observable, layout, touch, util, view} to samples/ui_lib . (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « client/layout/GridLayoutParams.dart ('k') | client/layout/GridTracks.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: client/layout/GridLayoutParser.dart
===================================================================
--- client/layout/GridLayoutParser.dart (revision 4144)
+++ client/layout/GridLayoutParser.dart (working copy)
@@ -1,486 +0,0 @@
-// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/**
- * Base class for simple recursive descent parsers.
- * Handles the lower level stuff, i.e. what a scanner/tokenizer would do.
- */
-class _Parser {
- static final WHITESPACE = ' \r\n\t';
-
- // TODO(jmesserly): shouldn't need this optimization, but dart_json parser
- // found that they needed this.
- static final A_BIG = 65; // 'A'.charCodeAt(0)
- static final Z_BIG = 90; // 'Z'.charCodeAt(0)
- static final A_SMALL = 97; // 'a'.charCodeAt(0)
- static final Z_SMALL = 122; // 'z'.charCodeAt(0)
- static final TAB = 9; // '\t'.charCodeAt(0)
- static final NEW_LINE = 10; // '\n'.charCodeAt(0)
- static final LINE_FEED = 13; // '\r'.charCodeAt(0)
- static final SPACE = 32; // ' '.charCodeAt(0)
- static final ZERO = 48; // '0'.charCodeAt(0)
- static final NINE = 57; // '9'.charCodeAt(0)
- static final DOT = 46; // '.'.charCodeAt(0)
- static final R_PAREN = 41; // ')'.charCodeAt(0)
-
- final String _src;
- int _offset;
-
- // TODO(jmesserly): should be this._offset = 0, see bug 5332175.
- _Parser(this._src) : _offset = 0;
-
- // TODO(jmesserly): these should exist in the standard lib.
- // I took this from dart_json.dart
- static bool _isWhitespace(int c) {
- switch (c) {
- case SPACE:
- case TAB:
- case NEW_LINE:
- case LINE_FEED:
- return true;
- }
- return false;
- }
-
- static bool _isDigit(int c) {
- return (ZERO <= c) && (c <= NINE);
- }
-
- static bool _isLetter(int c) {
- return (A_SMALL <= c) && (c <= Z_SMALL) || (A_BIG <= c) && (c <= Z_BIG);
- }
-
- void _error(String msg) {
- throw new SyntaxErrorException(msg, _src, _offset);
- }
-
- int get length() => _src.length;
-
- int get remaining() => _src.length - _offset;
-
- int _peekChar() => _src.charCodeAt(_offset);
-
- bool get endOfInput() => _offset >= _src.length;
-
- bool _maybeEatWhitespace() {
- int start = _offset;
- while (_offset < length && _isWhitespace(_peekChar())) {
- _offset++;
- }
- return _offset != start;
- }
-
- bool _maybeEatMultiLineComment() {
- if (_maybeEat('/*', /*eatWhitespace:*/false)) {
- while (!_maybeEat('*/', /*eatWhitespace:*/false)) {
- if (_offset >= length) {
- _error('expected */');
- }
- _offset++;
- }
- return true;
- }
- return false;
- }
-
- void _maybeEatWhitespaceOrComments() {
- while (_maybeEatWhitespace() || _maybeEatMultiLineComment()) {}
- }
-
- void _eatEnd() {
- _maybeEatWhitespaceOrComments();
- if (!endOfInput) {
- _error('expected end of input');
- }
- }
-
- bool _maybeEat(String value, [bool eatWhitespace = true]) {
- if (eatWhitespace) {
- _maybeEatWhitespaceOrComments();
- }
- if (remaining < value.length) {
- return false;
- }
- for (int i = 0; i < value.length; i++) {
- if (_src[_offset + i] != value[i]) {
- return false;
- }
- }
-
- // If we're eating something that's like a word, make sure
- // it's not followed by more characters.
- // This is ugly. Proper tokenization would make this cleaner.
- if (_isLetter(value.charCodeAt(value.length - 1))) {
- int i = _offset + value.length;
- if (i < _src.length && _isLetter(_src.charCodeAt(i))) {
- return false;
- }
- }
-
- _offset += value.length;
- return true;
- }
-
- void _eat(String value, [bool eatWhitespace = true]) {
- if (!_maybeEat(value)) {
- _error('expected "$value"');
- }
- }
-
- String _maybeEatString() {
- // TODO(jmesserly): make this match CSS string parsing
- String quote = "'";
- if (!_maybeEat(quote)) {
- quote = '"';
- if (!_maybeEat(quote)) {
- return null;
- }
- }
-
- bool hasEscape = false;
- int start = _offset;
- while (!_maybeEat(quote)) {
- if (endOfInput) {
- _error('expected "$quote"');
- }
- if (_maybeEat('\\')) {
- hasEscape = true;
- }
- _offset++;
- }
- String result = _src.substring(start, _offset - 1);
- if (hasEscape) {
- // TODO(jmesserly): more escape sequences
- result = result.replaceFirst('\\', '');
- }
- return result;
- }
-
- /** Eats something like a keyword. */
- String _eatWord() {
- int start = _offset;
- while (_offset < length && _isLetter(_peekChar())) {
- _offset++;
- }
- return _src.substring(start, _offset);
- }
-
- /** Eats an integer. */
- int _maybeEatInt() {
- int start = _offset;
- bool dot = false;
- while (_offset < length && _isDigit(_peekChar())) {
- _offset++;
- }
-
- if (start == _offset) {
- return null;
- }
-
- return Math.parseInt(_src.substring(start, _offset));
- }
-
- /** Eats an integer. */
- int _eatInt() {
- int result = _maybeEatInt();
- if (result == null) {
- _error('expected positive integer');
- }
- return result;
- }
-
- /** Eats something like a positive decimal: 12.345. */
- num _eatDouble() {
- int start = _offset;
- bool dot = false;
- while (_offset < length) {
- int c = _peekChar();
- if (!_isDigit(c)) {
- if (c == DOT && !dot) {
- dot = true;
- } else {
- // Not a digit or decimal seperator
- break;
- }
- }
- _offset++;
- }
-
- if (start == _offset) {
- _error('expected positive decimal number');
- }
-
- return Math.parseDouble(_src.substring(start, _offset));
- }
-}
-
-/** Parses a grid template. */
-class _GridTemplateParser extends _Parser {
- _GridTemplateParser._internal(String src) : super(src);
-
- /** Parses the grid-rows and grid-columns CSS properties into object form. */
- static GridTemplate parse(String str) {
- if (str == null) return null;
- final p = new _GridTemplateParser._internal(str);
- final result = p._parseTemplate();
- p._eatEnd();
- return result;
- }
-
- /** Parses a grid-cell value. */
- static String parseCell(String str) {
- if (str == null) return null;
- final p = new _GridTemplateParser._internal(str);
- final result = p._maybeEatString();
- p._eatEnd();
- return result;
- }
-
- // => <string>+ | 'none'
- GridTemplate _parseTemplate() {
- if (_maybeEat('none')) {
- return null;
- }
- final rows = new List<String>();
- String row;
- while ((row = _maybeEatString()) != null) {
- rows.add(row);
- }
- if (rows.length == 0) {
- _error('expected at least one cell, or "none"');
- }
- return new GridTemplate(rows);
- }
-}
-
-/** Parses a grid-row or grid-column */
-class _GridItemParser extends _Parser {
- _GridItemParser._internal(String src) : super(src);
-
- /** Parses the grid-rows and grid-columns CSS properties into object form. */
- static _GridLocation parse(String cell, GridTrackList list) {
- if (cell == null) return null;
- final p = new _GridItemParser._internal(cell);
- final result = p._parseTrack(list);
- p._eatEnd();
- return result;
- }
-
- // [ [ <integer> | <string> | 'start' | 'end' ]
- // [ <integer> | <string> | 'start' | 'end' ]? ]
- // | 'auto'
- _GridLocation _parseTrack(GridTrackList list) {
- if (_maybeEat('auto')) {
- return null;
- }
- int start = _maybeParseLine(list);
- if (start == null) {
- _error('expected row/column number or name');
- }
- int end = _maybeParseLine(list);
- int span = null;
- if (end != null) {
- span = end - start;
- if (span <= 0) {
- _error('expected row/column span to be a positive integer');
- }
- }
- return new _GridLocation(start, span);
- }
-
- // [ <integer> | <string> | 'start' | 'end' ]
- int _maybeParseLine(GridTrackList list) {
- if (_maybeEat('start')) {
- return 1;
- } else if (_maybeEat('end')) {
- // The end is exclusive and 1-based, so return one past the size of the
- // track list.
- // TODO(jmesserly): this won't interact properly with implicit
- // rows/columns. Instead it will snap to the number of tracks at the point
- // where it is evaluated.
- return list.tracks.length + 1;
- }
-
- String name = _maybeEatString();
- if (name == null) {
- return _maybeEatInt();
- } else {
- int edge = list.lineNames[name];
- if (edge == null) {
- _error('row/column name "$name" not found in the parent\'s '
- + ' grid-row/grid-columns properties');
- }
- return edge;
- }
- }
-}
-
-/**
- * Parses grid-rows and grid-column properties, see:
- * [http://dev.w3.org/csswg/css3-grid-align/#grid-columns-and-rows-properties]
- * This is kept as a recursive descent parser for simplicity.
- */
-// TODO(jmesserly): implement missing features from the spec. Mainly around
-// CSS units, support for all escape sequences, etc.
-class _GridTrackParser extends _Parser {
- final List<GridTrack> _tracks;
- final Map<String, int> _lineNames;
-
- _GridTrackParser._internal(String src)
- : super(src),
- _tracks = new List<GridTrack>(),
- _lineNames = new Map<String, int>();
-
- /** Parses the grid-rows and grid-columns CSS properties into object form. */
- static GridTrackList parse(String str) {
- if (str == null) return null;
- final p = new _GridTrackParser._internal(str);
- final result = p._parseTrackList();
- p._eatEnd();
- return result;
- }
-
- /**
- * Parses the grid-row-sizing and grid-column-sizing CSS properties into
- * object form.
- */
- static TrackSizing parseTrackSizing(String str) {
- if (str == null) str = 'auto';
- final p = new _GridTrackParser._internal(str);
- final result = p._parseTrackMinmax();
- p._eatEnd();
- return result;
- }
-
- // <track-list> => [ [ <string> ]* <track-group> [ <string> ]* ]+ | 'none'
- GridTrackList _parseTrackList() {
- if (_maybeEat('none')) {
- return null;
- }
- _parseTrackListHelper();
- return new GridTrackList(_tracks, _lineNames);
- }
-
- /** Code shared by _parseTrackList and _parseTrackGroup */
- void _parseTrackListHelper([List<GridTrack> resultTracks = null]) {
- _maybeEatWhitespace();
- while (!endOfInput) {
- String name;
- while ((name = _maybeEatString()) != null) {
- _lineNames[name] = _tracks.length + 1; // should be 1-based
- }
-
- _maybeEatWhitespace();
- if (endOfInput) {
- return;
- }
-
- if (resultTracks != null) {
- if (_peekChar() == R_PAREN) {
- return;
- }
- resultTracks.add(new GridTrack(_parseTrackMinmax()));
- } else {
- _parseTrackGroup();
- }
-
- _maybeEatWhitespace();
- }
- }
-
- // <track-group> => [ '(' [ [ <string> ]* <track-minmax> [ <string> ]* ]+ ')'
- // [ '[' <positive-number> ']' ]? ]
- // | <track-minmax>
- void _parseTrackGroup() {
- if (_maybeEat('(')) {
- final tracks = new List<GridTrack>();
- _parseTrackListHelper(tracks);
- _eat(')');
- if (_maybeEat('[')) {
- num expand = _eatInt();
- _eat(']');
-
- if (expand <= 0) {
- _error('expected positive number');
- }
-
- // Repeat the track definition (but not the names) the specified number
- // of times. See:
- // http://dev.w3.org/csswg/css3-grid-align/#grid-repeating-columns-and-rows
- for (int i = 0; i < expand; i++) {
- for (GridTrack t in tracks) {
- _tracks.add(t.clone());
- }
- }
- }
- } else {
- _tracks.add(new GridTrack(_parseTrackMinmax()));
- }
- }
-
- // <track-minmax> => 'minmax(' <track-breadth> ',' <track-breadth> ')'
- // | 'auto' | <track-breadth>
- TrackSizing _parseTrackMinmax() {
- if (_maybeEat('auto') || _maybeEat('fit-content')) {
- return const TrackSizing.auto();
- }
- if (_maybeEat('minmax(')) {
- final min = _parseTrackBreadth();
- _eat(',');
- final max = _parseTrackBreadth();
- _eat(')');
- return new TrackSizing(min, max);
- } else {
- final breadth = _parseTrackBreadth();
- return new TrackSizing(breadth, breadth);
- }
- }
-
- // <track-breadth> => <length> | <percentage> | <fraction>
- // | 'min-content' | 'max-content'
- SizingFunction _parseTrackBreadth() {
- if (_maybeEat('min-content')) {
- return const MinContentSizing();
- } else if (_maybeEat('max-content')) {
- return const MaxContentSizing();
- }
-
- num value = _eatDouble();
-
- String units;
- if (_maybeEat('%')) {
- units = '%';
- } else {
- units = _eatWord();
- }
-
- if (units == 'fr') {
- return new FractionSizing(value);
- } else {
- return new FixedSizing(value, units);
- }
- }
-}
-
-
-/**
- * Exception thrown because the grid style properties had incorrect values.
- */
-class SyntaxErrorException implements Exception {
- final String _message;
- final int _offset;
- final String _source;
-
- const SyntaxErrorException(this._message, this._source, this._offset);
-
- String toString() {
- String location;
- if (_offset < _source.length) {
- location = 'location: ' + _source.substring(_offset);
- } else {
- location = 'end of input';
- }
- return 'SyntaxErrorException: $_message at $location';
- }
-}
« no previous file with comments | « client/layout/GridLayoutParams.dart ('k') | client/layout/GridTracks.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698