diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f0ee7bb --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +sys/*.sqlite \ No newline at end of file diff --git a/README.md b/README.md index e4256b7..d4e49e6 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,103 @@ -#meta +# miniMVC +miniMVC is a minimalistic Modular MVC framework, with built-in minifier, and pure-PHP templating system. -So, you know all that client information you need to keep track of, like passwords and servers? Or how about all those serial keys for the software you have? meta is a webapp to organize these kinds of data for easier reference. +### Requirements +* PHP 5.4+ +* PDO extensions for databases you wish to use +* Webserver that correctly handles REQUEST_URI, such as: + * Apache + * IIS + * Lighttpd +* SimpleTest library for running unit tests -##Organizing Data - -Meta has a four-level hierarchy - -1. Genre - * The broadest category. An example could be titled 'Client Data' -2. Category - * A general item in the genre. For example, an individual client. -3. Section - * A grouping of label-data pairs. Something like 'CMS Access' -4. Data - * Pairs of labels and values. +### Unique features +#### Extensive use of PHP's magic methods on the base class +* `__toString()` method allows a view of the current class object when the current class object is used as a string. If you prefer `var_dump()` or `var_export()`, you can pass the name of that function if you call the `__toString` method directly. - Eg. Username : admin + Eg. `$this . "string"`, `$this->__toString()`, `echo $this`; + +* `__call()` method allows the dynamic addition of callable closure objects + + Eg. `$this->foo = function($baz){}` is callable as `$this->foo()`, with the current object as the last argument + +* `MM` class extends ArrayObject, and all the main classes extend this class. Functions begining with `array_` are callable on object from this class. E.g. `$this->array_keys()` will return a list of the class properties. + +#### Database class is an extension of PHP's PDO class. + +Database class uses [Query](https://github.com/aviat4ion/Query) as a database abstraction layer and query builder. + +Database connections are set in /app/config/db.php + +### File Structure + +* index.php - framework bootstrap + +* app - configuration and app-wide files + * classes - helper classes + * config - configuration files + * modules - MVC triads + * controllers - controller classes + * models - model classes + * views - module-specific views + * views - global page templates + * errors - error page templates + +* assets - frontend files + * js - javascript files + * css - css files + * config - minifier configuration files + +* sys - core framework classes + +### Common Tasks + +* Creating a controller + + db = miniMVC\db::get_instance($db_name);` + + Note that multiple databases can be used in the same class + by specifying a different database name. + +* Loading a model (From a controller) + + `$this->load_model($model)` - creates an instance of that model as a member of the current class. After loading the model, you can call its methods like so + + `$this->[model name]->method()` + +* Loading a class + + Librarys / classes found in `app/classes` or `sys/libraries` are autoloaded. + To call a library, simply instantiate that class. + + Classes with a `get_instance` static methods should be called like so: + + `$obj =& miniMVC\class::get_instance()` + + + Other classes should be called using the new operator + + `$obj = new miniMVC\class()` + + \ No newline at end of file diff --git a/app/classes/index.html b/app/classes/index.html new file mode 100644 index 0000000..e69de29 diff --git a/app/config/config.php b/app/config/config.php new file mode 100644 index 0000000..ea843d7 --- /dev/null +++ b/app/config/config.php @@ -0,0 +1,135 @@ + array( + 'type' => 'sqlite', + 'host' => '', + 'user' => '', + 'pass' => '', + 'port' => '', + 'database' => '', + 'file' => MM_SYS_PATH . 'meta.sqlite', + ) +); + +// End of db.php \ No newline at end of file diff --git a/app/config/routes.php b/app/config/routes.php new file mode 100644 index 0000000..51a2b11 --- /dev/null +++ b/app/config/routes.php @@ -0,0 +1,41 @@ + 'blog/blog/index' + * + * To route a special 404 page, set '404_route' to the "module/controller/method" you wish to use + * + * @package miniMVC + * @subpackage App + */ + +// -------------------------------------------------------------------------- + +return array( + // Default Paths + 'default_controller' => 'welcome', + 'default_module' => 'meta', + 'genre' => 'meta/genre/index', + 'genre/add' => 'meta/genre/add', + '404_route' => '', +); + +// End of routes.php \ No newline at end of file diff --git a/app/modules/meta/controllers/genre.php b/app/modules/meta/controllers/genre.php new file mode 100644 index 0000000..c8a5ea7 --- /dev/null +++ b/app/modules/meta/controllers/genre.php @@ -0,0 +1,102 @@ +load_model('meta\model'); + + $this->page->build_header(); + } + + /** + * Default controller method + */ + public function index() + { + // Re-route to detail page if the last segment + // is a valid integer + $id = (int) miniMVC\get_last_segment(); + + if ($id !== 0) + { + return $this->detail($id); + } + + // Otherwise, display list of genres + $data = array(); + $data['genres'] = $this->model->get_genres(); + + $this->load_view('genres', $data); + $this->page->build_footer(); + } + + /** + * Adds a new genre + */ + public function add() + { + // Strip away tags for the sake of security + $name = strip_tags($_POST['genre']); + + // Make sure the name doesn't already exist. If it does, show an error. + $res = $this->model->add_genre($name); + + if ($res === TRUE) + { + $this->page->set_message('success', 'Added new genre'); + } + else + { + $this->page->set_message('error', 'Genre already exists'); + } + + // Render the basic page + $this->index(); + } + + /** + * Returns the categories / editing options for a genre + * + * @param int + */ + public function detail($id) + { + $genre = $this->model->get_genre_by_id($id); + $categories = $this->model->get_categories($id); + + $data = array( + 'genre' => $genre, + 'categories' => $categories, + 'genre_id' => $id + ); + + $this->load_view('genre_detail', $data); + $this->page->build_footer(); + } +} + +// End of genre.php \ No newline at end of file diff --git a/app/modules/meta/controllers/welcome.php b/app/modules/meta/controllers/welcome.php new file mode 100644 index 0000000..a448b9b --- /dev/null +++ b/app/modules/meta/controllers/welcome.php @@ -0,0 +1,59 @@ +load_model('meta\model'); + + } + + // -------------------------------------------------------------------------- + + /** + * Default route for the controller + * + * @return void + */ + public function index() + { + $data = array(); + $data['genres'] = $this->model->get_genres(); + + $this->page->render('genres', $data); + } + + // -------------------------------------------------------------------------- + + public function login() + { + + } +} + +// End of welcome.php \ No newline at end of file diff --git a/app/modules/meta/models/model.php b/app/modules/meta/models/model.php new file mode 100644 index 0000000..13c5c83 --- /dev/null +++ b/app/modules/meta/models/model.php @@ -0,0 +1,351 @@ +session =& \miniMVC\Session::get_instance(); + $this->db =& \miniMVC\db::get_instance(); + } + + // -------------------------------------------------------------------------- + + /** + * Delete a genre/category/section or data item + * + * @param string $type + * @param int $id + */ + public function delete($type, $id) + { + $this->db->where('id', (int) $id) + ->delete($type); + } + + // -------------------------------------------------------------------------- + + /** + * Move a category/section/data item to another parent + * + * @param string + * @param int + * @param int + */ + public function move($type, $type_id, $parent_id) + { + $parent_type = array( + 'data' => 'section', + 'section' => 'category', + 'category' => 'genre' + ); + + $parent_field = "{$parent_type[$type]}_id"; + + $this->db->set($parent_field, $parent_id) + ->where('id', (int) $type_id) + ->update($type); + } + + // -------------------------------------------------------------------------- + + /** + * Add genre + * + * @param string + * @return bool + */ + public function add_genre($genre) + { + // Check for duplicates + $query = $this->db->from('genre') + ->where('genre', $genre) + ->get(); + + // Fetch the data as a workaround + // for databases that do not support + // grabbing result counts (SQLite / Firebird) + $array = $query->fetchAll(); + if (count($array) === 0) + { + $this->db->set('genre', $genre) + ->insert('genre'); + + return TRUE; + } + + return FALSE; + + } + + // -------------------------------------------------------------------------- + + /** + * Rename a genre + * + * @param int + * @param string + */ + public function update_genre($genre_id, $genre) + { + $this->db->set('genre', $genre) + ->where('id', $genre_id) + ->update('genre'); + } + + // -------------------------------------------------------------------------- + + /** + * Add category to genre + * + * @param string + * @param int + */ + public function add_category($cat, $genre_id) + { + $this->db->set('category', $cat) + ->set('genre_id', $genre_id) + ->insert('category'); + } + + // -------------------------------------------------------------------------- + + /** + * Rename a category + * + * @param int + * @param string + */ + public function update_category($cat_id, $category) + { + $this->db->set('category', $category) + ->where('id', (int) $cat_id) + ->update('category'); + } + + // -------------------------------------------------------------------------- + + /** + * Add a section to a category + * + * @param string + * @param int + */ + public function add_section($section, $category_id) + { + $this->db->set('section', $section) + ->set('category_id', (int) $category_id) + ->insert('section'); + } + + // -------------------------------------------------------------------------- + + /** + * Rename a section + * + * @param int + * @param string + */ + public function update_section($section_id, $section) + { + $this->db->set('section', $section) + ->where('id', (int) $section_id) + ->update('section'); + } + + // -------------------------------------------------------------------------- + + /** + * Add key/value data to a section + * + * @param int + * @param mixed object/array + */ + public function add_data($section_id, $data) + { + // Convert the data to json for storage + $data_str = json_encode($data); + + // Save the data + $this->db->set('data', $data_str) + ->set('section_id', (int) $section_id) + ->insert('data'); + } + + // -------------------------------------------------------------------------- + + /** + * Update the data + * + * @param int + * @param mixed + */ + public function update_data($data_id, $data) + { + // Convert the data to json for storage + $data_str = json_encode('data', $data_str); + + // Save the data + $this->db->set('data', $data_str) + ->where('id', (int) $data_id) + ->update('data'); + + } + + // -------------------------------------------------------------------------- + + /** + * Gets the list of genres + * + * @return array + */ + public function get_genres() + { + $genres = array(); + $query = $this->db->select('id, genre') + ->from('genre') + ->order_by('genre', 'asc') + ->get(); + + while($row = $query->fetch(\PDO::FETCH_ASSOC)) + { + $genres[$row['id']] = $row['genre']; + } + + return $genres; + } + + /** + * Gets the name of the genre from its id + * + * @param int + * @return string + */ + public function get_genre_by_id($id) + { + $query = $this->db->select('genre') + ->from('genre') + ->where('id', (int) $id) + ->get(); + + $row = $query->fetch(\PDO::FETCH_ASSOC); + + return $row['genre']; + } + + // -------------------------------------------------------------------------- + + /** + * Get the categories for the specified genre + * + * @param int + * @return array + */ + public function get_categories($genre_id) + { + $cats = array(); + + $query = $this->db->select('id, category') + ->from('category') + ->where('genre_id', (int) $genre_id) + ->get(); + + while($row = $query->fetch(\PDO::FETCH_ASSOC)) + { + $cats[$row['id']] = $row['category']; + } + + return $cats; + } + + // -------------------------------------------------------------------------- + + /** + * Get the sections for the specified category id + * + * @param int + * @return array + */ + public function get_sections($category_id) + { + $sections = array(); + + $query = $this->db->select('id, section') + ->from('section') + ->where('category_id', (int) $category_id) + ->get(); + + while($row = $query->fetch(\PDO::FETCH_ASSOC)) + { + $sections[$row['id']] = $row['section']; + } + + return $sections; + } + + // -------------------------------------------------------------------------- + + /** + * Get the data fro the section + * + * @param int + * @return array + */ + public function get_data($section_id) + { + $data = array(); + + $query = $this->db->select('id, data') + ->from('data') + ->where('section_id', (int) $section_id) + ->get(); + + while($row = $query->fetch(\PDO::FETCH_ASSOC)) + { + $data[$row['id']] = json_decode($row['data'], TRUE); + } + + return $data; + } + +} + +// End of model.php \ No newline at end of file diff --git a/app/modules/meta/models/user_model.php b/app/modules/meta/models/user_model.php new file mode 100644 index 0000000..023837a --- /dev/null +++ b/app/modules/meta/models/user_model.php @@ -0,0 +1,32 @@ +meta +

+ +

Genre Categories

+ + +
" method="post"> +
+ Add Category +
+ +
+
+ +
+
+
+
+
\ No newline at end of file diff --git a/app/modules/meta/views/genres.php b/app/modules/meta/views/genres.php new file mode 100644 index 0000000..e20191b --- /dev/null +++ b/app/modules/meta/views/genres.php @@ -0,0 +1,22 @@ +

Meta

+

Genres

+ + + +
" method="post"> +
+ Add Genre +
+ +
+
+ +
 
+
+
+
+
\ No newline at end of file diff --git a/app/modules/meta/views/index.html b/app/modules/meta/views/index.html new file mode 100644 index 0000000..e69de29 diff --git a/app/modules/meta/views/section_detail.php b/app/modules/meta/views/section_detail.php new file mode 100644 index 0000000..e69de29 diff --git a/app/views/errors/error_404.php b/app/views/errors/error_404.php new file mode 100644 index 0000000..e210433 --- /dev/null +++ b/app/views/errors/error_404.php @@ -0,0 +1,19 @@ + + + + 404 Not Found + + + +
+ +

+ + + + +
+ + \ No newline at end of file diff --git a/app/views/errors/error_db.php b/app/views/errors/error_db.php new file mode 100644 index 0000000..bab8d6d --- /dev/null +++ b/app/views/errors/error_db.php @@ -0,0 +1,7 @@ +
+

A Database Error was encountered

+ +

Code:

+

Driver Code:

+

Message:

+
\ No newline at end of file diff --git a/app/views/errors/error_general.php b/app/views/errors/error_general.php new file mode 100644 index 0000000..e210433 --- /dev/null +++ b/app/views/errors/error_general.php @@ -0,0 +1,19 @@ + + + + 404 Not Found + + + +
+ +

+ + + + +
+ + \ No newline at end of file diff --git a/app/views/errors/error_php_exception.php b/app/views/errors/error_php_exception.php new file mode 100755 index 0000000..e69e9ce --- /dev/null +++ b/app/views/errors/error_php_exception.php @@ -0,0 +1,22 @@ +
+

An uncaught exception was thrown.

+ +

Message:

+ + + +

Backtrace:

+ getTrace() as $error): ?> + + +

+ File:
+ Line:
+ Function: +

+ + +

+ + +
\ No newline at end of file diff --git a/app/views/footer.php b/app/views/footer.php new file mode 100644 index 0000000..2db2403 --- /dev/null +++ b/app/views/footer.php @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/views/header.php b/app/views/header.php new file mode 100644 index 0000000..4bb3b22 --- /dev/null +++ b/app/views/header.php @@ -0,0 +1,11 @@ + + + + + +<?= $title ?> + + + + +> \ No newline at end of file diff --git a/app/views/message.php b/app/views/message.php new file mode 100644 index 0000000..8f1fbd0 --- /dev/null +++ b/app/views/message.php @@ -0,0 +1,5 @@ +
+ + + +
\ No newline at end of file diff --git a/assets/config/config.php b/assets/config/config.php new file mode 100755 index 0000000..05bdf7e --- /dev/null +++ b/assets/config/config.php @@ -0,0 +1,76 @@ + array( + 'normalize.css', + 'message.css', + 'theme.css' + ) +); +// End of css_groups.php \ No newline at end of file diff --git a/assets/config/js_groups.php b/assets/config/js_groups.php new file mode 100755 index 0000000..f1b33b7 --- /dev/null +++ b/assets/config/js_groups.php @@ -0,0 +1,28 @@ + array( + 'path/to/css/file1.css', + 'path/to/css/file2.css' + ), + */ +]; \ No newline at end of file diff --git a/assets/css.php b/assets/css.php new file mode 100755 index 0000000..a44f76a --- /dev/null +++ b/assets/css.php @@ -0,0 +1,135 @@ + ')', + ') ' => ')', + ' }' => '}', + '} ' => '}', + ' {' => '{', + '{ ' => '{', + ', ' => ',', + ': ' => ':', + '; ' => ';', + ]; + + //Eradicate every last space! + $buffer = trim(strtr($buffer, $replace)); + $buffer = str_replace('{ ', '{', $buffer); + $buffer = str_replace('} ', '}', $buffer); + + return $buffer; +} + +// -------------------------------------------------------------------------- + +//Creative rewriting +$pi = $_SERVER['PATH_INFO']; +$pia = explode('/', $pi); + +$pia_len = count($pia); +$i = 1; + +while($i < $pia_len) +{ + $j = $i+1; + $j = (isset($pia[$j])) ? $j : $i; + + $_GET[$pia[$i]] = $pia[$j]; + + $i = $j + 1; +}; + +$css = ''; +$modified = []; + +if (isset($groups[$_GET['g']])) +{ + foreach ($groups[$_GET['g']] as &$file) + { + $new_file = $css_root.$file; + $css .= file_get_contents($new_file); + $modified[] = filemtime($new_file); + } +} + +//Add this page too +$modified[] = filemtime($this_file); + +//Get the latest modified date +rsort($modified); +$last_modified = $modified[0]; + +$requested_time= (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) + ? strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) + : time(); + +if ($last_modified === $requested_time) +{ + header("HTTP/1.1 304 Not Modified"); + exit(); +} + +if (!isset($_GET['debug'])) +{ + $css = compress($css); +} + +$size = strlen($css) * 8; + +//This GZIPs the CSS for transmission to the user +//making file size smaller and transfer rate quicker +ob_start("ob_gzhandler"); + +header("Content-Type: text/css; charset=utf8"); +header("Cache-control: public, max-age=691200, must-revalidate"); +header("Last-Modified: ".gmdate('D, d M Y H:i:s', $last_modified)." GMT"); +header("Expires: ".gmdate('D, d M Y H:i:s', (filemtime($this_file) + 691200))." GMT"); + +echo $css; + +ob_end_flush(); +//End of css.php \ No newline at end of file diff --git a/assets/css/message.css b/assets/css/message.css new file mode 100644 index 0000000..9eb6977 --- /dev/null +++ b/assets/css/message.css @@ -0,0 +1,36 @@ +.message{ + position:relative; + margin:0.5em auto; + padding:0.5em; + width:95%; +} + +.message .close{ + width:1em; + height:1em; + border:1px solid #000; + position:absolute; + right:0.5em; + top:0.5em; +} + +.message .icon{ + left:0.5em; + top:0.5em; + margin-right:1em; +} + +.error{ + border:1px solid #924949; + background: #f3e6e6; +} + +.success{ + border:1px solid #1f8454; + background: #70dda9; +} + +.info{ + border:1px solid #bfbe3a; + background: #FFFFCC; +} \ No newline at end of file diff --git a/assets/css/normalize.css b/assets/css/normalize.css new file mode 100644 index 0000000..4474dee --- /dev/null +++ b/assets/css/normalize.css @@ -0,0 +1,504 @@ +/*! normalize.css 2012-03-11T12:53 UTC - http://github.com/necolas/normalize.css */ + +/* ============================================================================= + HTML5 display definitions + ========================================================================== */ + +/* + * Corrects block display not defined in IE6/7/8/9 & FF3 + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section, +summary { + display: block; +} + +/* + * Corrects inline-block display not defined in IE6/7/8/9 & FF3 + */ + +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; +} + +/* + * Prevents modern browsers from displaying 'audio' without controls + * Remove excess height in iOS5 devices + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/* + * Addresses styling for 'hidden' attribute not present in IE7/8/9, FF3, S4 + * Known issue: no IE6 support + */ + +[hidden] { + display: none; +} + + +/* ============================================================================= + Base + ========================================================================== */ + +/* + * 1. Corrects text resizing oddly in IE6/7 when body font-size is set using em units + * http://clagnut.com/blog/348/#c790 + * 2. Prevents iOS text size adjust after orientation change, without disabling user zoom + * www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/ + */ + +html { + font-size: 100%; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ + -ms-text-size-adjust: 100%; /* 2 */ +} + +/* + * Addresses font-family inconsistency between 'textarea' and other form elements. + */ + +html, +button, +input, +select, +textarea { + font-family: sans-serif; +} + +/* + * Addresses margins handled incorrectly in IE6/7 + */ + +body { + margin: 0; +} + + +/* ============================================================================= + Links + ========================================================================== */ + +/* + * Addresses outline displayed oddly in Chrome + */ + +a:focus { + outline: thin dotted; +} + +/* + * Improves readability when focused and also mouse hovered in all browsers + * people.opera.com/patrickl/experiments/keyboard/test + */ + +a:hover, +a:active { + outline: 0; +} + + +/* ============================================================================= + Typography + ========================================================================== */ + +/* + * Addresses font sizes and margins set differently in IE6/7 + * Addresses font sizes within 'section' and 'article' in FF4+, Chrome, S5 + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +h2 { + font-size: 1.5em; + margin: 0.83em 0; +} + +h3 { + font-size: 1.17em; + margin: 1em 0; +} + +h4 { + font-size: 1em; + margin: 1.33em 0; +} + +h5 { + font-size: 0.83em; + margin: 1.67em 0; +} + +h6 { + font-size: 0.75em; + margin: 2.33em 0; +} + +/* + * Addresses styling not present in IE7/8/9, S5, Chrome + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/* + * Addresses style set to 'bolder' in FF3+, S4/5, Chrome +*/ + +b, +strong { + font-weight: bold; +} + +blockquote { + margin: 1em 40px; +} + +/* + * Addresses styling not present in S5, Chrome + */ + +dfn { + font-style: italic; +} + +/* + * Addresses styling not present in IE6/7/8/9 + */ + +mark { + background: #ff0; + color: #000; +} + +/* + * Addresses margins set differently in IE6/7 + */ + +p, +pre { + margin: 1em 0; +} + +/* + * Corrects font family set oddly in IE6, S4/5, Chrome + * en.wikipedia.org/wiki/User:Davidgothberg/Test59 + */ + +pre, +code, +kbd, +samp { + font-family: monospace, serif; + _font-family: 'courier new', monospace; + font-size: 1em; +} + +/* + * Improves readability of pre-formatted text in all browsers + */ + +pre { + white-space: pre; + white-space: pre-wrap; + word-wrap: break-word; +} + +/* + * 1. Addresses CSS quotes not supported in IE6/7 + * 2. Addresses quote property not supported in S4 + */ + +/* 1 */ + +q { + quotes: none; +} + +/* 2 */ + +q:before, +q:after { + content: ''; + content: none; +} + +small { + font-size: 75%; +} + +/* + * Prevents sub and sup affecting line-height in all browsers + * gist.github.com/413930 + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + + +/* ============================================================================= + Lists + ========================================================================== */ + +/* + * Addresses margins set differently in IE6/7 + */ + +dl, +menu, +ol, +ul { + margin: 1em 0; +} + +dd { + margin: 0 0 0 40px; +} + +/* + * Addresses paddings set differently in IE6/7 + */ + +menu, +ol, +ul { + padding: 0 0 0 40px; +} + +/* + * Corrects list images handled incorrectly in IE7 + */ + +nav ul, +nav ol { + list-style: none; + list-style-image: none; +} + + +/* ============================================================================= + Embedded content + ========================================================================== */ + +/* + * 1. Removes border when inside 'a' element in IE6/7/8/9, FF3 + * 2. Improves image quality when scaled in IE7 + * code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/ + */ + +img { + border: 0; /* 1 */ + -ms-interpolation-mode: bicubic; /* 2 */ +} + +/* + * Corrects overflow displayed oddly in IE9 + */ + +svg:not(:root) { + overflow: hidden; +} + + +/* ============================================================================= + Figures + ========================================================================== */ + +/* + * Addresses margin not present in IE6/7/8/9, S5, O11 + */ + +figure { + margin: 0; +} + + +/* ============================================================================= + Forms + ========================================================================== */ + +/* + * Corrects margin displayed oddly in IE6/7 + */ + +form { + margin: 0; +} + +/* + * Define consistent border, margin, and padding + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/* + * 1. Corrects color not being inherited in IE6/7/8/9 + * 2. Corrects text not wrapping in FF3 + * 3. Corrects alignment displayed oddly in IE6/7 + */ + +legend { + border: 0; /* 1 */ + padding: 0; + white-space: normal; /* 2 */ + *margin-left: -7px; /* 3 */ +} + +/* + * 1. Corrects font size not being inherited in all browsers + * 2. Addresses margins set differently in IE6/7, FF3+, S5, Chrome + * 3. Improves appearance and consistency in all browsers + */ + +button, +input, +select, +textarea { + font-size: 100%; /* 1 */ + margin: 0; /* 2 */ + vertical-align: baseline; /* 3 */ + *vertical-align: middle; /* 3 */ +} + +/* + * Addresses FF3/4 setting line-height on 'input' using !important in the UA stylesheet + */ + +button, +input { + line-height: normal; /* 1 */ +} + +/* + * 1. Improves usability and consistency of cursor style between image-type 'input' and others + * 2. Corrects inability to style clickable 'input' types in iOS + * 3. Removes inner spacing in IE7 without affecting normal text inputs + * Known issue: inner spacing remains in IE6 + */ + +button, +input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; /* 1 */ + -webkit-appearance: button; /* 2 */ + *overflow: visible; /* 3 */ +} + +/* + * Re-set default cursor for disabled elements + */ + +button[disabled], +input[disabled] { + cursor: default; +} + +/* + * 1. Addresses box sizing set to content-box in IE8/9 + * 2. Removes excess padding in IE8/9 + * 3. Removes excess padding in IE7 + Known issue: excess padding remains in IE6 + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ + *height: 13px; /* 3 */ + *width: 13px; /* 3 */ +} + +/* + * 1. Addresses appearance set to searchfield in S5, Chrome + * 2. Addresses box-sizing set to border-box in S5, Chrome (include -moz to future-proof) + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; /* 2 */ + box-sizing: content-box; +} + +/* + * Removes inner padding and search cancel button in S5, Chrome on OS X + */ + +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +/* + * Removes inner padding and border in FF3+ + * www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/ + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/* + * 1. Removes default vertical scrollbar in IE6/7/8/9 + * 2. Improves readability and alignment in all browsers + */ + +textarea { + overflow: auto; /* 1 */ + vertical-align: top; /* 2 */ +} + + +/* ============================================================================= + Tables + ========================================================================== */ + +/* + * Remove most spacing between table cells + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/assets/css/theme.css b/assets/css/theme.css new file mode 100644 index 0000000..4bb1aa0 --- /dev/null +++ b/assets/css/theme.css @@ -0,0 +1,28 @@ +/* ---------------- */ +/* ! General Styles */ +/* ---------------- */ +html, body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight:200; + max-width:800px; + margin: 0 auto; +} + +/* form styles */ +form dt, form dd { + display:inline-block; + padding:0.25em 0; +} + +form dt { + width:40%; + text-align:right; +} + +form dd { + width:59%; + text-align:left; + margin-left:0; + padding-left:.25em; +} + diff --git a/assets/js.php b/assets/js.php new file mode 100755 index 0000000..57ba8d8 --- /dev/null +++ b/assets/js.php @@ -0,0 +1,188 @@ + + + miniMVC + + docs + + + docs + + +