From 3fa8e7d8e869b0ce7d27414338c5871cb1a67bdf Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Mon, 1 Feb 2016 09:49:18 -0500 Subject: [PATCH] Ugly progress commit --- README.md | 2 +- app/config/minify_config.php | 2 +- app/config/minify_js_groups.php | 107 +- app/views/anime/add.php | 11 +- app/views/anime/details.php | 11 + app/views/anime/list.php | 6 +- app/views/footer.php | 1 + app/views/header.php | 20 +- app/views/message.ms | 5 + app/views/message.php | 2 +- public/bower.json | 20 + public/cache/.gitkeep | 0 public/css/base.css | 418 +- public/css/base.myth.css | 346 +- public/css/marx.css | 3 +- public/css/marx.myth.css | 3 +- public/js.php | 32 +- public/js/anime_collection.js | 51 +- public/js/anime_edit.js | 54 +- public/js/base.js | 45 + public/js/events.js | 13 + public/js/lib/datatables.js | 15226 -------------------- public/js/lib/jquery.min.js | 1 - public/js/lib/jquery.throttle-debounce.js | 252 - public/js/lib/jsrender.js | 1958 --- public/js/manga_edit.js | 43 +- public/js/show_message.js | 13 - public/js/sort_tables.js | 81 +- public/templates/ajax-search-results.html | 10 + src/Aviat/Ion/View/HttpView.php | 2 +- 30 files changed, 957 insertions(+), 17781 deletions(-) create mode 100644 app/views/anime/details.php create mode 100644 app/views/message.ms create mode 100644 public/bower.json create mode 100644 public/cache/.gitkeep create mode 100644 public/js/base.js create mode 100644 public/js/events.js delete mode 100644 public/js/lib/datatables.js delete mode 100644 public/js/lib/jquery.min.js delete mode 100644 public/js/lib/jquery.throttle-debounce.js delete mode 100644 public/js/lib/jsrender.js delete mode 100644 public/js/show_message.js create mode 100644 public/templates/ajax-search-results.html diff --git a/README.md b/README.md index 4d97aa44..15c8c2de 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ A self-hosted client that allows custom formatting of data from the hummingbird * app/cache * public/images/manga * public/images/anime - * public/js/cache + * public/cache #### Anime Collection Additional Installation * Run `php /vendor/bin/phinx migrate -e development` to create the database tables diff --git a/app/config/minify_config.php b/app/config/minify_config.php index 9fa30251..20d9941a 100644 --- a/app/config/minify_config.php +++ b/app/config/minify_config.php @@ -56,4 +56,4 @@ $path_to = ''; | The folder where javascript files exist, in relation to the document root | */ -$js_root = $config['asset_dir'] . '/js/'; \ No newline at end of file +$js_root = $config['asset_dir'] . '/'; \ No newline at end of file diff --git a/app/config/minify_js_groups.php b/app/config/minify_js_groups.php index f6d0efff..dd1b728f 100644 --- a/app/config/minify_js_groups.php +++ b/app/config/minify_js_groups.php @@ -13,10 +13,57 @@ // -------------------------------------------------------------------------- +$bower_packages = ['jquery', 'datatables', 'mustache.js']; +$bower_file_map = []; + +foreach($bower_packages as $package) +{ + $bower_file_map[$package] = []; + $json = json_decode(file_get_contents(__DIR__ . "/../../public/bower_components/{$package}/bower.json")); + + if ( ! is_array($json->main)) + { + $json->main = [$json->main]; + } + + foreach($json->main as $file) + { + if (stristr($file, '.js') !== FALSE) + { + array_push($bower_file_map[$package], "bower_components/{$package}/{$file}"); + } + } +} + +/** + * Merge together bower configs and local files + * + * @param string|array $bower - array of bower components to include + * @param string|array $local - array of local js files to include + * @return array - group array + */ +function create_group($bower, $local=[]) +{ + global $bower_file_map; + $group = []; + + foreach((array) $bower as $component) + { + $group = array_merge($group, $bower_file_map[$component]); + } + + foreach((array) $local as $file) + { + $group[] = $file; + } + + return $group; +} + /** * This is the config array for javascript files to concatenate and minify */ -return [ +$map = [ /* For each group create an array like so @@ -25,37 +72,33 @@ return [ 'path/to/js/file2.js' ), */ - 'table' => [ - 'lib/jquery.min.js', - 'lib/datatables.js', - 'sort_tables.js' - ], - 'table_edit' => [ - 'lib/jquery.min.js', - 'lib/datatables.js', - 'sort_tables.js', - 'show_message.js', - 'anime_edit.js', - 'manga_edit.js' - ], - 'edit' => [ - 'lib/jquery.min.js', - 'show_message.js', - 'anime_edit.js', - 'manga_edit.js' - ], - 'anime_collection' => [ - 'lib/jquery.min.js', - 'lib/jquery.throttle-debounce.js', - 'lib/jsrender.js', - 'anime_collection.js' - ], - 'manga_collection' => [ - 'lib/jquery.min.js', - 'lib/jquery.throttle-debounce.js', - 'lib/jsrender.js', - 'manga_collection.js' - ] + 'base' => create_group('jquery', [ + 'js/base.js', + ]), + 'event' => create_group([], 'js/events.js'), + 'table' => create_group([], 'js/sort_tables.js'), + 'table_edit' => create_group([], [ + 'js/sort_tables.js', + 'js/anime_edit.js', + 'js/manga_edit.js', + ]), + 'edit' => create_group([],[ + 'js/anime_edit.js', + 'js/manga_edit.js' + ]), + 'anime_collection' => create_group('mustache.js', [ + 'bower_components/jquery-throttle-debounce/jquery.ba-throttle-debounce.js', + 'js/anime_collection.js' + ]), + 'manga_collection' => create_group('mustache.js', [ + 'bower_components/jquery-throttle-debounce/jquery.ba-throttle-debounce.js', + 'js/manga_collection.js' + ]), ]; +//print_r($map); +//die(); + +return $map; + // End of js_groups.php \ No newline at end of file diff --git a/app/views/anime/add.php b/app/views/anime/add.php index 12e88ab3..2fbdd582 100644 --- a/app/views/anime/add.php +++ b/app/views/anime/add.php @@ -3,6 +3,11 @@

Add Anime to your List

+
@@ -30,11 +35,5 @@ - \ No newline at end of file diff --git a/app/views/anime/details.php b/app/views/anime/details.php new file mode 100644 index 00000000..94ab30fe --- /dev/null +++ b/app/views/anime/details.php @@ -0,0 +1,11 @@ +
+

+ +

+ + + <?= $data['title'] ?> cover image + +

+
+
\ No newline at end of file diff --git a/app/views/anime/list.php b/app/views/anime/list.php index 030c74e1..c173c738 100644 --- a/app/views/anime/list.php +++ b/app/views/anime/list.php @@ -11,7 +11,7 @@ is_authenticated()): ?> -   +   Title Airing Status @@ -33,7 +33,7 @@ ">Edit - + @@ -42,7 +42,7 @@ / 10 - + Episodes:
 /  diff --git a/app/views/footer.php b/app/views/footer.php index 691287b6..d9e45b6b 100644 --- a/app/views/footer.php +++ b/app/views/footer.php @@ -1,2 +1,3 @@ + \ No newline at end of file diff --git a/app/views/header.php b/app/views/header.php index 7f38f211..ad56fd7a 100644 --- a/app/views/header.php +++ b/app/views/header.php @@ -5,12 +5,9 @@ <?= $title ?> - + - +
@@ -50,11 +47,8 @@ -
- -
- - html($message['message']) ?> - x -
- + + \ No newline at end of file diff --git a/app/views/message.ms b/app/views/message.ms new file mode 100644 index 00000000..99b2b568 --- /dev/null +++ b/app/views/message.ms @@ -0,0 +1,5 @@ +
+ + {{message}} + x +
\ No newline at end of file diff --git a/app/views/message.php b/app/views/message.php index f34b205c..f20323bf 100644 --- a/app/views/message.php +++ b/app/views/message.php @@ -1,5 +1,5 @@
html($message) ?> - x +
\ No newline at end of file diff --git a/public/bower.json b/public/bower.json new file mode 100644 index 00000000..80f461c8 --- /dev/null +++ b/public/bower.json @@ -0,0 +1,20 @@ +{ + "name": "HummingbirdAnimeClient", + "homepage": "https://github.com/timw4mail/HummingBirdAnimeClient", + "authors": [ + "Timothy J Warren " + ], + "description": "Frontend stuff for php app", + "main": "", + "moduleType": [ + "globals" + ], + "license": "MIT", + "private": true, + "dependencies": { + "jquery": "^2.2.0", + "datatables": "DataTables#^1.10.10", + "jquery-throttle-debounce": "*", + "mustache.js": "mustache#^2.2.1" + } +} diff --git a/public/cache/.gitkeep b/public/cache/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/public/css/base.css b/public/css/base.css index 84977fd5..f700e521 100644 --- a/public/css/base.css +++ b/public/css/base.css @@ -6,67 +6,46 @@ body { margin: 0.5em; } -a:hover, -a:active { - color: #7d12db; +button { + background: rgba(255,255,255,0.65); + margin: 0; } table { - width: 85%; + /*width:85%;*/ margin: 0 auto; } -tbody > tr:nth-child(odd) { - background: #ddd; +td { + padding: 1em; + padding: 1rem; } -/* Table sorting styles */ - -th.sorting::after { - content: " ↕ "; -} - -th.sorting_asc::after { - content: " ↑ "; -} - -th.sorting_desc::after { - content: " ↓ "; +thead td, +thead th { + padding: 0.5em; + padding: 0.5rem; } input[type=number] { width: 4em; } -.form { - width: 100%; +tbody > tr:nth-child(odd) { + background: #ddd; } -.form tr > td:nth-child(odd) { - text-align: right; - min-width: 25px; - max-width: 30%; +a:hover, +a:active { + color: #7d12db; } -.form tr > td:nth-child(even) { - text-align: left; - min-width: 70%; -} +/* ----------------------------------------------------------------------------- + Utility classes +------------------------------------------------------------------------------*/ -.form thead th, -.form thead tr { - background: inherit; - border: 0; -} - -.form.invisible tr:nth-child(odd) { - background: inherit; -} - -.form.invisible tr, -.form.invisible td, -.form.invisible th { - border: 0; +.bracketed { + color: #12db18; } .bracketed, @@ -82,10 +61,6 @@ h1 a { content: '\00a0]'; } -.bracketed { - color: #12db18; -} - .bracketed:hover, .bracketed:active { color: #db7d12; @@ -146,6 +121,10 @@ h1 a { font-size: 1.6rem; } +.justify { + text-align: justify; +} + .align_center { text-align: center; } @@ -158,11 +137,257 @@ h1 a { text-align: right; } +.no_border { + border: none; +} + .media-wrap { text-align: center; margin: 0 auto; } +/* ----------------------------------------------------------------------------- + CSS loading icon +------------------------------------------------------------------------------*/ + +.cssload-loader { + position: relative; + left: calc(50% - 31px); + width: 62px; + height: 62px; + border-radius: 50%; + -webkit-perspective: 780px; + perspective: 780px; +} + +.cssload-inner { + position: absolute; + width: 100%; + height: 100%; + box-sizing: border-box; + border-radius: 50%; +} + +.cssload-inner.cssload-one { + left: 0%; + top: 0%; + -webkit-animation: cssload-rotate-one 1.15s linear infinite; + animation: cssload-rotate-one 1.15s linear infinite; + border-bottom: 3px solid rgb(0,0,0); +} + +.cssload-inner.cssload-two { + right: 0%; + top: 0%; + -webkit-animation: cssload-rotate-two 1.15s linear infinite; + animation: cssload-rotate-two 1.15s linear infinite; + border-right: 3px solid rgb(0,0,0); +} + +.cssload-inner.cssload-three { + right: 0%; + bottom: 0%; + -webkit-animation: cssload-rotate-three 1.15s linear infinite; + animation: cssload-rotate-three 1.15s linear infinite; + border-top: 3px solid rgb(0,0,0); +} + +@-webkit-keyframes cssload-rotate-one { + 0% { + -webkit-transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg); + transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg); + } + + 100% { + -webkit-transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg); + transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg); + } +} + +@keyframes cssload-rotate-one { + 0% { + -webkit-transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg); + transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg); + } + + 100% { + -webkit-transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg); + transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg); + } +} + +@-webkit-keyframes cssload-rotate-two { + 0% { + -webkit-transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg); + transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg); + } + + 100% { + -webkit-transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg); + transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg); + } +} + +@keyframes cssload-rotate-two { + 0% { + -webkit-transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg); + transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg); + } + + 100% { + -webkit-transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg); + transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg); + } +} + +@-webkit-keyframes cssload-rotate-three { + 0% { + -webkit-transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg); + transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg); + } + + 100% { + -webkit-transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg); + transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg); + } +} + +@keyframes cssload-rotate-three { + 0% { + -webkit-transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg); + transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg); + } + + 100% { + -webkit-transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg); + transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg); + } +} + +/* ----------------------------------------------------------------------------- + Table sorting and form styles +------------------------------------------------------------------------------*/ + +.sorting, +.sorting_asc, +.sorting_desc { + vertical-align: text-bottom; +} + +.sorting::before { + content: " ↕\00a0"; +} + +.sorting_asc::before { + content: " ↑\00a0"; +} + +.sorting_desc::before { + content: " ↓\00a0"; +} + +.form { + width: 100%; +} + +.form thead th, +.form thead tr { + background: inherit; + border: 0; +} + +.form tr > td:nth-child(odd) { + text-align: right; + min-width: 25px; + max-width: 30%; +} + +.form tr > td:nth-child(even) { + text-align: left; + min-width: 70%; +} + +.form.invisible tr:nth-child(odd) { + background: inherit; +} + +.form.invisible tr, +.form.invisible td, +.form.invisible th { + border: 0; +} + +/* ----------------------------------------------------------------------------- + Message boxes +------------------------------------------------------------------------------*/ + +.message { + position: relative; + margin: 0.5em auto; + padding: 0.5em; + width: 95%; +} + +.message .close { + width: 1em; + height: 1em; + position: absolute; + right: 0.5em; + top: 0.5em; + text-align: center; + vertical-align: middle; + line-height: 1em; +} + +/*.message .close:after { + content: '☐'; +}*/ + +.message:hover .close:after { + content: '☒'; +} + +.message:hover { + cursor: pointer; +} + +.message .icon { + left: 0.5em; + top: 0.5em; + margin-right: 1em; +} + +.message.error { + border: 1px solid #924949; + background: #f3e6e6; +} + +.message.error .icon::after { + content: '✘'; +} + +.message.success { + border: 1px solid #1f8454; + background: #70dda9; +} + +.message.success .icon::after { + content: '✔'; +} + +.message.info { + border: 1px solid #bfbe3a; + background: #FFFFCC; +} + +.message.info .icon::after { + content: '⚠'; +} + +/* ----------------------------------------------------------------------------- + Base list styles +------------------------------------------------------------------------------*/ + .media { position: relative; vertical-align: top; @@ -173,11 +398,6 @@ h1 a { margin: 0.25em; } -button { - background: rgba(255,255,255,0.65); - margin: 0; -} - .media .edit_buttons > button { margin: 0.5em auto; } @@ -238,53 +458,6 @@ button { text-shadow: 1px 2px 1px rgba(0, 0, 0, 0.85); } -/* ----------------------------------------------------------------------------- - Message boxes -------------------------------------------------------------------------------*/ - -.message { - position: relative; - margin: 0.5em auto; - padding: 0.5em; - width: 95%; -} - -.message .close { - width: 1em; - height: 1em; - position: absolute; - right: 0.5em; - top: 0.5em; - text-align: center; - vertical-align: middle; - line-height: 1em; -} - -.message .close:hover { - cursor: pointer; -} - -.message .icon { - left: 0.5em; - top: 0.5em; - margin-right: 1em; -} - -.message.error { - border: 1px solid #924949; - background: #f3e6e6; -} - -.message.success { - border: 1px solid #1f8454; - background: #70dda9; -} - -.message.info { - border: 1px solid #bfbe3a; - background: #FFFFCC; -} - /* ----------------------------------------------------------------------------- Anime-list-specific styles ------------------------------------------------------------------------------*/ @@ -384,4 +557,53 @@ button { top: calc(50% - 58.5px); left: 5px; left: calc(50% - 95px); +} + +/* ----------------------------------------------------------------------------- + Page-specific styles +------------------------------------------------------------------------------*/ + +.media.search > .name { + background-color: #555; + background-color: rgba(000,000,000,0.35); + background-size: cover; + background-size: contain; + background-repeat: no-repeat; +} + +.big-check { + display: none; +} + +.big-check:checked + label { + -webkit-transition: .25s ease; + transition: .25s ease; + background: rgba(0,0,0,0.75); +} + +.big-check:checked + label:after { + content: '✓'; + font-size: 15em; + font-size: 15rem; + text-align: center; + color: greenyellow; + position: absolute; + top: 5px; + left: 0; + height: 100%; + width: 100%; +} + +#series_list article.media { + position: relative; +} + +#series_list .name, +#series_list .name label { + position: absolute; + display: block; + top: 0; + height: 100%; + width: 100%; + vertical-align: middle; } \ No newline at end of file diff --git a/public/css/base.myth.css b/public/css/base.myth.css index f099f887..49828697 100644 --- a/public/css/base.myth.css +++ b/public/css/base.myth.css @@ -13,65 +13,51 @@ template {display:none} body {margin: 0.5em;} -a:hover, a:active { - color: var(--link-hover-color) +button { + background:rgba(255,255,255,0.65); + margin: 0; } table { - width:85%; + /*width:85%;*/ margin: 0 auto; } -tbody > tr:nth-child(odd) { - background: #ddd; +td { + padding:1em; + padding:1rem; } -/* Table sorting styles */ -th.sorting::after { - content: " ↕ "; -} -th.sorting_asc::after { - content: " ↑ "; -} -th.sorting_desc::after { - content: " ↓ "; +thead td, thead th { + padding:0.5em; + padding:0.5rem; + } input[type=number] { width: 4em; } -.form { width:100%; } -.form tr > td:nth-child(odd) { - text-align:right; - min-width:25px; - max-width:30%; -} -.form tr > td:nth-child(even) { - text-align:left; - min-width:70%; +tbody > tr:nth-child(odd) { + background: #ddd; } -.form thead th, .form thead tr { - background: inherit; - border:0; +a:hover, a:active { + color: var(--link-hover-color) } -.form.invisible tr:nth-child(odd) { - background: inherit; -} -.form.invisible tr, .form.invisible td, .form.invisible th { - border:0; -} +/* ----------------------------------------------------------------------------- + Utility classes +------------------------------------------------------------------------------*/ +.bracketed { + color: var(--edit-link-color); +} .bracketed, h1 a { text-shadow: var(--link-shadow); } .bracketed:before {content: '[\00a0'} .bracketed:after {content: '\00a0]'} -.bracketed { - color: var(--edit-link-color); -} .bracketed:hover, .bracketed:active { color: var(--edit-link-hover-color) } @@ -89,15 +75,202 @@ input[type=number] { font-size:1.6rem; } +.justify {text-align:justify} .align_center {text-align:center} -.align_left {text-align:left;} -.align_right {text-align:right;} +.align_left {text-align:left} +.align_right {text-align:right} + +.no_border {border:none} .media-wrap { text-align:center; margin:0 auto; } +/* ----------------------------------------------------------------------------- + CSS loading icon +------------------------------------------------------------------------------*/ + +.cssload-loader { + position: relative; + left: calc(50% - 31px); + width: 62px; + height: 62px; + border-radius: 50%; + perspective: 780px; +} + +.cssload-inner { + position: absolute; + width: 100%; + height: 100%; + box-sizing: border-box; + border-radius: 50%; +} + +.cssload-inner.cssload-one { + left: 0%; + top: 0%; + animation: cssload-rotate-one 1.15s linear infinite; + border-bottom: 3px solid rgb(0,0,0); +} + +.cssload-inner.cssload-two { + right: 0%; + top: 0%; + animation: cssload-rotate-two 1.15s linear infinite; + border-right: 3px solid rgb(0,0,0); +} + +.cssload-inner.cssload-three { + right: 0%; + bottom: 0%; + animation: cssload-rotate-three 1.15s linear infinite; + border-top: 3px solid rgb(0,0,0); +} + +@keyframes cssload-rotate-one { + 0% { + transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg); + } + 100% { + transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg); + } +} + +@keyframes cssload-rotate-two { + 0% { + transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg); + } + 100% { + transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg); + } +} + +@keyframes cssload-rotate-three { + 0% { + transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg); + } + 100% { + transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg); + } +} + +/* ----------------------------------------------------------------------------- + Table sorting and form styles +------------------------------------------------------------------------------*/ +.sorting, +/*.sorting::before,*/ +.sorting_asc, +/*.sorting_asc::before,*/ +.sorting_desc +/*.sorting_desc::before*/ { + vertical-align:text-bottom; +} +.sorting::before { + content: " ↕\00a0"; +} +.sorting_asc::before { + content: " ↑\00a0"; +} +.sorting_desc::before { + content: " ↓\00a0"; +} + +.form { width:100%; } + +.form thead th, .form thead tr { + background: inherit; + border:0; +} + +.form tr > td:nth-child(odd) { + text-align:right; + min-width:25px; + max-width:30%; +} +.form tr > td:nth-child(even) { + text-align:left; + min-width:70%; +} + +.form.invisible tr:nth-child(odd) { + background: inherit; +} +.form.invisible tr, .form.invisible td, .form.invisible th { + border:0; +} + +/* ----------------------------------------------------------------------------- + Message boxes +------------------------------------------------------------------------------*/ + +.message{ + position:relative; + margin:0.5em auto; + padding:0.5em; + width:95%; +} + +.message .close{ + width:1em; + height:1em; + position:absolute; + right:0.5em; + top:0.5em; + text-align:center; + vertical-align:middle; + line-height:1em; +} + +/*.message .close:after { + content: '☐'; +}*/ + +.message:hover .close:after { + content: '☒'; +} + +.message:hover { + cursor:pointer; +} + +.message .icon{ + left:0.5em; + top:0.5em; + margin-right:1em; +} + +.message.error{ + border:1px solid #924949; + background: #f3e6e6; +} + + .message.error .icon::after { + content: '✘'; + } + +.message.success{ + border:1px solid #1f8454; + background: #70dda9; +} + .message.success .icon::after { + content: '✔' + } + +.message.info{ + border:1px solid #bfbe3a; + background: #FFFFCC; +} + + .message.info .icon::after { + content: '⚠'; + } + +/* ----------------------------------------------------------------------------- + Base list styles +------------------------------------------------------------------------------*/ + .media { position:relative; vertical-align:top; @@ -108,11 +281,6 @@ input[type=number] { margin: var(--normal-padding); } -button { - background:rgba(255,255,255,0.65); - margin: 0; -} - .media .edit_buttons > button { margin:0.5em auto; } @@ -172,52 +340,7 @@ button { text-shadow: var(--shadow); } -/* ----------------------------------------------------------------------------- - Message boxes -------------------------------------------------------------------------------*/ -.message{ - position:relative; - margin:0.5em auto; - padding:0.5em; - width:95%; -} - -.message .close{ - width:1em; - height:1em; - position:absolute; - right:0.5em; - top:0.5em; - text-align:center; - vertical-align:middle; - line-height:1em; -} - -.message .close:hover { - cursor:pointer; -} - -.message .icon{ - left:0.5em; - top:0.5em; - margin-right:1em; -} - -.message.error{ - border:1px solid #924949; - background: #f3e6e6; -} - -.message.success{ - border:1px solid #1f8454; - background: #70dda9; -} - -.message.info{ - border:1px solid #bfbe3a; - background: #FFFFCC; -} /* ----------------------------------------------------------------------------- Anime-list-specific styles @@ -304,3 +427,52 @@ button { left: 5px; left: calc(50% - 95px); } + + +/* ----------------------------------------------------------------------------- + Page-specific styles +------------------------------------------------------------------------------*/ +.media.search > .name { + background-color:#555; + background-color: rgba(000,000,000,0.35); + background-size: cover; + background-size: contain; + background-repeat: no-repeat; +} + +.big-check { + display:none; +} + +.big-check:checked + label { + transition: .25s ease; + background:rgba(0,0,0,0.75); +} + +.big-check:checked + label:after { + content: '✓'; + font-size: 15em; + font-size: 15rem; + text-align:center; + color: greenyellow; + position:absolute; + top:5px; + left:0; + height:100%; + width:100%; +} + +#series_list article.media { + position:relative; +} +#series_list .name, #series_list .name label { + position:absolute; + display:block; + top:0; + height:100%; + width:100%; + vertical-align:middle; +} + + + diff --git a/public/css/marx.css b/public/css/marx.css index f5696df9..c1616f66 100644 --- a/public/css/marx.css +++ b/public/css/marx.css @@ -111,7 +111,6 @@ button, input, select, textarea { - /*background-color: transparent;*/ border: .1rem solid #ccc; color: inherit; font-family: inherit; @@ -507,7 +506,7 @@ textarea { input[type=submit], button { - background-color: transparent; + /*background-color: transparent;*/ border: .2rem solid #444; border-radius: 0; color: #444; diff --git a/public/css/marx.myth.css b/public/css/marx.myth.css index 07038a6b..d42cd5b4 100644 --- a/public/css/marx.myth.css +++ b/public/css/marx.myth.css @@ -78,7 +78,6 @@ audio, canvas, iframe, img, svg, video { vertical-align: middle; } button, input, select, textarea { - /*background-color: transparent;*/ border: .1rem solid #ccc; color: inherit; font-family: inherit; @@ -342,7 +341,7 @@ textarea { vertical-align: middle; } input[type=submit], button { - background-color: transparent; + /*background-color: transparent;*/ border: .2rem solid #444; border-radius: 0; color: #444; diff --git a/public/js.php b/public/js.php index 88890bf4..c97c7ab5 100644 --- a/public/js.php +++ b/public/js.php @@ -19,7 +19,7 @@ use GuzzleHttp\Psr7\Request; require_once('../app/config/minify_config.php'); //Include the js groups -$groups_file = "../app/config/minify_js_groups.php"; +$groups_file = '../app/config/minify_js_groups.php'; $groups = require_once($groups_file); // Include guzzle @@ -67,8 +67,9 @@ function google_min($new_file) 'output_info' => 'errors', 'output_format' => 'json', 'compilation_level' => 'SIMPLE_OPTIMIZATIONS', + //'compilation_level' => 'ADVANCED_OPTIMIZATIONS', 'js_code' => $new_file, - 'language' => 'ECMASCRIPT5', + 'language' => 'ECMASCRIPT6_STRICT', 'language_out' => 'ECMASCRIPT5_STRICT' ]; @@ -77,17 +78,18 @@ function google_min($new_file) $error_res = $error_client->post('http://closure-compiler.appspot.com/compile', [ 'headers' => [ 'Accept-Encoding' => 'gzip', - "Content-type" => "application/x-www-form-urlencoded" + 'Content-type' => 'application/x-www-form-urlencoded' ], 'form_params' => $options ]); $error_json = $error_res->getBody(); - $error_obj = json_decode($error_json); + $error_obj = json_decode($error_json) ?: (object)[]; + // Show error if exists if ( ! empty($error_obj->errors)) { - ?>
post('http://closure-compiler.appspot.com/compile', [ 'headers' => [ 'Accept-Encoding' => 'gzip', - "Content-type" => "application/x-www-form-urlencoded" + 'Content-type' => 'application/x-www-form-urlencoded' ], 'form_params' => $options ]); @@ -163,7 +165,7 @@ if(isset($groups[$_GET['g']])) } else //Nothing to display? Just exit { - die("You must specify a group that exists"); + die('You must specify a group that exists'); } // -------------------------------------------------------------------------- @@ -180,7 +182,7 @@ $requested_time=(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) // don't resend the file if($last_modified === $requested_time) { - header("HTTP/1.1 304 Not Modified"); + header('HTTP/1.1 304 Not Modified'); exit(); } @@ -188,7 +190,7 @@ if($last_modified === $requested_time) //Determine what to do: rebuild cache, send files as is, or send cache. // If debug is set, just concatenate -if(isset($_GET['debug'])) +if(array_key_exists('debug', $_GET)) { $js = get_files(); } @@ -199,7 +201,7 @@ else if($cache_modified < $last_modified) //Make sure cache file gets created/updated if(file_put_contents($cache_file, $js) === FALSE) { - die("Cache file was not created. Make sure you have the correct folder permissions."); + die('Cache file was not created. Make sure you have the correct folder permissions.'); } } // Otherwise, send the cached file @@ -212,13 +214,13 @@ else //This GZIPs the js for transmission to the user //making file size smaller and transfer rate quicker -ob_start("ob_gzhandler"); +ob_start('ob_gzhandler'); // Set important caching headers -header("Content-Type: application/javascript; 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"); +header('Content-Type: application/javascript; 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 $js; diff --git a/public/js/anime_collection.js b/public/js/anime_collection.js index db9c06d0..9b4b5864 100755 --- a/public/js/anime_collection.js +++ b/public/js/anime_collection.js @@ -1,17 +1,46 @@ -(function($, undefined) { +(($, AnimeClient) => { + + 'use strict'; function search(query, callback) { - $.get(BASE_URL + 'collection/search', {'query':query}, callback); + var endpoint = '//' + document.location.host + '/collection/search'; + return $.get(AnimeClient.url('/collection/search'), {'query':query}, callback); } - $("#search").on('keypress', $.throttle(750, function(e) { - var query = encodeURIComponent($(this).val()); - search(query, function(res) { - var template = $.templates("#show_list"); - var html = template.render(res); - $('#series_list').html(html); - }); - })); + $.get('/public/templates/ajax-search-results.html').done(tempHtml => { + $('#search').on('keypress', $.throttle(750, function(e) { + $('.cssload-loader').removeAttr('hidden'); + let query = encodeURIComponent($(this).val()); + $.get(AnimeClient.url('/collection/search'), {'query':query}).done((searchResults) => { + $('.cssload-loader').attr('hidden', 'hidden'); -}(jQuery)); \ No newline at end of file + // Give mustache a key to iterate over + searchResults = { + anime: searchResults + }; + + Mustache.parse(tempHtml); + $('#series_list').html(Mustache.render(tempHtml, searchResults)); + }).fail(() => { + $('.cssload-loader').attr('hidden', 'hidden'); + }); + })); + }); + + /*$.get('/public/templates/ajax-search-results.html', tempHtml => { + $('#search').on('keypress', $.throttle(750, function(e) { + var query = encodeURIComponent($(this).val()); + search(query, function(searchResults) { + // Give mustache a key to iterate over + searchResults = { + anime: searchResults + }; + + Mustache.parse(tempHtml); + var rendered = Mustache.render(tempHtml, searchResults); + $('#series_list').html(rendered); + }); + })); + });*/ +})(jQuery, AnimeClient); \ No newline at end of file diff --git a/public/js/anime_edit.js b/public/js/anime_edit.js index abf82705..c7ab73ee 100755 --- a/public/js/anime_edit.js +++ b/public/js/anime_edit.js @@ -1,42 +1,38 @@ /** * Javascript for editing anime, if logged in */ -(function($){ +(($, AnimeClient, w) => { - "use strict"; - - if (CONTROLLER !== "anime") return; + 'use strict'; // Action to increment episode count - $(".plus_one").on("click", function(e) { - e.stopPropagation(); + $('body.anime.list').on('click', '.plus_one', function(e) { + //e.stopPropagation(); - var self = this; - var this_sel = $(this); - var parent_sel = $(this).closest("article, td"); + let self = this; + let this_sel = $(this); + let parent_sel = $(this).closest('article, td'); - var watched_count = parseInt(parent_sel.find('.completed_number').text(), 10); - var total_count = parseInt(parent_sel.find('.total_number').text(), 10); - var title = parent_sel.find('.name a').text(); + let watched_count = parseInt(parent_sel.find('.completed_number').text(), 10); + let total_count = parseInt(parent_sel.find('.total_number').text(), 10); + let title = parent_sel.find('.name a').text(); // Setup the update data - var data = { + let data = { id: this_sel.parent('article, td').attr('id'), increment_episodes: true }; // If the episode count is 0, and incremented, // change status to currently watching - if (isNaN(watched_count) || watched_count === 0) - { - data.status = "currently-watching"; + if (isNaN(watched_count) || watched_count === 0) { + data.status = 'currently-watching'; } // If you increment at the last episode, mark as completed - if (( ! isNaN(watched_count)) && (watched_count + 1) === total_count) - { + if (( ! isNaN(watched_count)) && (watched_count + 1) === total_count) { delete data.increment_episodes; - data.status = "completed"; + data.status = 'completed'; } // okay, lets actually make some changes! @@ -45,18 +41,20 @@ dataType: 'json', method: 'POST', mimeType: 'application/json', - url: BASE_URL + CONTROLLER + '/update' - }).done(function(res) { - if (res.status === 'completed') - { - $(self).closest('article, tr').hide(); + url: AnimeClient.url('/anime/update'), + }).done((res) => { + if (res.status === 'completed') { + $(this).closest('article, tr').hide(); } - add_message('success', "Sucessfully updated " + title); + AnimeClient.showMessage('success', `Sucessfully updated ${title}`); parent_sel.find('.completed_number').text(++watched_count); - }).fail(function() { - add_message('error', "Failed to updated " + title); + + // scroll to top + w.scroll(0,0); + }).fail(() => { + AnimeClient.showMessage('error', `Failed to updated ${title}`); }); }); -}(jQuery)); \ No newline at end of file +})(jQuery, AnimeClient, window); \ No newline at end of file diff --git a/public/js/base.js b/public/js/base.js new file mode 100644 index 00000000..e645292a --- /dev/null +++ b/public/js/base.js @@ -0,0 +1,45 @@ +const AnimeClient = (function($) { + + 'use strict'; + + return { + /** + * Display a message box + * + * @param {String} type - message type: info, error, success + * @param {String} message - the message itself + * @return {void} + */ + showMessage(type, message) { + let template = ` +
+ + ${message} + +
`; + + if ($(".message").length > 0) + { + $(".message").replaceWith(template); + $(".message").show(); + } + else + { + $("header").append(template); + } + }, + /** + * Generate a full url from a relative path + * + * @param {String} path - url path + * @return {String} - full url + */ + url(path) { + let uri = `//${document.location.host}`; + uri += (path.charAt(0) === '/') ? path : `/${path}`; + + return uri; + }, + }; + +})(jQuery); \ No newline at end of file diff --git a/public/js/events.js b/public/js/events.js new file mode 100644 index 00000000..3b8ace39 --- /dev/null +++ b/public/js/events.js @@ -0,0 +1,13 @@ +/** + * jQuery event handlers + */ +(($) => { + + 'use strict'; + + // Close event for messages + $('header').on('click', '.message', function() { + $(this).hide(); + }); + +})(jQuery); \ No newline at end of file diff --git a/public/js/lib/datatables.js b/public/js/lib/datatables.js deleted file mode 100644 index 7ae37e49..00000000 --- a/public/js/lib/datatables.js +++ /dev/null @@ -1,15226 +0,0 @@ -/* - * This combined file was created by the DataTables downloader builder: - * https://datatables.net/download - * - * To rebuild or modify this file with the latest versions of the included - * software please visit: - * https://datatables.net/download/#dt/dt-1.10.10 - * - * Included libraries: - * DataTables 1.10.10 - */ - -/*! DataTables 1.10.10 - * ©2008-2015 SpryMedia Ltd - datatables.net/license - */ - -/** - * @summary DataTables - * @description Paginate, search and order HTML tables - * @version 1.10.10 - * @file jquery.dataTables.js - * @author SpryMedia Ltd (www.sprymedia.co.uk) - * @contact www.sprymedia.co.uk/contact - * @copyright Copyright 2008-2015 SpryMedia Ltd. - * - * This source file is free software, available under the following license: - * MIT license - http://datatables.net/license - * - * This source file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. - * - * For details please refer to: http://www.datatables.net - */ - -/*jslint evil: true, undef: true, browser: true */ -/*globals $,require,jQuery,define,_selector_run,_selector_opts,_selector_first,_selector_row_indexes,_ext,_Api,_api_register,_api_registerPlural,_re_new_lines,_re_html,_re_formatted_numeric,_re_escape_regex,_empty,_intVal,_numToDecimal,_isNumber,_isHtml,_htmlNumeric,_pluck,_pluck_order,_range,_stripHtml,_unique,_fnBuildAjax,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAjaxDataSrc,_fnAddColumn,_fnColumnOptions,_fnAdjustColumnSizing,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnVisbleColumns,_fnGetColumns,_fnColumnTypes,_fnApplyColumnDefs,_fnHungarianMap,_fnCamelToHungarian,_fnLanguageCompat,_fnBrowserDetect,_fnAddData,_fnAddTr,_fnNodeToDataIndex,_fnNodeToColumnIndex,_fnGetCellData,_fnSetCellData,_fnSplitObjNotation,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnGetDataMaster,_fnClearTable,_fnDeleteIndex,_fnInvalidate,_fnGetRowElements,_fnCreateTr,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAddOptionsHtml,_fnDetectHeader,_fnGetUniqueThs,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnFilterCreateSearch,_fnEscapeRegex,_fnFilterData,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnInfoMacros,_fnInitialise,_fnInitComplete,_fnLengthChange,_fnFeatureHtmlLength,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnFeatureHtmlTable,_fnScrollDraw,_fnApplyToChildren,_fnCalculateColumnWidths,_fnThrottle,_fnConvertToWidth,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/ - -(function( factory ) { - "use strict"; - - if ( typeof define === 'function' && define.amd ) { - // AMD - define( ['jquery'], function ( $ ) { - return factory( $, window, document ); - } ); - } - else if ( typeof exports === 'object' ) { - // CommonJS - module.exports = function (root, $) { - if ( ! root ) { - // CommonJS environments without a window global must pass a - // root. This will give an error otherwise - root = window; - } - - if ( ! $ ) { - $ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window - require('jquery') : - require('jquery')( root ); - } - - return factory( $, root, root.document ); - }; - } - else { - // Browser - factory( jQuery, window, document ); - } -} -(function( $, window, document, undefined ) { - "use strict"; - - /** - * DataTables is a plug-in for the jQuery Javascript library. It is a highly - * flexible tool, based upon the foundations of progressive enhancement, - * which will add advanced interaction controls to any HTML table. For a - * full list of features please refer to - * [DataTables.net](href="http://datatables.net). - * - * Note that the `DataTable` object is not a global variable but is aliased - * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may - * be accessed. - * - * @class - * @param {object} [init={}] Configuration object for DataTables. Options - * are defined by {@link DataTable.defaults} - * @requires jQuery 1.7+ - * - * @example - * // Basic initialisation - * $(document).ready( function { - * $('#example').dataTable(); - * } ); - * - * @example - * // Initialisation with configuration options - in this case, disable - * // pagination and sorting. - * $(document).ready( function { - * $('#example').dataTable( { - * "paginate": false, - * "sort": false - * } ); - * } ); - */ - var DataTable; - - - /* - * It is useful to have variables which are scoped locally so only the - * DataTables functions can access them and they don't leak into global space. - * At the same time these functions are often useful over multiple files in the - * core and API, so we list, or at least document, all variables which are used - * by DataTables as private variables here. This also ensures that there is no - * clashing of variable names and that they can easily referenced for reuse. - */ - - - // Defined else where - // _selector_run - // _selector_opts - // _selector_first - // _selector_row_indexes - - var _ext; // DataTable.ext - var _Api; // DataTable.Api - var _api_register; // DataTable.Api.register - var _api_registerPlural; // DataTable.Api.registerPlural - - var _re_dic = {}; - var _re_new_lines = /[\r\n]/g; - var _re_html = /<.*?>/g; - var _re_date_start = /^[\w\+\-]/; - var _re_date_end = /[\w\+\-]$/; - - // Escape regular expression special characters - var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' ); - - // http://en.wikipedia.org/wiki/Foreign_exchange_market - // - \u20BD - Russian ruble. - // - \u20a9 - South Korean Won - // - \u20BA - Turkish Lira - // - \u20B9 - Indian Rupee - // - R - Brazil (R$) and South Africa - // - fr - Swiss Franc - // - kr - Swedish krona, Norwegian krone and Danish krone - // - \u2009 is thin space and \u202F is narrow no-break space, both used in many - // standards as thousands separators. - var _re_formatted_numeric = /[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfk]/gi; - - - var _empty = function ( d ) { - return !d || d === true || d === '-' ? true : false; - }; - - - var _intVal = function ( s ) { - var integer = parseInt( s, 10 ); - return !isNaN(integer) && isFinite(s) ? integer : null; - }; - - // Convert from a formatted number with characters other than `.` as the - // decimal place, to a Javascript number - var _numToDecimal = function ( num, decimalPoint ) { - // Cache created regular expressions for speed as this function is called often - if ( ! _re_dic[ decimalPoint ] ) { - _re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' ); - } - return typeof num === 'string' && decimalPoint !== '.' ? - num.replace( /\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) : - num; - }; - - - var _isNumber = function ( d, decimalPoint, formatted ) { - var strType = typeof d === 'string'; - - // If empty return immediately so there must be a number if it is a - // formatted string (this stops the string "k", or "kr", etc being detected - // as a formatted number for currency - if ( _empty( d ) ) { - return true; - } - - if ( decimalPoint && strType ) { - d = _numToDecimal( d, decimalPoint ); - } - - if ( formatted && strType ) { - d = d.replace( _re_formatted_numeric, '' ); - } - - return !isNaN( parseFloat(d) ) && isFinite( d ); - }; - - - // A string without HTML in it can be considered to be HTML still - var _isHtml = function ( d ) { - return _empty( d ) || typeof d === 'string'; - }; - - - var _htmlNumeric = function ( d, decimalPoint, formatted ) { - if ( _empty( d ) ) { - return true; - } - - var html = _isHtml( d ); - return ! html ? - null : - _isNumber( _stripHtml( d ), decimalPoint, formatted ) ? - true : - null; - }; - - - var _pluck = function ( a, prop, prop2 ) { - var out = []; - var i=0, ien=a.length; - - // Could have the test in the loop for slightly smaller code, but speed - // is essential here - if ( prop2 !== undefined ) { - for ( ; i') - .css( { - position: 'fixed', - top: 0, - left: 0, - height: 1, - width: 1, - overflow: 'hidden' - } ) - .append( - $('
') - .css( { - position: 'absolute', - top: 1, - left: 1, - width: 100, - overflow: 'scroll' - } ) - .append( - $('
') - .css( { - width: '100%', - height: 10 - } ) - ) - ) - .appendTo( 'body' ); - - var outer = n.children(); - var inner = outer.children(); - - // Numbers below, in order, are: - // inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth - // - // IE6 XP: 100 100 100 83 - // IE7 Vista: 100 100 100 83 - // IE 8+ Windows: 83 83 100 83 - // Evergreen Windows: 83 83 100 83 - // Evergreen Mac with scrollbars: 85 85 100 85 - // Evergreen Mac without scrollbars: 100 100 100 100 - - // Get scrollbar width - browser.barWidth = outer[0].offsetWidth - outer[0].clientWidth; - - // IE6/7 will oversize a width 100% element inside a scrolling element, to - // include the width of the scrollbar, while other browsers ensure the inner - // element is contained without forcing scrolling - browser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100; - - // In rtl text layout, some browsers (most, but not all) will place the - // scrollbar on the left, rather than the right. - browser.bScrollbarLeft = Math.round( inner.offset().left ) !== 1; - - // IE8- don't provide height and width for getBoundingClientRect - browser.bBounding = n[0].getBoundingClientRect().width ? true : false; - - n.remove(); - } - - $.extend( settings.oBrowser, DataTable.__browser ); - settings.oScroll.iBarWidth = DataTable.__browser.barWidth; - } - - - /** - * Array.prototype reduce[Right] method, used for browsers which don't support - * JS 1.6. Done this way to reduce code size, since we iterate either way - * @param {object} settings dataTables settings object - * @memberof DataTable#oApi - */ - function _fnReduce ( that, fn, init, start, end, inc ) - { - var - i = start, - value, - isSet = false; - - if ( init !== undefined ) { - value = init; - isSet = true; - } - - while ( i !== end ) { - if ( ! that.hasOwnProperty(i) ) { - continue; - } - - value = isSet ? - fn( value, that[i], i, that ) : - that[i]; - - isSet = true; - i += inc; - } - - return value; - } - - /** - * Add a column to the list used for the table with default values - * @param {object} oSettings dataTables settings object - * @param {node} nTh The th element for this column - * @memberof DataTable#oApi - */ - function _fnAddColumn( oSettings, nTh ) - { - // Add column to aoColumns array - var oDefaults = DataTable.defaults.column; - var iCol = oSettings.aoColumns.length; - var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, { - "nTh": nTh ? nTh : document.createElement('th'), - "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '', - "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol], - "mData": oDefaults.mData ? oDefaults.mData : iCol, - idx: iCol - } ); - oSettings.aoColumns.push( oCol ); - - // Add search object for column specific search. Note that the `searchCols[ iCol ]` - // passed into extend can be undefined. This allows the user to give a default - // with only some of the parameters defined, and also not give a default - var searchCols = oSettings.aoPreSearchCols; - searchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] ); - - // Use the default column options function to initialise classes etc - _fnColumnOptions( oSettings, iCol, $(nTh).data() ); - } - - - /** - * Apply options for a column - * @param {object} oSettings dataTables settings object - * @param {int} iCol column index to consider - * @param {object} oOptions object with sType, bVisible and bSearchable etc - * @memberof DataTable#oApi - */ - function _fnColumnOptions( oSettings, iCol, oOptions ) - { - var oCol = oSettings.aoColumns[ iCol ]; - var oClasses = oSettings.oClasses; - var th = $(oCol.nTh); - - // Try to get width information from the DOM. We can't get it from CSS - // as we'd need to parse the CSS stylesheet. `width` option can override - if ( ! oCol.sWidthOrig ) { - // Width attribute - oCol.sWidthOrig = th.attr('width') || null; - - // Style attribute - var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%]+)/); - if ( t ) { - oCol.sWidthOrig = t[1]; - } - } - - /* User specified column options */ - if ( oOptions !== undefined && oOptions !== null ) - { - // Backwards compatibility - _fnCompatCols( oOptions ); - - // Map camel case parameters to their Hungarian counterparts - _fnCamelToHungarian( DataTable.defaults.column, oOptions ); - - /* Backwards compatibility for mDataProp */ - if ( oOptions.mDataProp !== undefined && !oOptions.mData ) - { - oOptions.mData = oOptions.mDataProp; - } - - if ( oOptions.sType ) - { - oCol._sManualType = oOptions.sType; - } - - // `class` is a reserved word in Javascript, so we need to provide - // the ability to use a valid name for the camel case input - if ( oOptions.className && ! oOptions.sClass ) - { - oOptions.sClass = oOptions.className; - } - - $.extend( oCol, oOptions ); - _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" ); - - /* iDataSort to be applied (backwards compatibility), but aDataSort will take - * priority if defined - */ - if ( oOptions.iDataSort !== undefined ) - { - oCol.aDataSort = [ oOptions.iDataSort ]; - } - _fnMap( oCol, oOptions, "aDataSort" ); - } - - /* Cache the data get and set functions for speed */ - var mDataSrc = oCol.mData; - var mData = _fnGetObjectDataFn( mDataSrc ); - var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null; - - var attrTest = function( src ) { - return typeof src === 'string' && src.indexOf('@') !== -1; - }; - oCol._bAttrSrc = $.isPlainObject( mDataSrc ) && ( - attrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter) - ); - - oCol.fnGetData = function (rowData, type, meta) { - var innerData = mData( rowData, type, undefined, meta ); - - return mRender && type ? - mRender( innerData, type, rowData, meta ) : - innerData; - }; - oCol.fnSetData = function ( rowData, val, meta ) { - return _fnSetObjectDataFn( mDataSrc )( rowData, val, meta ); - }; - - // Indicate if DataTables should read DOM data as an object or array - // Used in _fnGetRowElements - if ( typeof mDataSrc !== 'number' ) { - oSettings._rowReadObject = true; - } - - /* Feature sorting overrides column specific when off */ - if ( !oSettings.oFeatures.bSort ) - { - oCol.bSortable = false; - th.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called - } - - /* Check that the class assignment is correct for sorting */ - var bAsc = $.inArray('asc', oCol.asSorting) !== -1; - var bDesc = $.inArray('desc', oCol.asSorting) !== -1; - if ( !oCol.bSortable || (!bAsc && !bDesc) ) - { - oCol.sSortingClass = oClasses.sSortableNone; - oCol.sSortingClassJUI = ""; - } - else if ( bAsc && !bDesc ) - { - oCol.sSortingClass = oClasses.sSortableAsc; - oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed; - } - else if ( !bAsc && bDesc ) - { - oCol.sSortingClass = oClasses.sSortableDesc; - oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed; - } - else - { - oCol.sSortingClass = oClasses.sSortable; - oCol.sSortingClassJUI = oClasses.sSortJUI; - } - } - - - /** - * Adjust the table column widths for new data. Note: you would probably want to - * do a redraw after calling this function! - * @param {object} settings dataTables settings object - * @memberof DataTable#oApi - */ - function _fnAdjustColumnSizing ( settings ) - { - /* Not interested in doing column width calculation if auto-width is disabled */ - if ( settings.oFeatures.bAutoWidth !== false ) - { - var columns = settings.aoColumns; - - _fnCalculateColumnWidths( settings ); - for ( var i=0 , iLen=columns.length ; i