diff --git a/LICENSE.mdown b/LICENSE.mdown index 6267be9..eb791bb 100644 --- a/LICENSE.mdown +++ b/LICENSE.mdown @@ -1,7 +1,7 @@ License ======= -Copyright 2010 Dave Balmer, Jr. All rights reserved. +Copyright 2010-2013 Dave Balmer, Jr. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/README.mdown b/README.mdown index 3029343..a0739ee 100644 --- a/README.mdown +++ b/README.mdown @@ -43,16 +43,11 @@ Important files in the directory tree are: will need to build the library to make this file (as well as the un-minified version `jo.js` which is useful for debugging). -- `css/aluminum` +- `css/flattery/*` - This is a CSS3 bundle ready to ship your app with. Also serves as a good example + This is the new CSS3 bundle ready to ship your app with. Also serves as a good example of modern HTML5 styling capabilities. Looks pretty bad in IE up through version 8. -- `css/jo.css` - - This is a newer base CSS theme for Jo, preferred over Aluminum for now. Built with - Less CSS compiler. - - `docs/*.mdown` These are supplimental doc files which are used by joDoc to build out the diff --git a/build b/build index 0b05804..0af5129 100755 --- a/build +++ b/build @@ -2,13 +2,13 @@ echo "Building jo.js" cd js/core -cat log.js _jo.js dom.js event.js subject.js time.js yield.js cache.js clipboard.js local.js > ../jo.js +cat log.js _jo.js dom.js event.js subject.js time.js yield.js cache.js clipboard.js local.js queue.js timer.js > ../jo.js cd ../data -cat datasource.js record.js database.js sqldatasource.js filesource.js script.js preference.js yql.js dispatch.js >> ../jo.js +cat datasource.js record.js database.js sqldatasource.js filesource.js script.js preference.js yql.js dispatch.js template.js >> ../jo.js cd ../ui -cat interface.js collect.js view.js container.js control.js button.js list.js busy.js caption.js card.js stack.js scroller.js divider.js expando.js expandotitle.js flexrow.js focus.js footer.js gesture.js group.js html.js input.js label.js menu.js option.js passwordinput.js popup.js screen.js shim.js sound.js stackscroller.js tabbar.js table.js textarea.js title.js toolbar.js form.js dialog.js selectlist.js navbar.js select.js toggle.js slider.js >> ../jo.js +cat interface.js collect.js view.js container.js control.js button.js list.js busy.js caption.js card.js stack.js scroller.js divider.js expando.js expandotitle.js flexrow.js focus.js footer.js gesture.js group.js html.js input.js label.js menu.js option.js passwordinput.js popup.js screen.js shim.js sound.js stackscroller.js tabbar.js table.js textarea.js title.js toolbar.js form.js dialog.js selectlist.js navbar.js select.js toggle.js slider.js image.js canvas.js >> ../jo.js cd .. echo "Done." diff --git a/build.bat b/build.bat index c4f492c..8acde01 100644 --- a/build.bat +++ b/build.bat @@ -6,13 +6,13 @@ goto wrongdir echo "Building js\jo.js" cd js\core -copy log.js + _jo.js + dom.js + event.js + subject.js + time.js + yield.js + cache.js + clipboard.js + local.js ..\jo_core.js +copy log.js + _jo.js + dom.js + event.js + subject.js + time.js + yield.js + cache.js + clipboard.js + local.js + timer.js + queue.js ..\jo_core.js cd ..\data -copy datasource.js + record.js + database.js + filesource.js + sqldatasource.js + script.js + preference.js + yql.js + dispatch.js ..\jo_data.js +copy datasource.js + record.js + database.js + filesource.js + sqldatasource.js + script.js + preference.js + yql.js + dispatch.js + template.js ..\jo_data.js cd ..\ui -copy collect.js + interface.js + view.js + container.js + control.js + button.js + list.js + busy.js + caption.js + card.js + stack.js + scroller.js + divider.js + expando.js + expandotitle.js + flexrow.js + focus.js + footer.js + gesture.js + group.js + html.js + input.js + label.js + menu.js + option.js + passwordinput.js + popup.js + screen.js + shim.js + sound.js + stackscroller.js + tabbar.js + table.js + textarea.js + title.js + toolbar.js + form.js + dialog.js + selectlist.js + navbar.js + select.js + toggle.js + slider.js ..\jo_ui.js +copy collect.js + interface.js + view.js + container.js + control.js + button.js + list.js + busy.js + caption.js + card.js + stack.js + scroller.js + divider.js + expando.js + expandotitle.js + flexrow.js + focus.js + footer.js + gesture.js + group.js + html.js + input.js + label.js + menu.js + option.js + passwordinput.js + popup.js + screen.js + shim.js + sound.js + stackscroller.js + tabbar.js + table.js + textarea.js + title.js + toolbar.js + form.js + dialog.js + selectlist.js + navbar.js + select.js + toggle.js + slider.js + image.js + canvas.js ..\jo_ui.js cd .. diff --git a/css/bootstrap/jo.bootstrap.css b/css/bootstrap/jo.bootstrap.css index c4f7224..fa948a7 100644 --- a/css/bootstrap/jo.bootstrap.css +++ b/css/bootstrap/jo.bootstrap.css @@ -1005,3 +1005,31 @@ jobackbutton { border-color: #424242; font-size: 85%; } + +.nativescroll jostack { width: 100%; position: relative; } + +.nativescroll joscroller { + position: absolute; + display: block; + height: auto; + width: auto; + top: 0; left: 0; bottom: 0; right: 0; + overflow: auto; + padding: 0; + margin: 0; + -webkit-overflow-scrolling: touch; +} + +.nativescroll jocontainer { + height: inherit; +} + +.nativescroll joscroller { + display: block; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + diff --git a/css/flat/jo.flat.css b/css/flat/jo.flat.css index 60852e0..b2921cc 100644 --- a/css/flat/jo.flat.css +++ b/css/flat/jo.flat.css @@ -1001,3 +1001,31 @@ jobackbutton { border-color: #424242; font-size: 85%; } + +.nativescroll jostack { width: 100%; position: relative; } + +.nativescroll joscroller { + position: absolute; + display: block; + height: auto; + width: auto; + top: 0; left: 0; bottom: 0; right: 0; + overflow: auto; + padding: 0; + margin: 0; + -webkit-overflow-scrolling: touch; +} + +.nativescroll jocontainer { + height: inherit; +} + +.nativescroll joscroller { + display: block; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + diff --git a/css/flattery/README.md b/css/flattery/README.md new file mode 100644 index 0000000..bba5973 --- /dev/null +++ b/css/flattery/README.md @@ -0,0 +1,26 @@ +Jo Flattery Theme +================= + +Clean, flat design style which uses a custom font for glyphs and no image files. + +- Simple cross-platform unified look for your app +- Fast load time +- Quick render time +- Easy to customize +- Easy to scale +- Includes commonly-used glyphs in the custom font created with icomoon (feel +free to create your own) + +Required Files +-------------- + +`jo-flattery.css` Main CSS file +`jo-flattery.ttf` Glyph font +`jo-flattery.woff` Glyph font for older MSIE browsers (and WP8) + +Build File +---------- + +`jo.flattery.less` requires less.js to build. Easy to tweak style preferences +to suit your project (e.g. colors, size, spacing, rounding, borders). + diff --git a/css/flattery/jo-flattery.css b/css/flattery/jo-flattery.css new file mode 100644 index 0000000..6fb98ab --- /dev/null +++ b/css/flattery/jo-flattery.css @@ -0,0 +1,1021 @@ +@font-face { + font-family: 'jo-flattery'; + src: url('jo-flattery.eot'); + src: url('jo-flattery.eot?#iefix') format('embedded-opentype'), url('jo-flattery.ttf') format('truetype'), url('jo-flattery.woff') format('woff'); + font-weight: normal; + font-style: normal; +} +::selection { + background: #4f5b98; + /* Safari */ + color: #fff; +} +::-moz-selection { + background: #4f5b98; + /* Firefox */ + color: #fff; +} +body { + margin: 0; + padding: 0; + background: #ffffff; + word-wrap: break-word; + overflow: hidden; + font: normal 14px "Helvetica", "Droid Sans", "Trebuchet MS"; +} +jobutton, +joview, +jolist, +jolistitem, +jomenu, +jomenuitem, +joexpando, +joexpandotitle, +jogroup, +jocard, +jostack, +jotitle, +jocaption, +jolabel, +jodivider, +joinput, +input, +textarea, +jotextarea, +jooption, +jooptionitem, +jonavbar, +jocontainer, +jotoggle, +joslider, +josliderthumb { + display: block; + margin: 0; + padding: 0; + -webkit-user-select: none; + -moz-user-select: none; + -o-user-select: none; + user-select: none; + -webkit-background-clip: padding-box; + /* background: transparent; */ +} +/* +em, i, b, span, u, a, button, input { + display: inline; +} +*/ +.noflex { + -webkit-box-flex: 0; + -moz-box-flex: 0; + -o-box-flex: 0; + box-flex: 0; +} +.flexible { + -webkit-box-flex: 1; + -moz-box-flex: 1; + -o-box-flex: 1; + box-flex: 1; +} +jobutton, +jooptionitem, +joexpandotitle { + overflow: hidden; +} +.flex { + display: block; + display: -webkit-box; + display: -moz-box; + display: -o-box; + display: box; + margin: 0; + -moz-box-align: stretch; + -o-box-align: stretch; + box-align: stretch; +} +.listitem { + border-top: 1px solid rgba(0, 0, 0, 0.4); + margin: 0; + padding: 1em; + cursor: pointer; +} +.widgety { + color: rgba(255, 255, 255, 0.9); + background-color: #c5c5c5; + font-weight: normal; + cursor: pointer; + outline: none; + outline-color: transparent; + padding: 1em 0; +} +.shiny { + color: rgba(255, 255, 255, 0.9); + background-color: #c5c5c5; + font-weight: normal; + cursor: pointer; + outline: none; + outline-color: transparent; + padding: 1em 0; +} +.matte { + color: rgba(255, 255, 255, 0.9); + background-color: #c5c5c5; + font-weight: normal; + cursor: pointer; + outline: none; + outline-color: transparent; + padding: 1em 0; +} +.stretch-full { + display: block; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} +.widget { + margin: 0px 1em 1em 1em; +} +.selected { + background-color: #4f5b98; + color: #fffeff; +} +.focus { + background-color: #fff; +} +jooptionitem:last-child { + -webkit-border-radius: 0; + -webkit-border-top-right-radius: 1.5em; + -webkit-border-bottom-right-radius: 1.5em; + -moz-border-radius: 0 1.5em 1.5em 0; + border-radius: 0 1.5em 1.5em 0; +} +jobutton { + display: block; + text-align: center; + color: #fff; + background: #333; + font-weight: normal; + cursor: pointer; + outline: none; + outline-color: transparent; + height: 3em; + line-height: 3em; + -webkit-border-radius: 1.5em; + -moz-border-radius: 1.5em; + border-radius: 1.5em; +} +jobutton .focus { + background-color: #4f5b98; +} +jooption { + display: block; + display: -webkit-box; + display: -moz-box; + display: -o-box; + display: box; + -moz-box-align: stretch; + -o-box-align: stretch; + box-align: stretch; + margin: 0px 1em 1em 1em; +} +jooptionitem { + color: #000; + background-color: #c5c5c5; + font-weight: normal; + cursor: pointer; + outline: none; + outline-color: transparent; + padding: 0 1.5em; + -webkit-box-flex: 1; + -moz-box-flex: 1; + -o-box-flex: 1; + box-flex: 1; + text-align: center; + margin: 0; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + height: 3em; + line-height: 2.6em; + border-left: 0.2em solid #999999; + border-top: 0.2em solid #999999; + border-bottom: 0.2em solid #999999; +} +jooptionitem:first-child { + -webkit-border-radius: 0; + -webkit-border-top-left-radius: 1.5em; + -webkit-border-bottom-left-radius: 1.5em; + -moz-border-radius: 1.5em 0 0 1.5em; + border-radius: 1.5em 0 0 1.5em; +} +jooptionitem:last-child { + border-right: 0.2em solid #999999; + -webkit-border-radius: 0; + -webkit-border-top-right-radius: 1.5em; + -webkit-border-bottom-right-radius: 1.5em; + -moz-border-radius: 0 1.5em 1.5em 0; + border-radius: 0 1.5em 1.5em 0; +} +jobutton, +input, +jolabel, +textarea, +joexpando { + margin: 0px 1em 1em 1em; +} +jotitle { + background-color: #b8b8b8; + font-weight: normal; + cursor: pointer; + outline: none; + outline-color: transparent; + text-align: center; + padding: 1em; + font-size: 120%; + margin: 0; + border-left: none; + border-right: none; + border-bottom: 1px solid #858585; + border-top: 1px solid #d8d8d8; + color: #3c3c3c; +} +*:focus { + outline: none; +} +jolistitem, +jomenuitem { + border-top: 1px solid #ebebeb; + margin: 0; + padding: 1em; + cursor: pointer; + border-bottom: 1px solid #6d6d6d; +} +jolistitem.selected, +jomenuitem.selected { + border-color: #333; +} +jomenuitem:last-child { + border-bottom: 1px solid #666; +} +jobutton.focus { + background-color: #4f5b98; + background-image: none; +} +joselect.focus { + background-color: transparent; +} +jolist { + margin: 0; +} +joselectlist, +joexpandocontent { + display: block; + border-top: none; + -webkit-border-radius: 0; + -webkit-border-bottom-right-radius: 1.5em; + -webkit-border-bottom-left-radius: 1.5em; + -moz-border-radius: 0 0 1.5em 1.5em; + border-radius: 0 0 1.5em 1.5em; + background-color: rgba(255, 255, 255, 0.6); +} +joexpando { + display: block; + padding-bottom: 0px; + margin-bottom: 0; +} +joexpando.open { + margin-bottom: 1em; +} +joexpandocontent { + padding-top: 1em; +} +joselectlist > *:last-child { + border-bottom: none; + -webkit-border-radius: 0; + -webkit-border-bottom-right-radius: 1.5em; + -webkit-border-bottom-left-radius: 1.5em; + -moz-border-radius: 0 0 1.5em 1.5em; + border-radius: 0 0 1.5em 1.5em; +} +joselectlist > *:last-child.select { + border-bottom: none; + -webkit-border-radius: 0; + -webkit-border-bottom-right-radius: 1.5em; + -webkit-border-bottom-left-radius: 1.5em; + -moz-border-radius: 0 0 1.5em 1.5em; + border-radius: 0 0 1.5em 1.5em; +} +joselectlist > *.first-child { + border-top: none; +} +jocard > jolist, +jocard > jomenu { + margin: 0; +} +joinput.password, +input.password { + -webkit-text-security: disc; + -moz-text-security: disc; + -o-text-security: disc; + text-security: disc; +} +joinput, +jotextarea, +input, +textarea { + cursor: text; + display: block; + -webkit-border-radius: 0.2em; + -moz-border-radius: 0.2em; + border-radius: 0.2em; + margin: 0 1em 1em 1em; + padding: 0.75em; + background: #e7e6e7; + /* white-space: nowrap; */ + font-size: 105%; + overflow: hidden; + outline: none; + -webkit-user-select: text; + -moz-user-select: text; + user-select: text; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + border: 0.2em solid #999999; +} +jolist, +jomenu { + font-size: 110%; +} +jotextarea, +textarea { + white-space: normal; +} +joinput.disabled, +jotextarea.disabled, +input.disabled, +textarea.disabled { + color: #666; + cursor: text; +} +joexpandotitle joicon { + position: absolute; + border-radius: 0 1.5em 1.5em 0; + background: none; + border: none; + text-align: center; + display: block; + height: 3em; + width: 3em; + line-height: 2.6em; + right: 0; + top: 0; + -webkit-transform-origin: 50% 50% 0; + -webkit-transform: rotatez(0); + -webkit-transition: -webkit-transform 0.2s ease-out; + -moz-transform-origin: 50% 50% 0; + -moz-transform: rotate(0); + -moz-transition: -moz-transform 0.2s ease-out; + -o-transform-origin: 50% 50% 0; + -o-transform: rotate(0); + -o-transition: -o-transform 0.2s ease-out; + -ms-transform-origin: 50% 50% 0; + -ms-transform: rotate(0); + -ms-transition: -ms-transform 0.2s ease-out; +} +joexpando joicon:after { + content: ">"; + font-family: "jo-flattery"; +} +joexpando.open > joexpandotitle joicon { + -webkit-transform: rotatez(90deg); + -moz-transform: rotate(90deg); + -o-transform: rotate(90deg); + -ms-transform: rotate(90deg); +} +joexpando > *:last-child { + height: 0; + overflow: hidden; + opacity: 0; + display: none; + margin-top: 0; + margin-bottom: 0; +} +joexpando.open > *:last-child { + height: 100%; + overflow: visible; + opacity: 1; + display: block; +} +joexpando > *:first-child { + -webkit-transform: none; + opacity: 1; + overflow: visible; +} +joexpandotitle { + color: #000; + position: relative; + background-color: #c5c5c5; + font-weight: normal; + outline: none; + outline-color: transparent; + height: 3em; + line-height: 2.6em; + padding: 0 1em; + -webkit-border-radius: 1.5em; + -moz-border-radius: 1.5em; + border-radius: 1.5em; + cursor: pointer; + text-align: left; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + border: 0.2em solid #999999; +} +joexpando.open > *:first-child { + background-color: #6d6d6d; + -webkit-border-radius: 0; + -webkit-border-top-right-radius: 1.5em; + -webkit-border-top-left-radius: 1.5em; + -moz-border-radius: 1.5em 1.5em 0 0; + border-radius: 1.5em 1.5em 0 0; + color: #fff; +} +jolabel, +label { + margin-bottom: 5px; +} +jocaption { + margin: 1em; +} +johtml { + display: block; + margin: 0 1em 1em 1em; + padding: 0; +} +jodivider { + border-top: 1px solid rgba(0, 0, 0, 0.2); + border-bottom: 1px solid rgba(255, 255, 255, 0.2); + margin: 0 0 1em 0; + text-align: center; + height: 0; + display: block; +} +joflexrow > jotoggle { + -webkit-box-flex: 0; + -moz-box-flex: 0; + -o-box-flex: 0; + box-flex: 0; +} +jotoggle { + cursor: pointer; + display: block; + margin: 1em 1em 0 1em; + -webkit-border-radius: 1.5em; + -moz-border-radius: 1.5em; + border-radius: 1.5em; + background-color: #999; + position: relative; + width: 9em; + height: 3em; + line-height: 3em; +} +jotoggle > * { + color: #000; + background-color: #c5c5c5; + font-weight: normal; + cursor: pointer; + outline: none; + outline-color: transparent; + text-align: center; + -webkit-border-radius: 1.5em; + -moz-border-radius: 1.5em; + border-radius: 1.5em; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + height: 3em; + line-height: 2.6em; + border: 0.2em solid #999999; + width: 6em; + -webkit-transition: -webkit-transform 0.1s ease, background 0.1s ease; + -moz-transition: -moz-transform 0.1s ease, background 0.1s ease; + -o-transition: -o-transform 0.1s ease, background 0.1s ease; + -ms-transition: -ms-transform 0.1s ease, background 0.1s ease; + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translatex(0em); + -o-transform: translatex(0em); + -ms-transform: translatex(0em); + -webkit-animation-fill-mode: forwards; +} +jotoggle.on > * { + color: #fff; + background-color: #4f5b98; + -webkit-transform: translate3d(3em, 0, 0); + -moz-transform: translatex(3em); + -o-transform: translatex(3em); + -ms-transform: translatex(3em); +} +jotable { + display: block; + margin: 0 1em; +} +tr { + margin: 0; +} +th { + text-align: left; + padding: 5px; +} +td { + padding: 5px; +} +jolabel.left { + margin-top: 1em; + padding: 9px 0; +} +.disabled { + opacity: .2; +} +jotoolbar { + padding: 1em; +} +josliderthumb { + position: absolute; + height: 3em; + width: 6em; + color: rgba(255, 255, 255, 0.9); + background-color: #4f5b98; + font-weight: normal; + outline: none; + outline-color: transparent; + -webkit-border-radius: 1.5em; + -moz-border-radius: 1.5em; + border-radius: 1.5em; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + line-height: 2.6em; + border: 0.2em solid #999999; + -webkit-transition: left 0.1s ease; + -moz-transition: left 0.1s ease; + -o-transition: left 0.1s ease; + -ms-transition: left 0.1s ease; +} +joslider.live > josliderthumb { + -webkit-transition: none; + -moz-transition: none; + -o-transition: none; + -ms-transition: none; +} +joslider { + cursor: pointer; + background: #999; + margin: 1em; + position: relative; + height: 3em; + -webkit-border-radius: 1.5em; + -moz-border-radius: 1.5em; + border-radius: 1.5em; +} +joflexrow { + display: block; + display: -webkit-box; + display: -moz-box; + display: -o-box; + display: box; + margin: 0; + -moz-box-align: stretch; + -o-box-align: stretch; + box-align: stretch; + width: 100%; +} +joflexrow > * { + -webkit-box-flex: 1; + -moz-box-flex: 1; + -o-box-flex: 1; + box-flex: 1; + margin-right: 0; + position: relative; +} +joflexrow > *:last-child { + margin-right: 1em; +} +joflexcol { + display: block; + display: -webkit-box; + display: -moz-box; + display: -o-box; + display: box; + height: 100%; + width: 100%; + -webkit-box-orient: vertical; + -webkit-box-align: stretch; + -moz-box-orient: vertical; + -moz-box-align: stretch; + -o-box-orient: vertical; + -o-box-align: stretch; + box-orient: vertical; + box-align: stretch; + margin: 0; +} +joflexcol > * { + -webkit-box-flex: 1; + -moz-box-flex: 1; + -o-box-flex: 1; + box-flex: 1; +} +jotitle + joflexcol, +jotitle + joflexrow { + margin-top: 1em; +} +jostack { + height: 100%; + /* + -webkit-perspective: 0; + -moz-perspective: 0; + -o-perspective: 0; + -ms-perspective: 0; +*/ + -webkit-transition: opacity 0.2s ease-out; + -moz-transition: opacity 0.2s ease-out; + -o-transition: opacity 0.2s ease-out; + -ms-transition: opacity 0.2s ease-out; +} +jostack > * { + z-index: 0; + position: absolute; + -webkit-animation-fill-mode: forwards; + /* -webkit-transform-origin: 0 0 0; */ + -webkit-transform: translate3d(0, 0, 0); + -webkit-transition: -webkit-transform 0.2s ease-out, z-index 0.2s ease-out, height 0s ease, overflow 0s ease; + /* -moz-transform-origin: 0 0 0; */ + -moz-transform: translate3d(0, 0, 0); + -moz-transition: -moz-transform 0.2s ease-out, z-index 0.2s ease-out, height 0s ease, overflow 0s ease; + /* -o-transform-origin: 0 0 0; */ + -o-transform: translate3d(0, 0, 0); + -o-transition: -o-transform 0.2s ease-out; + /* -ms-transform-origin: 0 0 0; */ + -ms-transform: translate3d(0, 0, 0); + -ms-transition: -ms-transform 0.2s ease-out; + /* + display: block; + height: 100%; + width: 100%; + overflow: hidden; + padding: 0; + margin: 0; +*/ +} +jostack > .next { + z-index: -1; + -webkit-transform: translateX(100%); + -moz-transform: translateX(100%); + -o-transform: translateX(100%); + -ms-transform: translateX(100%); + height: 100%; + overflow: hidden; +} +jostack > .prev { + z-index: 1; + -webkit-transform: translateX(-100%); + -moz-transform: translateX(-100%); + -o-transform: translateX(-100%); + -ms-transform: translateX(-100%); + height: 100%; + overflow: hidden; +} +* { + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +jocard { + width: 100%; + min-height: 100%; + display: -webkit-box; + display: -moz-box; + display: -o-box; + display: box; + padding: 0; + margin: 0; + -webkit-box-orient: vertical; + -webkit-box-align: stretch; + -moz-box-orient: vertical; + -moz-box-align: stretch; + -o-box-orient: vertical; + -o-box-align: stretch; + box-orient: vertical; + box-align: stretch; + background: #ffffff; +} +jocard > * { + /* display: block; */ +} +jocard > *:last-child { + margin-bottom: 1em; +} +joscroller { + position: absolute; + display: block; + height: 100%; + width: 100%; + overflow: hidden; + padding: 0; + margin: 0; + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translatey(0); + -o-transform: translate(0, 0); + -ms-transform: translate(0, 0); +} +joscroller > * { + position: absolute; + top: 0; + -webkit-animation-fill-mode: forwards; + -webkit-transition: -webkit-transform 0s ease; + -moz-animation-fill-mode: forwards; + -moz-transition: -moz-transform 0s ease; + -o-animation-fill-mode: forwards; + -o-transition: -o-transform 0s ease; + -ms-animation-fill-mode: forwards; + -ms-transition: -ms-transform 0s ease; +} +.flick { + -webkit-transition: -webkit-transform 1.8s cubic-bezier(0, 0.2, 0, 1); + -moz-transition: -moz-transform 1.8s cubic-bezier(0, 0.2, 0, 1); + -o-transition: -o-transform 1.8s cubic-bezier(0, 0.2, 0, 1); + -ms-transition: -ms-transform 1.8s cubic-bezier(0, 0.2, 0, 1); +} +.flickback { + -webkit-transition: -webkit-transform 0.2s cubic-bezier(0, 0, 0.4, 1); + -moz-transition: -moz-transform 0.2s cubic-bezier(0, 0, 0.4, 1); + -o-transition: -o-transform 0.2s cubic-bezier(0, 0, 0.4, 1); + -ms-transition: -o-transform 0.2s cubic-bezier(0, 0, 0.4, 1); +} +.flickfast { + -webkit-transition: -webkit-transform 0.6s cubic-bezier(0, 0.2, 0, 1); + -moz-transition: -moz-transform 0.6s cubic-bezier(0, 0.2, 0, 1); + -o-transition: -o-transform 0.6s cubic-bezier(0, 0.2, 0, 1); +} +jocontainer { + margin: 0; + display: block; + position: relative; +} +jogroup { + margin: 1em; + padding: 1em 0; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + background: #eeeeee; +} +jogroup > *.last-child { + margin-bottom: 0; +} +jofooter { + display: block; + display: -webkit-box; + display: -moz-box; + display: box; + width: 100%; + -webkit-box-flex: 1; + -webkit-box-orient: vertical; + -webkit-box-align: stretch; + -webkit-box-pack: end; + -moz-box-flex: 1; + -moz-box-orient: vertical; + -moz-box-align: stretch; + -moz-box-pack: end; + box-flex: 1; + box-orient: vertical; + box-align: stretch; + box-pack: end; + margin: 0; +} +jofooter > * { + -webkit-box-align: end; + -moz-box-align: end; + -o-box-align: end; + box-align: end; +} +joshim { + overflow: hidden; + position: absolute; + z-index: 100; + top: 0; + left: 0; + right: 0; + bottom: 0; + display: none; + background: rgba(0, 0, 0, 0.8); + opacity: 0; + -webkit-transition: opacity .2s ease; + -moz-transition: opacity .2s ease; + -o-transition: opacity .2s ease; + -ms-transition: opacity .2s ease; +} +joshim.show { + display: block; + opacity: 1; +} +jotoolbar { + border-top: 1px solid rgba(0, 0, 0, 0.8); + padding: 1em 0; + color: rgba(255, 255, 255, 0.9); + background-color: rgba(0, 0, 0, 0.8); + font-weight: normal; + cursor: pointer; + outline: none; + outline-color: transparent; + z-index: 1; + position: absolute; + bottom: 0; + left: 0; + right: 0; + text-align: center; +} +jopopup { + -webkit-box-flex: 0; + -moz-box-flex: 0; + -o-box-flex: 0; + box-flex: 0; + display: block; + overflow: hidden; + border: 2px solid #434343; + -webkit-box-shadow: 0 0 20px rgba(0, 0, 0, 0.6); + -moz-box-shadow: 0 0 20px rgba(0, 0, 0, 0.6); + -o-box-shadow: 0 0 20px rgba(0, 0, 0, 0.6); + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + background-color: #747474; + color: #000; + background-repeat: repeat-x; + background-position: top left; + background-size: 100% 100%; + -webkit-transition: -webkit-transform 0.4s ease-in, opacity 0.4s ease-in; + -moz-transition: -moz-transform 0.4s ease-in, opacity 0.4s ease-in; + -o-transition: -o-transform 0.4s ease-in, opacity 0.4s ease-in; + -ms-transition: -m-transform 0.4s ease-in, opacity 0.4s ease-in; + -webkit-transform: scale(0.5); + -moz-transform: scale(0.5); + -o-transform: scale(0.5); + -ms-transform: scale(0.5); + max-width: 280px; + margin: 0 auto; + opacity: 0; +} +jopopup > jolist > *.select:first-childjopopup > jomenu > *.select:first-child { + border-top: none; + -webkit-border-radius: 0; + -webkit-border-top-right-radius: 1em; + -webkit-border-top-left-radius: 1em; + -moz-border-radius: 1em 1em 0 0; + border-radius: 1em 1em 0 0; +} +jopopup > jolist > *:last-child.selectjopopup > jomenu > *:first-child.select { + border-bottom: none; + -webkit-border-radius: 0; + -webkit-border-bottom-right-radius: 1em; + -webkit-border-bottom-left-radius: 1em; + -moz-border-radius: 0 0 1em 1em; + border-radius: 0 0 1em 1em; +} +jopopup.show { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + opacity: 1; +} +jopopup > joscroller { + width: 100%; +} +jonavbar { + font-size: 120%; + font-weight: bold; + display: block; + position: relative; + padding: 0; + color: #333; + height: 3em; + line-height: 3em; + border-top: none; + border-right: none; + border-left: none; + text-align: center; + -webkit-box-flex: 0; + -moz-box-flex: 0; + -o-box-flex: 0; + box-flex: 0; + background-color: #888; + cursor: default; +} +jonavbar > joview { + margin: 0; + display: block; + text-align: center; +} +jonavbar > joflexrow { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} +jobackbutton { + margin: 3px 1em; + line-height: 3em; + height: 3em; + padding: 0 1.5em; + -webkit-border-radius: 1.5em; + -moz-border-radius: 1.5em; + border-radius: 1.5em; + display: none; + color: #fff; + background: #000; + font-size: 85%; +} +jobackbutton.focus, +jobackbutton.selected { + background-color: rgba(0, 0, 0, 0.5); +} +jobackbutton.active { + display: block; +} +jonavbar > joflexrow > * { + -webkit-box-flex: 1; + -moz-box-flex: 1; + -o-box-flex: 1; + box-flex: 1; +} +jonavbar > joflexrow > jobackbutton { + -webkit-box-flex: 0; + -moz-box-flex: 0; + -o-box-flex: 0; + box-flex: 0; + max-width: 4em; +} +jopopup > jotitle { + color: #fff; + border-top: none; + border-color: #999; + margin-bottom: 1em; + -webkit-border-radius: 0; + -webkit-border-top-right-radius: 2px; + -webkit-border-top-left-radius: 2px; + -moz-border-radius: 2px 2px 0 0; + border-radius: 2px 2px 0 0; + background-color: #3f3f3f; +} +joflexcol { + height: 100%; + width: 100%; +} +body > jocontainer, +body > jocard, +body > joview, +body > joflexcol, +body > joscroller, +body > jostack { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; +} +html { + -webkit-text-size-adjust: none; +} +body { + /* -webkit-backface-visibility: hidden; */ +} +.nativescroll jostack { + width: 100%; + position: relative; +} +.nativescroll joscroller { + position: absolute; + display: block; + height: auto; + width: auto; + top: 0; + left: 0; + bottom: 0; + right: 0; + overflow: auto; + padding: 0; + margin: 0; + -webkit-overflow-scrolling: touch; +} +.nativescroll jocontainer { + height: inherit; +} +.nativescroll joscroller { + display: block; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} diff --git a/css/flattery/jo-flattery.eot b/css/flattery/jo-flattery.eot new file mode 100755 index 0000000..5e7ea32 Binary files /dev/null and b/css/flattery/jo-flattery.eot differ diff --git a/css/flattery/jo-flattery.less b/css/flattery/jo-flattery.less new file mode 100644 index 0000000..f655a1f --- /dev/null +++ b/css/flattery/jo-flattery.less @@ -0,0 +1,1063 @@ + + +@bgcolor: #fff; +@groupcolor: difference(#fff, #111); +@widgetheight: 3em; +@widgetborderwidth: .2em; +@widgetlineheight: (@widgetheight - (2 * @widgetborderwidth)); +@widgetborder: (@widgetheight / 2); +@space: (@widgetheight / 3); +@widgetpadding: (@widgetheight / 4); +@fontsize: 14px; + +@font-face { + font-family: 'jo-flattery'; + src:url('jo-flattery.eot'); + src:url('jo-flattery.eot?#iefix') format('embedded-opentype'), + url('jo-flattery.ttf') format('truetype'), + url('jo-flattery.woff') format('woff'); + font-weight: normal; + font-style: normal; +} + +::selection { + background: #4f5b98; /* Safari */ + color: #fff; +} +::-moz-selection { + background: #4f5b98; /* Firefox */ + color: #fff; +} + +body { + margin: 0; + padding: 0; + background: @bgcolor; + word-wrap: break-word; + overflow: hidden; + font: normal @fontsize "Helvetica", "Droid Sans", "Trebuchet MS"; +} +jobutton, +joview, +jolist, +jolistitem, +jomenu, +jomenuitem, +joexpando, +joexpandotitle, +jogroup, +jocard, +jostack, +jotitle, +jocaption, +jolabel, +jodivider, +joinput, +input, +textarea, +jotextarea, +jooption, +jooptionitem, +jonavbar, +jocontainer, +jotoggle, +joslider, +josliderthumb { + display: block; + margin: 0; + padding: 0; + -webkit-user-select: none; + -moz-user-select: none; + -o-user-select: none; + user-select: none; + -webkit-background-clip: padding-box; + /* background: transparent; */ +} +/* +em, i, b, span, u, a, button, input { + display: inline; +} +*/ +.noflex { + -webkit-box-flex: 0; + -moz-box-flex: 0; + -o-box-flex: 0; + box-flex: 0; +} +.flexible { + -webkit-box-flex: 1; + -moz-box-flex: 1; + -o-box-flex: 1; + box-flex: 1; +} + +jobutton, jooptionitem, joexpandotitle { overflow: hidden; } +.flex { + display: block; + display: -webkit-box; + display: -moz-box; + display: -o-box; + display: box; + margin: 0; + -moz-box-align: stretch; + -o-box-align: stretch; + box-align: stretch; +} +.listitem { + border-top: 1px solid rgba(0, 0, 0, 0.4); + margin: 0; + padding: @space; + cursor: pointer; +} +.widgety { + color: rgba(255, 255, 255, 0.9); + background-color: #c5c5c5; + font-weight: normal; + cursor: pointer; + outline: none; + outline-color: transparent; + padding: @space 0; +} +.shiny { + color: rgba(255, 255, 255, 0.9); + background-color: #c5c5c5; + font-weight: normal; + cursor: pointer; + outline: none; + outline-color: transparent; + padding: @space 0; +} +.matte { + color: rgba(255, 255, 255, 0.9); + background-color: #c5c5c5; + font-weight: normal; + cursor: pointer; + outline: none; + outline-color: transparent; + padding: @space 0; +} +.stretch-full { + display: block; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} +.widget { + margin: 0px @space @space @space; +} +*.selected, *.focus { +} +.selected { + background-color: #4f5b98; + color: #fffeff; +} +.focus { + background-color: #fff; +} +jooptionitem:last-child { + -webkit-border-radius: 0; + -webkit-border-top-right-radius: @widgetborder; + -webkit-border-bottom-right-radius: @widgetborder; + -moz-border-radius: 0 @widgetborder @widgetborder 0; + border-radius: 0 @widgetborder @widgetborder 0; +} +jobutton { + display: block; + text-align: center; + color: #fff; + background: #333; + font-weight: normal; + cursor: pointer; + outline: none; + outline-color: transparent; + height: @widgetheight; + line-height: @widgetheight; + -webkit-border-radius: @widgetborder; + -moz-border-radius: @widgetborder; + border-radius: @widgetborder; +} +jobutton .focus { + background-color: #4f5b98; +} +jooption { + display: block; + display: -webkit-box; + display: -moz-box; + display: -o-box; + display: box; + -moz-box-align: stretch; + -o-box-align: stretch; + box-align: stretch; + margin: 0px @space @space @space; +} +jooptionitem { + color: #000; + background-color: #c5c5c5; + font-weight: normal; + cursor: pointer; + outline: none; + outline-color: transparent; + padding: 0 @widgetborder; + -webkit-box-flex: 1; + -moz-box-flex: 1; + -o-box-flex: 1; + box-flex: 1; + text-align: center; + margin: 0; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + height: @widgetheight; + line-height: @widgetlineheight; + + border-left: @widgetborderwidth solid #999; + border-top: @widgetborderwidth solid #999; + border-bottom: @widgetborderwidth solid #999; +} +jooptionitem:first-child { + -webkit-border-radius: 0; + -webkit-border-top-left-radius: @widgetborder; + -webkit-border-bottom-left-radius: @widgetborder; + -moz-border-radius: @widgetborder 0 0 @widgetborder; + border-radius: @widgetborder 0 0 @widgetborder; +} +jooptionitem:last-child { + border-right: @widgetborderwidth solid #999; + -webkit-border-radius: 0; + -webkit-border-top-right-radius: @widgetborder; + -webkit-border-bottom-right-radius: @widgetborder; + -moz-border-radius: 0 @widgetborder @widgetborder 0; + border-radius: 0 @widgetborder @widgetborder 0; +} +jobutton, +input, +jolabel, +textarea, +joexpando { + margin: 0px @space @space @space; +} +jotitle { + background-color: #b8b8b8; + font-weight: normal; + cursor: pointer; + outline: none; + outline-color: transparent; + + text-align: center; + padding: @space; + font-size: 120%; + margin: 0; + border-left: none; + border-right: none; + border-bottom: 1px solid #858585; + border-top: 1px solid #d8d8d8; + color: #3c3c3c; +} +*:focus { + outline: none; +} +jolistitem, jomenuitem { + border-top: 1px solid #ebebeb; + margin: 0; + padding: @space; + cursor: pointer; + border-bottom: 1px solid #6d6d6d; +} +jolistitem.selected, jomenuitem.selected { + border-color: #333; +} +jomenuitem:last-child { + border-bottom: 1px solid #666; +} +jobutton.focus { + background-color: #4f5b98; + background-image: none; +} +joselect.focus { + background-color: transparent; +} +jolist { + margin: 0; +} +joselectlist, joexpandocontent { + display: block; + border-top: none; + -webkit-border-radius: 0; + -webkit-border-bottom-right-radius: @widgetborder; + -webkit-border-bottom-left-radius: @widgetborder; + -moz-border-radius: 0 0 @widgetborder @widgetborder; + border-radius: 0 0 @widgetborder @widgetborder; + background-color: rgba(255, 255, 255, 0.6); +} +joexpando { + display: block; + padding-bottom: 0px; + margin-bottom: 0; +} +joexpando.open { + margin-bottom: @space; +} +joexpandocontent { + padding-top: @space; +} +joselectlist > *:last-child { + border-bottom: none; + -webkit-border-radius: 0; + -webkit-border-bottom-right-radius: @widgetborder; + -webkit-border-bottom-left-radius: @widgetborder; + -moz-border-radius: 0 0 @widgetborder @widgetborder; + border-radius: 0 0 @widgetborder @widgetborder; +} +joselectlist > *:last-child.select { + border-bottom: none; + -webkit-border-radius: 0; + -webkit-border-bottom-right-radius: @widgetborder; + -webkit-border-bottom-left-radius: @widgetborder; + -moz-border-radius: 0 0 @widgetborder @widgetborder; + border-radius: 0 0 @widgetborder @widgetborder; +} +joselectlist > *.first-child { + border-top: none; +} +jocard > jolist, jocard > jomenu { + margin: 0; +} +joinput.password, input.password { + -webkit-text-security: disc; + -moz-text-security: disc; + -o-text-security: disc; + text-security: disc; +} +joinput, +jotextarea, +input, +textarea { + cursor: text; + display: block; + -webkit-border-radius: @widgetborderwidth; + -moz-border-radius: @widgetborderwidth; + border-radius: @widgetborderwidth; + margin: 0 @space @space @space; + padding: @widgetpadding; + background: #e7e6e7; +/* white-space: nowrap; */ + font-size: 105%; + overflow: hidden; + outline: none; + -webkit-user-select: text; + -moz-user-select: text; + user-select: text; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + + border: @widgetborderwidth solid #999; +} +jolist, jomenu { + font-size: 110%; +} +jotextarea, textarea { + white-space: normal; +} +joinput.disabled, +jotextarea.disabled, +input.disabled, +textarea.disabled { + color: #666; + cursor: text; +} +joexpandotitle joicon { + position: absolute; + border-radius: 0 @widgetborder @widgetborder 0; + background: none; + border: none; + text-align: center; + display: block; + height: @widgetheight; + width: @widgetheight; + line-height: @widgetlineheight; + right: 0; + top: 0; + + -webkit-transform-origin: 50% 50% 0; + -webkit-transform: rotatez(0); + -webkit-transition: -webkit-transform 0.2s ease-out; + -moz-transform-origin: 50% 50% 0; + -moz-transform: rotate(0); + -moz-transition: -moz-transform 0.2s ease-out; + -o-transform-origin: 50% 50% 0; + -o-transform: rotate(0); + -o-transition: -o-transform 0.2s ease-out; + -ms-transform-origin: 50% 50% 0; + -ms-transform: rotate(0); + -ms-transition: -ms-transform 0.2s ease-out; +} +joexpando joicon:after { + content: ">"; + font-family: "jo-flattery"; +} + +joexpando.open > joexpandotitle joicon { + -webkit-transform: rotatez(90deg); + -moz-transform: rotate(90deg); + -o-transform: rotate(90deg); + -ms-transform: rotate(90deg); +} +joexpando > *:last-child { + height: 0; + overflow: hidden; + opacity: 0; + display: none; + margin-top: 0; + margin-bottom: 0; +} +joexpando.open > *:last-child { + height: 100%; + overflow: visible; + opacity: 1; + display: block; +} +joexpando > *:first-child { + -webkit-transform: none; + opacity: 1; + overflow: visible; +} + +joexpandotitle { + color: #000; + position: relative; + background-color: #c5c5c5; + font-weight: normal; + cursor: pointer; + outline: none; + outline-color: transparent; + height: @widgetheight; + line-height: @widgetlineheight; + padding: 0 @space; + -webkit-border-radius: @widgetborder; + -moz-border-radius: @widgetborder; + border-radius: @widgetborder; + cursor: pointer; + text-align: left; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + + border: @widgetborderwidth solid #999; +} + +joexpando.open > *:first-child { + background-color: #6d6d6d; + -webkit-border-radius: 0; + -webkit-border-top-right-radius: @widgetborder; + -webkit-border-top-left-radius: @widgetborder; + -moz-border-radius: @widgetborder @widgetborder 0 0; + border-radius: @widgetborder @widgetborder 0 0; + color: #fff; +} +jolabel, label { + margin-bottom: 5px; +} +jocaption { + margin: @space; +} +johtml { + display: block; + margin: 0 @space @space @space; + padding: 0; +} +jodivider { + border-top: 1px solid rgba(0, 0, 0, 0.2); + border-bottom: 1px solid rgba(255, 255, 255, 0.2); + margin: 0 0 @space 0; + text-align: center; + height: 0; + display: block; +} + +joflexrow > jotoggle { + -webkit-box-flex: 0; + -moz-box-flex: 0; + -o-box-flex: 0; + box-flex: 0; +} + +jotoggle { + cursor: pointer; + display: block; + margin: @space @space 0 @space; + -webkit-border-radius: @widgetborder; + -moz-border-radius: @widgetborder; + border-radius: @widgetborder; + background-color: #999; + position: relative; + width: (@widgetheight * 3); + height: @widgetheight; + line-height: @widgetheight; +} + +jotoggle > * { + color: #000; + background-color: #c5c5c5; + font-weight: normal; + cursor: pointer; + outline: none; + outline-color: transparent; + text-align: center; + -webkit-border-radius: @widgetborder; + -moz-border-radius: @widgetborder; + border-radius: @widgetborder; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + height: @widgetheight; + line-height: @widgetlineheight; + + border: @widgetborderwidth solid #999; + + width: (@widgetheight * 2); + + -webkit-transition: -webkit-transform 0.1s ease, background 0.1s ease; + -moz-transition: -moz-transform 0.1s ease, background 0.1s ease; + -o-transition: -o-transform 0.1s ease, background 0.1s ease; + -ms-transition: -ms-transform 0.1s ease, background 0.1s ease; + + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translatex(0em); + -o-transform: translatex(0em); + -ms-transform: translatex(0em); + + -webkit-animation-fill-mode: forwards; +} + +jotoggle.on > * { + color: #fff; + background-color: #4f5b98; + -webkit-transform: translate3d(@widgetheight, 0, 0); + -moz-transform: translatex(@widgetheight); + -o-transform: translatex(@widgetheight); + -ms-transform: translatex(@widgetheight); +} +jotable { + display: block; + margin: 0 @space; +} +tr { + margin: 0; +} +th { + text-align: left; + padding: 5px; +} +td { + padding: 5px; +} +jolabel.left { + margin-top: @space; + padding: 9px 0; +} +.disabled { + opacity: .2; +} +jotoolbar { + padding: @space; +} +josliderthumb { + position: absolute; + height: @widgetheight; + width: (@widgetheight * 2); + color: rgba(255, 255, 255, 0.9); + background-color: #4f5b98; + font-weight: normal; + outline: none; + outline-color: transparent; + -webkit-border-radius: @widgetborder; + -moz-border-radius: @widgetborder; + border-radius: @widgetborder; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + line-height: @widgetlineheight; + + border: @widgetborderwidth solid #999; + + -webkit-transition: left 0.1s ease; + -moz-transition: left 0.1s ease; + -o-transition: left 0.1s ease; + -ms-transition: left 0.1s ease; +} + +joslider.live > josliderthumb { + -webkit-transition: none; + -moz-transition: none; + -o-transition: none; + -ms-transition: none; +} + + +joslider { + cursor: pointer; + background: #999; + margin: @space; + position: relative; + height: @widgetheight; + -webkit-border-radius: @widgetborder; + -moz-border-radius: @widgetborder; + border-radius: @widgetborder; +} +joflexrow { + display: block; + display: -webkit-box; + display: -moz-box; + display: -o-box; + display: box; + margin: 0; + -moz-box-align: stretch; + -o-box-align: stretch; + box-align: stretch; + width: 100%; +} +joflexrow > * { + -webkit-box-flex: 1; + -moz-box-flex: 1; + -o-box-flex: 1; + box-flex: 1; + margin-right: 0; + position: relative; +} +joflexrow > *:last-child { + margin-right: @space; +} +joflexcol { + display: block; + display: -webkit-box; + display: -moz-box; + display: -o-box; + display: box; + margin: 0; + -moz-box-align: stretch; + -o-box-align: stretch; + box-align: stretch; + height: 100%; + width: 100%; + -webkit-box-orient: vertical; + -webkit-box-align: stretch; + -moz-box-orient: vertical; + -moz-box-align: stretch; + -o-box-orient: vertical; + -o-box-align: stretch; + box-orient: vertical; + box-align: stretch; + margin: 0; +} +joflexcol > * { + -webkit-box-flex: 1; + -moz-box-flex: 1; + -o-box-flex: 1; + box-flex: 1; +} +jotitle + joflexcol, jotitle + joflexrow { + margin-top: @space; +} +jostack { + height: 100%; +/* + -webkit-perspective: 0; + -moz-perspective: 0; + -o-perspective: 0; + -ms-perspective: 0; +*/ + -webkit-transition: opacity 0.2s ease-out; + -moz-transition: opacity 0.2s ease-out; + -o-transition: opacity 0.2s ease-out; + -ms-transition: opacity 0.2s ease-out; +} +jostack > * { + z-index: 0; + position: absolute; + + -webkit-animation-fill-mode: forwards; +/* -webkit-transform-origin: 0 0 0; */ + -webkit-transform: translate3d(0, 0, 0); + -webkit-transition: -webkit-transform 0.2s ease-out, z-index 0.2s ease-out, height 0s ease, overflow 0s ease; +/* -moz-transform-origin: 0 0 0; */ + -moz-transform: translate3d(0, 0, 0); + -moz-transition: -moz-transform 0.2s ease-out, z-index 0.2s ease-out, height 0s ease, overflow 0s ease; +/* -o-transform-origin: 0 0 0; */ + -o-transform: translate3d(0, 0, 0); + -o-transition: -o-transform 0.2s ease-out; +/* -ms-transform-origin: 0 0 0; */ + -ms-transform: translate3d(0, 0, 0); + -ms-transition: -ms-transform 0.2s ease-out; + /* + display: block; + height: 100%; + width: 100%; + overflow: hidden; + padding: 0; + margin: 0; +*/ + +} +jostack > .next { + z-index: -1; + -webkit-transform: translateX(100%); + -moz-transform: translateX(100%); + -o-transform: translateX(100%); + -ms-transform: translateX(100%); + height: 100%; + overflow: hidden; +} +jostack > .prev { + z-index: 1; + -webkit-transform: translateX(-100%); + -moz-transform: translateX(-100%); + -o-transform: translateX(-100%); + -ms-transform: translateX(-100%); + height: 100%; + overflow: hidden; +} +* { + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +jocard { + width: 100%; + min-height: 100%; + display: -webkit-box; + display: -moz-box; + display: -o-box; + display: box; + padding: 0; + margin: 0; + -webkit-box-orient: vertical; + -webkit-box-align: stretch; + -moz-box-orient: vertical; + -moz-box-align: stretch; + -o-box-orient: vertical; + -o-box-align: stretch; + box-orient: vertical; + box-align: stretch; + background: @bgcolor; +} +jocard > * { + /* display: block; */ + +} +jocard > *:last-child { + margin-bottom: @space; +} +joscroller { + position: absolute; + display: block; + height: 100%; + width: 100%; + overflow: hidden; + padding: 0; + margin: 0; + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translatey(0); + -o-transform: translate(0, 0); + -ms-transform: translate(0, 0); +} +joscroller > * { + position: absolute; + top: 0; + -webkit-animation-fill-mode: forwards; + -webkit-transition: -webkit-transform 0s ease; + -moz-animation-fill-mode: forwards; + -moz-transition: -moz-transform 0s ease; + -o-animation-fill-mode: forwards; + -o-transition: -o-transform 0s ease; + -ms-animation-fill-mode: forwards; + -ms-transition: -ms-transform 0s ease; +} +.flick { + -webkit-transition: -webkit-transform 1.8s cubic-bezier(0, 0.2, 0, 1); + -moz-transition: -moz-transform 1.8s cubic-bezier(0, 0.2, 0, 1); + -o-transition: -o-transform 1.8s cubic-bezier(0, 0.2, 0, 1); + -ms-transition: -ms-transform 1.8s cubic-bezier(0, 0.2, 0, 1); +} +.flickback { + -webkit-transition: -webkit-transform 0.2s cubic-bezier(0, 0, 0.4, 1); + -moz-transition: -moz-transform 0.2s cubic-bezier(0, 0, 0.4, 1); + -o-transition: -o-transform 0.2s cubic-bezier(0, 0, 0.4, 1); + -ms-transition: -o-transform 0.2s cubic-bezier(0, 0, 0.4, 1); +} +.flickfast { + -webkit-transition: -webkit-transform 0.6s cubic-bezier(0, 0.2, 0, 1); + -moz-transition: -moz-transform 0.6s cubic-bezier(0, 0.2, 0, 1); + -o-transition: -o-transform 0.6s cubic-bezier(0, 0.2, 0, 1); +} +jocontainer { + margin: 0; + display: block; + position: relative; +} +jogroup { + margin: @space; + padding: @space 0; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + background: @groupcolor; +} +jogroup > *.last-child { + margin-bottom: 0; +} +jofooter { + display: block; + display: -webkit-box; + display: -moz-box; + display: box; + width: 100%; + -webkit-box-flex: 1; + -webkit-box-orient: vertical; + -webkit-box-align: stretch; + -webkit-box-pack: end; + -moz-box-flex: 1; + -moz-box-orient: vertical; + -moz-box-align: stretch; + -moz-box-pack: end; + box-flex: 1; + box-orient: vertical; + box-align: stretch; + box-pack: end; + margin: 0; +} +jofooter > * { + -webkit-box-align: end; + -moz-box-align: end; + -o-box-align: end; + box-align: end; +} +joshim { + opacity: 0; + overflow: hidden; + position: absolute; + z-index: 100; + top: 0; + left: 0; + right: 0; + bottom: 0; + display: none; + background: rgba(0,0,0,0.8); + opacity: 0; + -webkit-transition: opacity .2s ease; + -moz-transition: opacity .2s ease; + -o-transition: opacity .2s ease; + -ms-transition: opacity .2s ease; +} +joshim.show { + display: block; + opacity: 1; +} +jotoolbar { + border-top: 1px solid rgba(0, 0, 0, 0.8); + padding: @space 0; + color: rgba(255, 255, 255, 0.9); + background-color: rgba(0,0,0,0.8); + font-weight: normal; + cursor: pointer; + outline: none; + outline-color: transparent; + z-index: 1; + position: absolute; + bottom: 0; + left: 0; + right: 0; + text-align: center; +} +jopopup { + -webkit-box-flex: 0; + -moz-box-flex: 0; + -o-box-flex: 0; + box-flex: 0; + display: block; + overflow: hidden; + margin: 0 auto; + border: 2px solid #434343; + -webkit-box-shadow: 0 0 20px rgba(0, 0, 0, 0.6); + -moz-box-shadow: 0 0 20px rgba(0, 0, 0, 0.6); + -o-box-shadow: 0 0 20px rgba(0, 0, 0, 0.6); + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + background-color: #747474; + color: #000; + background-repeat: repeat-x; + background-position: top left; + background-size: 100% 100%; + -webkit-transition: -webkit-transform 0.4s ease-in, opacity 0.4s ease-in; + -moz-transition: -moz-transform 0.4s ease-in, opacity 0.4s ease-in; + -o-transition: -o-transform 0.4s ease-in, opacity 0.4s ease-in; + -ms-transition: -m-transform 0.4s ease-in, opacity 0.4s ease-in; + -webkit-transform: scale(0.5); + -moz-transform: scale(0.5); + -o-transform: scale(0.5); + -ms-transform: scale(0.5); + max-width: 280px; + margin: 0 auto; + opacity: 0; +} +jopopup > jolist > *.select:first-childjopopup > jomenu > *.select:first-child { + border-top: none; + -webkit-border-radius: 0; + -webkit-border-top-right-radius: @space; + -webkit-border-top-left-radius: @space; + -moz-border-radius: @space @space 0 0; + border-radius: @space @space 0 0; +} +jopopup > jolist > *:last-child.selectjopopup > jomenu > *:first-child.select { + border-bottom: none; + -webkit-border-radius: 0; + -webkit-border-bottom-right-radius: @space; + -webkit-border-bottom-left-radius: @space; + -moz-border-radius: 0 0 @space @space; + border-radius: 0 0 @space @space; +} +jopopup.show { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + opacity: 1; +} +jopopup > joscroller { + width: 100%; +} +jonavbar { + font-size: 120%; + font-weight: bold; + display: block; + position: relative; + padding: 0; + color: #333; + height: 3em; + line-height: 3em; + border-top: none; + border-right: none; + border-left: none; + text-align: center; + -webkit-box-flex: 0; + -moz-box-flex: 0; + -o-box-flex: 0; + box-flex: 0; + background-color: #888; + cursor: default; +} +jonavbar > joview { + margin: 0; + display: block; + text-align: center; +} +jonavbar > joflexrow { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} +jobackbutton { + margin: 3px @space; + line-height: @widgetheight; + height: @widgetheight; + padding: 0 @widgetborder; + -webkit-border-radius: @widgetborder; + -moz-border-radius: @widgetborder; + border-radius: @widgetborder; + display: none; + color: #fff; + background: #000; + font-size: 85%; +} +jobackbutton.focus, jobackbutton.selected { + background-color: rgba(0, 0, 0, 0.5); +} +jobackbutton.active { + display: block; +} +jonavbar > joflexrow > * { + -webkit-box-flex: 1; + -moz-box-flex: 1; + -o-box-flex: 1; + box-flex: 1; +} +jonavbar > joflexrow > jobackbutton { + -webkit-box-flex: 0; + -moz-box-flex: 0; + -o-box-flex: 0; + box-flex: 0; + max-width: 4em; +} +jopopup > jotitle { + color: #fff; + border-top: none; + border-color: #999; + margin-bottom: @space; + -webkit-border-radius: 0; + -webkit-border-top-right-radius: 2px; + -webkit-border-top-left-radius: 2px; + -moz-border-radius: 2px 2px 0 0; + border-radius: 2px 2px 0 0; + background-color: #3f3f3f; +} +joflexcol { + height: 100%; + width: 100%; +} +body > jocontainer, +body > jocard, +body > joview, +body > joflexcol, +body > joscroller, +body > jostack { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; +} +html { + -webkit-text-size-adjust: none; +} +body { +/* -webkit-backface-visibility: hidden; */ +} + + +.nativescroll jostack { + width: 100%; + position: relative; +} + +.nativescroll joscroller { + position: absolute; + display: block; + height: auto; + width: auto; + top: 0; left: 0; bottom: 0; right: 0; + overflow: auto; + padding: 0; + margin: 0; + -webkit-overflow-scrolling: touch; +} + +.nativescroll jocontainer { + height: inherit; +} + +.nativescroll joscroller { + display: block; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} diff --git a/css/flattery/jo-flattery.ttf b/css/flattery/jo-flattery.ttf new file mode 100755 index 0000000..c5d445a Binary files /dev/null and b/css/flattery/jo-flattery.ttf differ diff --git a/css/flattery/jo-flattery.woff b/css/flattery/jo-flattery.woff new file mode 100755 index 0000000..adc2705 Binary files /dev/null and b/css/flattery/jo-flattery.woff differ diff --git a/css/jo.css b/css/jo.css index bb84367..65f8733 100644 --- a/css/jo.css +++ b/css/jo.css @@ -1093,3 +1093,31 @@ html { body { -webkit-backface-visibility: hidden; } + +.nativescroll jostack { width: 100%; position: relative; } + +.nativescroll joscroller { + position: absolute; + display: block; + height: auto; + width: auto; + top: 0; left: 0; bottom: 0; right: 0; + overflow: auto; + padding: 0; + margin: 0; + -webkit-overflow-scrolling: touch; +} + +.nativescroll jocontainer { + height: inherit; +} + +.nativescroll joscroller { + display: block; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + diff --git a/css/jo2.css b/css/jo2.css index 5badb65..c75cd81 100644 --- a/css/jo2.css +++ b/css/jo2.css @@ -1167,3 +1167,31 @@ jobackbutton { color: inherit; font-size: 85%; } + +.nativescroll jostack { width: 100%; position: relative; } + +.nativescroll joscroller { + position: absolute; + display: block; + height: auto; + width: auto; + top: 0; left: 0; bottom: 0; right: 0; + overflow: auto; + padding: 0; + margin: 0; + -webkit-overflow-scrolling: touch; +} + +.nativescroll jocontainer { + height: inherit; +} + +.nativescroll joscroller { + display: block; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + diff --git a/css/sample.html b/css/sample.html index dd7a78a..e79cc26 100644 --- a/css/sample.html +++ b/css/sample.html @@ -7,7 +7,7 @@ joTest - + diff --git a/docs/_quickstart.mdown b/docs/_quickstart.mdown index cf0329a..d1a8553 100644 --- a/docs/_quickstart.mdown +++ b/docs/_quickstart.mdown @@ -10,7 +10,7 @@ Jo needs at least a simple HTML file to operate in. Here is a bare-bones example - + diff --git a/docs/platforms.mdown b/docs/platforms.mdown index 5caea73..3367afd 100644 --- a/docs/platforms.mdown +++ b/docs/platforms.mdown @@ -4,22 +4,18 @@ Supported Platforms Jo is built on HTML5, so anything with decent support for these emerging standards should work with Jo. The list of devices and platforms you can distribute your apps on is growing, but here's -a list of +a list: Mobile Apps ----------- -Most require PhoneGap to create a native app "shell". webOS doesn't -require PhoneGap, but it is useful for some things. +Most require PhoneGap to create a native app "shell": -- iOS 3+ for iPhone, iPad, iPod Touch +- iOS 4+ for iPhone, iPad, iPod Touch - Android 2.1+ -- webOS 1.4+ -- Blackberry PlayBook using their Web SDK -- Symbian ^ 3 - -It's been reported that Jo works great with newer releases of Blackberry, -but I haven't done any testing with it yet. +- Blackberry 10 and PlayBook OS +- Tizen 2.2+ +- webOS 2.0+ Mobile Browsers --------------- @@ -32,17 +28,16 @@ will make life interesting and might require some CSS fiddling. Desktop Apps ------------ -HTML5 is making its way into desktop applications. Both native Mac OSX -and Windows require special builds of PhoneGap. +HTML5 is making its way into desktop applications. Native OSX requires a +special build of PhoneGap or a similar tool. -- ChromeOS -- Windows +- Chrome OS +- Chrome Browser Plugins +- Safari Extensions +- Windows 8+ - Mac OSX 10.5+ - Mac OSX DashBoard Widgets -It's been reported that Jo will work with Adobe AIR, but I haven't done -any testing with it. - Desktop Browsers ---------------- @@ -50,11 +45,9 @@ In general, all modern browsers which have decent HTML5 support will work well with Jo and its CSS3. Note that Internet Explorer and FireFox 3.x can work, but you will have to play with the CSS to get things going. -- Safari 5+ - Chrome 9+ +- Safari 5+ - Opera 10+ - FireFox 4+ -- Internet Explorer 8+ +- Internet Explorer 10+ -For browsers, you will want to include `css/browser.css` in your project -to revert joScroller and joStackScroller to use native scrollbars. diff --git a/docs/releasenotes.mdown b/docs/releasenotes.mdown index 2e6f7c7..4d6da81 100644 --- a/docs/releasenotes.mdown +++ b/docs/releasenotes.mdown @@ -1,6 +1,28 @@ Release Notes ============= +Jo 0.5.0 "Pumpkin Spice" +------------------------ + +- Support for Tizen 2.2+ browser & the Tizen Web App SDK + - Native scroller support + - CSS rendering tweaks + - Enhanced back button support +- New theme: "Flattery" (css/flattery) + - Flat design + - Easy to customize (either directly or with less.js) + - No image dependencies + - Uses a custom font for glyphs (built with http://icomoon.io) +- Improved desktop browser support (yes, your trackpad can now scroll) +- Improved kitchen sink sample app +- CSS transition bug fixes for joToggle, joSlider and joPopup +- New joQueue for serializing asynchronous calls +- New joPool for class-based object pooling +- New joTimer object for, well, timing things +- New joCanvas widget, a basic canvas tag wrapper +- New joImage widget +- New joTemplate class for simple string templating + Jo 0.4.1 -------- diff --git a/js/core/_jo.js b/js/core/_jo.js index 17ff7fb..5557e5e 100644 --- a/js/core/_jo.js +++ b/js/core/_jo.js @@ -90,7 +90,11 @@ // syntactic sugar to make it easier to extend a class Function.prototype.extend = function(superclass, proto) { // create our new subclass - this.prototype = new superclass(); + + if (typeof Object.create !== "undefined") + this.prototype = Object.create(superclass.prototype); + else + this.prototype = new superclass(); // optional subclass methods and properties if (proto) { @@ -125,16 +129,23 @@ if (typeof console.log !== 'function') // just a place to hang our hat jo = { platform: "webkit", - version: "0.4.2", + version: "0.5.0", useragent: [ 'ipad', 'iphone', + 'ipod', 'playbook', + 'bb10', 'webos', 'hpwos', 'bada', + 'ouya', + 'tizen', 'android', + 'kindle', + 'silk', + 'iemobile', 'msie', 'opera', 'chrome', @@ -143,6 +154,20 @@ jo = { 'gecko' ], + osMap: { + ipad: "ios", + iphone: "ios", + ipod: "ios", + webos: "webos", + hpwos: "webos", + silk: "android", + ouya: "android", + kindle: "android", + msie: "windows", + iemobile: "windows", + safari: "osx" + }, + debug: false, setDebug: function(state) { this.debug = state; @@ -173,6 +198,8 @@ jo = { } } + this.os = this.osMap[this.platform] || this.platform; + if (joEvent) { // detect if we're on a touch or mouse based browser var o = document.createElement('div'); @@ -188,39 +215,84 @@ jo = { if (joGesture) joGesture.load(); - var s = joScroller.prototype; - + var s = (typeof joScroller !== "undefined") ? joScroller.prototype : null; + var d = joDOM; + + if (s && this.matchPlatform("tizen msie chrome safari bb10")) { + // native scrolling + joDOM.addCSSClass(document.body, "nativescroll"); + s.onDown = function() {}; + s.setEvents = function() {}; + s.onUp = function() {}; + s.onMove = function() {}; + s.onClick = function() {}; + s.setPosition = s.setPositionNative; + } + // setup transition css hooks for the scroller if (typeof document.body.style.webkitTransition !== "undefined") { - // webkit, leave everything alone + joEvent.map.transitionend = "webkitTransitionEnd"; + d.transform = function(node, arg) { + node.style.webkitTransform = arg; + }; + d.transformOrigin = function(node, arg) { + node.style.webkitTransformOrigin = arg; + }; + d.transition = function(node, arg) { + node.style.webkitTransition = arg; + }; } else if (typeof document.body.style.MozTransition !== "undefined") { // mozilla with transitions - s.transitionEnd = "transitionend"; - s.setPosition = function(x, y, node) { + if (s) s.setPosition = function(x, y, node) { node.style.MozTransform = "translate(" + x + "px," + y + "px)"; }; + d.transform = function(node, arg) { + node.style.MozTransform = arg; + }; + d.transformOrigin = function(node, arg) { + node.style.MozTransformOrigin = arg; + }; + d.transition = function(node, arg) { + node.style.MozTransition = arg; + }; } else if (typeof document.body.style.msTransform !== "undefined") { // IE9 with transitions - s.transitionEnd = "transitionend"; - s.setPosition = function(x, y, node) { + if (s) s.setPosition = function(x, y, node) { node.style.msTransform = "translate(" + x + "px," + y + "px)"; }; + d.transform = function(node, arg) { + node.style.msTransform = arg; + }; + d.transformOrigin = function(node, arg) { + node.style.msTransformOrigin = arg; + }; + d.transition = function(node, arg) { + node.style.msTransition = arg; + }; } else if (typeof document.body.style.OTransition !== "undefined") { // opera with transitions - s.transitionEnd = "otransitionend"; - s.setPosition = function(x, y, node) { + if (s) s.setPosition = function(x, y, node) { node.style.OTransform = "translate(" + x + "px," + y + "px)"; }; + joEvent.map.transitionend = "otransitionend"; + d.transform = function(node, arg) { + node.style.OTransform = arg; + }; + d.transformOrigin = function(node, arg) { + node.style.OTransformOrigin = arg; + }; + d.transition = function(node, arg) { + node.style.OTransition = arg; + }; } else { // no transitions, disable flick scrolling s.velocity = 0; s.bump = 0; - s.transitionEnd = "transitionend"; - s.setPosition = function(x, y, node) { + if (s) s.setPosition = function(x, y, node) { if (this.vertical) node.style.top = y + "px"; @@ -229,6 +301,17 @@ jo = { }; } + if (!window.requestAnimationFrame) { + console.log("jo: swapping requestanimationframe with settimeout"); + jo.requestAnimationFrame = false; + window.requestAnimationFrame = function(call) { + setTimeout(call, 17); + } + } + else { + jo.requestAnimationFrame = true; + } + joLog("Jo", this.version, "loaded for", this.platform, "environment"); this.loadEvent.fire(); diff --git a/js/core/dom.js b/js/core/dom.js index 0add251..541a778 100644 --- a/js/core/dom.js +++ b/js/core/dom.js @@ -240,6 +240,23 @@ joDOM = { return css; }, + + applyCSS: function(style, oldnode) { + var css = oldnode || joDOM.create('jostyle'); + css.innerHTML = ''; + + if (!oldnode) + document.body.appendChild(css); + + return css; + }, + + addMeta: function(name, content) { + var meta = joDOM.create("meta"); + meta.setAttribute("name", name); + meta.setAttribute("content", content); + document.head.appendChild(meta); + }, pageOffsetLeft: function(node) { var l = 0; @@ -258,7 +275,7 @@ joDOM = { var t = 0; while (typeof node !== 'undefined' && node && node.parentNode !== window) { - if(node.offsetTop) + if (node.offsetTop) t += node.offsetTop; node = node.parentNode; @@ -267,22 +284,34 @@ joDOM = { return t; }, - getBounds:function(node) { + getBounds: function(node) { var top = joDOM.pageOffsetTop(node); var left = joDOM.pageOffsetLeft(node); - var bottom = top+node.offsetHeight; - var right = left+node.offsetWidth; + var bottom = top + node.offsetHeight; + var right = left + node.offsetWidth; return { - top:top, - left:left, - bottom:bottom, - right:right, + top: top, + left: left, + bottom: bottom, + right: right, center:{ - x:left+(right-left)/2, - y:top+(bottom-top)/2 + x: left + (right - left) / 2, + y: top + (bottom - top) / 2 } }; + }, + + attach: function(node, parent) { + parent.appendChild(node); + }, + + detach: function(node, parent) { + if (!parent) + parent = node.parentNode; + + if (parent) + parent.removeChild(node); } }; diff --git a/js/core/event.js b/js/core/event.js index 3bd3597..d80778a 100644 --- a/js/core/event.js +++ b/js/core/event.js @@ -50,6 +50,12 @@ joEvent = { "mouseup": "touchend", "mouseout": "touchcancel" }, + + map: { + click: "click", + transitionend: "transitionend" + }, + touchy: false, getTarget: function(e) { diff --git a/js/core/queue.js b/js/core/queue.js new file mode 100644 index 0000000..4baec70 --- /dev/null +++ b/js/core/queue.js @@ -0,0 +1,78 @@ + +joQueue = function() { + this.queue = []; + + this.doneEvent = new joSubject(this); +}; +joQueue.prototype = { + push: function(call, delay, context, data) { + this.queue.push({ + delay: delay, + call: call, + context: context, + data: data + }); + }, + + tick: function() { + var t = (new Date() * 1); + + if (this.next == 0 || t >= this.next) { + var c = this.queue.shift(); + if (c.context) + c.call.call(c.context, c.data || null); + else + c.call(c.data || null); + + if (this.queue.length) + this.next = t + this.queue[0].delay; + } + + if (this.queue.length) { + var self = this; + window.requestAnimationFrame(function() { + self.tick.call(self); + }); + } + else { + this.stop(); + } + }, + + start: function() { + this.working = true; + this.next = 0; + + if (this.queue.length) { + joDefer(this.tick, this); + } + + return this; + }, + + stop: function() { + this.working = false; + this.next = 0; + + this.doneEvent.fire(); + }, + + getElapsed: function(last) { + return (new Date() * 1) - last; + }, + + getTime: function() { + return (new Date() * 1); + }, + + setLast: function(time) { + if (!time) + time = (new Date() * 1); + + this.last = time; + + return this; + } +}; + + diff --git a/js/core/timer.js b/js/core/timer.js new file mode 100644 index 0000000..c301796 --- /dev/null +++ b/js/core/timer.js @@ -0,0 +1,148 @@ +/** + joTimer + ======= + + Timer interval with events. + + Methods + ------- + + - `start()` + + Start the timer from the last value. + + - `stop()` + + Stop the timer, does not reset it. You can restart it with `start()` + + - `reset()` + + Reset the timer to its original time. + + Use + --- + + var x = new joTimer(time, resolution); + + Where + ----- + + - `time` in seconds, the start time + - `resolution` interval resolution in ms + +*/ + +joTimer = function(sec, resolution) { + this.setDuration(sec || 60); + + this.expiredEvent = new joSubject(this); + this.startEvent = new joSubject(this); + this.stopEvent = new joSubject(this); + this.updateEvent = new joSubject(this); + this.resetEvent = new joSubject(this); + + this.resolution = resolution || 100; + + this.init(); + this.started = 0; + this.paused = 0; +}; +joTimer.prototype = { + start: function(silent) { + var paused = this.paused; + + this.init(); + + if (paused) + this.started = joTime.timestamp() - paused; + else + this.started = joTime.timestamp(); + + this.paused = 0; + + var self = this; + + this.interval = setInterval(function() { + joDefer(self.update, self); + }, this.resolution); + + if (!silent) + this.startEvent.fire(); + + return this; + }, + + init: function() { + if (this.interval) + clearInterval(this.interval); + + this.interval = null; + this.lastRemaining = null; + + return this; + }, + + stop: function(silent) { + this.init(); + this.paused = joTime.timestamp() - this.started; + + if (!silent) + this.stopEvent.fire(); + + return this; + }, + + pause: function() { + if (this.interval) { + clearInterval(this.interval); + this.interval = 0; + } + }, + + resume: function() { + if (this.interval || this.paused) + return; + + var self = this; + this.interval = setInterval(function() { + joDefer(self.update, self); + }, this.resolution); + }, + + reset: function(silent) { + this.started = joTime.timestamp(); + this.paused = 0; + + if (!silent) + this.resetEvent.fire(); + + return this; + }, + + setDuration: function(sec) { + this.duration = sec * 1000; + + return this; + }, + + update: function() { + var remaining = Math.round((this.duration - (joTime.timestamp() - this.started)) / 1000); + + if (this.lastRemaining == null || remaining < this.lastRemaining) + this.updateEvent.fire(remaining); + + if (remaining <= 0) + this.expired(); + + this.lastRemaining = remaining; + + return this; + }, + + expired: function() { + this.stop(); +// this.update(); + + this.expiredEvent.fire(); + } +}; diff --git a/js/data/template.js b/js/data/template.js new file mode 100644 index 0000000..6fe07ef --- /dev/null +++ b/js/data/template.js @@ -0,0 +1,27 @@ + +joTemplate = function(template) { + this.setTemplate(template || ""); +}; +joTemplate.prototype = { + setTemplate: function(template) { + if (template && typeof template == 'object' && template instanceof Array) + this.template = template.join(" "); + else + this.template = template + ""; + + return this; + }, + + apply: function(data) { + var str = this.template + ""; + + // pretty wasteful, but this is quick/dirty + for (var i in data) { + var key = "__" + i + "__"; + var reg = new RegExp(key, "g"); + str = str.replace(reg, data[i]); + } + + return str; + } +}; diff --git a/js/ui/canvas.js b/js/ui/canvas.js new file mode 100644 index 0000000..e9a6ae3 --- /dev/null +++ b/js/ui/canvas.js @@ -0,0 +1,93 @@ + +function joCanvas(w, h) { + this.canvas = joDOM.create("canvas"); + + if (this.canvas) + this.ctx = this.canvas.getContext("2d"); + + this.ctx.imageSmoothingEnabled = false; + this.ctx.mozImageSmoothingEnabled = false; + this.ctx.oImageSmoothingEnabled = false; + this.ctx.webkitImageSmoothingEnabled = false; + + if (w || h) + this.setSize(w, h); +} +joCanvas.prototype = { + getImage: function() { + return this.canvas.toDataURL(); + }, + + getCSSImage: function() { + return "url(" + this.canvas.toDataURL() + ")"; + }, + + clear: function() { + this.ctx.clearRect(0, 0, this.width, this.height); + }, + + setSize: function(w, h) { + if (!w) + w = 50; + + if (!h) + h = 50; + + this.canvas.setAttribute("width", w); + this.canvas.setAttribute("height", h); + + this.width = w; + this.height = h; + + return this; + }, + + getContext: function() { + return this.ctx; + }, + + roundRect: function(sx, sy, ex, ey, r) { + var r2d = Math.PI / 180; + + if ((ex - sx) - (2 * r) < 0) + r = ((ex - sx) / 2); + + if ((ey - sy) - (2 * r) < 0 ) + r = ((ey - sy) / 2); + + var ctx = this.ctx; + + ctx.beginPath(); + ctx.moveTo(sx + r, sy); + ctx.lineTo(ex - r, sy); + ctx.arc(ex - r, sy + r, r, r2d * 270, r2d * 360); + ctx.lineTo(ex, ey - r); + ctx.arc(ex - r, ey - r, r, 0, r2d * 90); + ctx.lineTo(sx + r, ey); + ctx.arc(sx + r, ey - r, r, r2d * 90, r2d * 180); + ctx.lineTo(sx, sy + r); + ctx.arc(sx + r, sy + r, r, r2d * 180, r2d * 270); + ctx.closePath(); + + return this; + }, + + setFont: function(font) { + this.ctx.font = font; + + return this; + }, + + ellipse: function(sx, sy, r) { + this.ctx.beginPath(); + this.ctx.arc(sx, sy, r, 0, Math.PI * 2); + this.ctx.closePath(); + + return this; + }, + + getNode: function() { + return this.canvas; + } +}; + diff --git a/js/ui/gesture.js b/js/ui/gesture.js index 8ab9aa2..f35df6d 100644 --- a/js/ui/gesture.js +++ b/js/ui/gesture.js @@ -2,10 +2,8 @@ joGesture ========= - Experimental global gesture handler (keyboard, dpad, back, home, flick?). - This needs a lot more fleshing out, so it's not (quite) ready for general - consumption. - + Global gesture handler. + Events ------ @@ -32,11 +30,6 @@ - `activateEvent` - `deactivateEvent` - > Note that the events setup here are for the browser - > or webOS. The `setEvents` method most likely needs to change - > based on which OS you're running, although looking more deeply - > into PhoneGap event layer. - */ joGesture = { load: function() { diff --git a/js/ui/image.js b/js/ui/image.js index a8ef267..1f57da8 100644 --- a/js/ui/image.js +++ b/js/ui/image.js @@ -57,3 +57,4 @@ joImage.extend(joControl, { this.container.src = data; } }); + diff --git a/js/ui/input.js b/js/ui/input.js index 5469ff8..2c7f2c1 100644 --- a/js/ui/input.js +++ b/js/ui/input.js @@ -35,15 +35,23 @@ You can manually set focus or call the `blur()` method (which also triggers a data save). - - `setData()` + - `setData(string)` Pass in either some arbitrary value for the control, or a reference to a joDataSource if you want to automatically bind to a storage system (e.g. joPreference). + + - `setPlaceholder(string)` + + Display placeholder text on an empty input control (* not all + browsers support this). */ -joInput = function(data) { +joInput = function(data, placeholder) { joControl.apply(this, arguments); + + if (placeholder) + this.setPlaceholder(placeholder); }; joInput.extend(joControl, { tagName: "input", @@ -63,6 +71,11 @@ joInput.extend(joControl, { return this; }, + + setPlaceholder: function(placeholder) { + if (typeof this.container !== "undefined") + this.container.setAttribute("placeholder", placeholder); + }, getData: function() { if (typeof this.container.value !== "undefined") @@ -87,7 +100,7 @@ joInput.extend(joControl, { if (!o) return; - o.setAttribute("type", "text"); + o.setAttribute("type", this.type); o.setAttribute("tabindex", "1"); o.contentEditable = this.enabled; @@ -100,13 +113,6 @@ joInput.extend(joControl, { joControl.prototype.setEvents.call(this); joEvent.on(this.container, "keydown", this.onKeyDown, this); - -/* - this.container.addEventListener('touchmove', function(e) { - e.preventDefault(); - joEvent.stop(e); - }, false); -*/ }, onKeyDown: function(e) { diff --git a/js/ui/popup.js b/js/ui/popup.js index 6f25db8..b148a5c 100644 --- a/js/ui/popup.js +++ b/js/ui/popup.js @@ -45,19 +45,29 @@ joPopup.extend(joContainer, { }, hide: function() { - joEvent.on(this.container, "webkitTransitionEnd", this.onHide, this); - this.container.className = 'hide'; + joGesture.backEvent.release(this.hide, this); + + joDefer(function() { + joEvent.on(this.container, joEvent.map.transitionend, this.onHide, this); + this.container.className = 'hide'; + }, this); return this; }, onHide: function() { + joEvent.remove(this.container, joEvent.map.transitionend, this.onHide, this); this.hideEvent.fire(); }, show: function() { - this.container.className = 'show'; - this.showEvent.fire(); + joEvent.remove(this.container, joEvent.map.transitionend, this.onHide, this); + joDefer(function() { + this.container.className = 'show'; + this.showEvent.fire(); + }, this); + + joGesture.backEvent.capture(this.hide, this); return this; } diff --git a/js/ui/screen.js b/js/ui/screen.js index ab0707d..e1252b9 100644 --- a/js/ui/screen.js +++ b/js/ui/screen.js @@ -101,14 +101,26 @@ joScreen.extend(joContainer, { else { this.popup.setData(data); } -// this.shim.showEvent.subscribe(this.popup.show, this); + this.shim.hideEvent.subscribe(this.hideShim, this); + this.popup.hideEvent.subscribe(this.hidePopup, this); this.shim.show(); this.popup.show(); return this; }, + + hideShim: function() { + this.shim = null; + + if (this.popup) + this.popup.hide(); + + return this; + }, hidePopup: function() { + this.popup = null; + if (this.shim) this.shim.hide(); diff --git a/js/ui/scroller.js b/js/ui/scroller.js index 462b424..38e19dd 100644 --- a/js/ui/scroller.js +++ b/js/ui/scroller.js @@ -364,6 +364,12 @@ joScroller.extend(joContainer, { node.jotop = y; node.joleft = x; }, + + setPositionNative: function(x, y, node) { + node.scrollTop = y; + + return this; + }, setPosition: function(x, y, node) { node.style.webkitTransform = "translate3d(" + x + "px, " + y + "px, 0)"; diff --git a/js/ui/shim.js b/js/ui/shim.js index 23f9c94..7697113 100644 --- a/js/ui/shim.js +++ b/js/ui/shim.js @@ -45,8 +45,10 @@ joShim.extend(joContainer, { }, hide: function() { - this.container.className = ''; - joEvent.on(this.container, "webkitTransitionEnd", this.onHide, this); + joDefer(function() { + joEvent.on(this.container, joEvent.map.transitionend, this.onHide, this); + this.container.className = ''; + }, this); return this; }, @@ -54,8 +56,10 @@ joShim.extend(joContainer, { show: function() { this.attach(); - this.container.className = 'show'; - joEvent.on(this.container, "webkitTransitionEnd", this.onShow, this); + joEvent.remove(this.container, joEvent.map.transitionend, this.onHide, this); + joDefer(function() { + this.container.className = 'show'; + }, this); // default parent to the document body if (!this.lastParent) @@ -69,6 +73,7 @@ joShim.extend(joContainer, { }, onHide: function() { + joEvent.remove(this.container, joEvent.map.transitionend, this.onHide, this); this.detach(); this.hideEvent.fire(); } diff --git a/js/ui/slider.js b/js/ui/slider.js index 3538835..69e8882 100644 --- a/js/ui/slider.js +++ b/js/ui/slider.js @@ -131,7 +131,8 @@ joSlider.extend(joControl, { joEvent.stop(e); this.reset(); - + joDOM.addCSSClass(this.container, "live"); + var node = this.container.firstChild; this.inMotion = true; @@ -157,7 +158,7 @@ joSlider.extend(joControl, { joEvent.stop(e); e.preventDefault(); - + var point = this.getMouse(e); var y = point.y; @@ -198,8 +199,6 @@ joSlider.extend(joControl, { }, initValue: function(value) { - console.log(this.container); - if (!this.container) return this; @@ -248,6 +247,8 @@ joSlider.extend(joControl, { var point = this.getMouse(e); var x = Math.floor(point.x); var t = this.thumb.offsetWidth; + + joDOM.removeCSSClass(this.container, "live"); x = x - t; diff --git a/js/ui/stack.js b/js/ui/stack.js index 3476514..9d75aaf 100644 --- a/js/ui/stack.js +++ b/js/ui/stack.js @@ -165,16 +165,16 @@ joStack.extend(joContainer, { var self = this; var transitionevent = null; - joDefer(animate, this, 1); + joDefer(animate, this, 20); function animate() { // FIXME: AHHH must have some sort of transition for this to work, // need to check computed style for transition to make this // better if (typeof window.onwebkittransitionend !== 'undefined') - transitionevent = joEvent.on(newchild, "webkitTransitionEnd", cleanup, self); + transitionevent = joEvent.on(newchild, joEvent.map.transitionend, cleanup, self); else - joDefer(cleanup, this, 200); + joDefer(cleanup, this, 500); if (newclass && newchild) joDOM.removeCSSClass(newchild, newclass); @@ -192,7 +192,7 @@ joStack.extend(joContainer, { if (newchild) { if (transitionevent) - joEvent.remove(newchild, "webkitTransitionEnd", transitionevent); + joEvent.remove(newchild, joEvent.map.transitionend, transitionevent); joDOM.removeCSSClass(newchild, "next"); joDOM.removeCSSClass(newchild, "prev"); @@ -236,7 +236,7 @@ joStack.extend(joContainer, { push: function(o) { // if (!this.data || !this.data.length || o !== this.data[this.data.length - 1]) // return; - + // don't push the same view we already have if (this.data && this.data.length && this.data[this.data.length - 1] === o) return this; @@ -245,6 +245,8 @@ joStack.extend(joContainer, { this.index = this.data.length - 1; this.draw(); this.pushEvent.fire(o); + + this.captureBack(); return this; }, @@ -270,6 +272,8 @@ joStack.extend(joContainer, { this.hide(); } + this.captureBack(); + if (this.data.length > 0) this.popEvent.fire(); @@ -289,6 +293,8 @@ joStack.extend(joContainer, { this.index = 0; // this.lastNode = null; this.draw(); + + this.captureBack(); this.popEvent.fire(); this.homeEvent.fire(); @@ -327,7 +333,7 @@ joStack.extend(joContainer, { return this; }, - + hide: function() { if (this.visible) { this.visible = false; @@ -337,5 +343,12 @@ joStack.extend(joContainer, { } return this; + }, + + captureBack: function() { + if (this.index > 0) + joGesture.backEvent.capture(this.pop, this); + else if (this.index <= 0) + joGesture.backEvent.release(this.pop, this); } }); diff --git a/js/ui/toggle.js b/js/ui/toggle.js index 2c132c6..8e883df 100644 --- a/js/ui/toggle.js +++ b/js/ui/toggle.js @@ -75,9 +75,11 @@ joToggle.extend(joControl, { this.button.innerHTML = this.labels[(this.data) ? 1 : 0]; - if (this.data) - joDOM.addCSSClass(this.container, "on"); - else - joDOM.removeCSSClass(this.container, "on"); + joDefer(function() { + if (this.data) + joDOM.addCSSClass(this.container, "on"); + else + joDOM.removeCSSClass(this.container, "on"); + }, this); } }); diff --git a/js/ui/view.js b/js/ui/view.js index d5b21c1..07ea2c5 100644 --- a/js/ui/view.js +++ b/js/ui/view.js @@ -128,6 +128,11 @@ joView.prototype = { return this; }, - + + setId: function(id) { + this.container.id = id; + return this; + }, + setEvents: function() {} }; diff --git a/samples/kitchensink/htmltest.html b/samples/kitchensink/htmltest.html new file mode 100644 index 0000000..c401866 --- /dev/null +++ b/samples/kitchensink/htmltest.html @@ -0,0 +1,9 @@ +

Embedded HTML

+ +

This HTML fragment was loaded dynamically. The joHTML control +also intercepts links so you +can keep them on the page. This is useful for pure content cases +such as disclaimers, app info, and help.

+ +

Note that since Jo uses custom tag names for its controls, +you should have little if any CSS overlap with your App UI.

diff --git a/samples/kitchensink/htmltestlink.html b/samples/kitchensink/htmltestlink.html new file mode 100644 index 0000000..9c05c89 --- /dev/null +++ b/samples/kitchensink/htmltestlink.html @@ -0,0 +1,10 @@ +

Embedded HTML Link

+ +

You tapped a link, the app code listened for it and +handled loading a different HTML fragment into the file source...

+ +

Which automatically updated the UI. You could also +push these "pages" onto your UI stack, but that's a little more +involved.

+ +Back to the original file diff --git a/samples/kitchensink/index.html b/samples/kitchensink/index.html index 4ba99f4..2152889 100644 --- a/samples/kitchensink/index.html +++ b/samples/kitchensink/index.html @@ -5,60 +5,16 @@ + + Kitchen Sink - + - -
- - This was Defined as HTML - - - Apple Touch Icon -

- Welcome to a "kitchen sink" demo of some of the things you - can do with the Jo HTML5 framework. -

-

- One thing I hope comes across is how flexible the framework - truly is. This demo illustrates not only some of the important - goodies like widgets and interacting with data, but also some - of the many ways you can go about getting them to work. -

-

- For example, this "about" content is pulled directly from the - index.html file in the project using joInterface. - This entire box can be defined by your HTML, or using pure - JavaScript, or a mix. -

-

- Most of the coding examples use a pure JavaScript approach - because that tends to be more performant in terms of load time, - and tends to build tighter apps. -

-

- However, as this view shows, Jo doesn't try to force you to - go any deeper into the framework than you want to go. By learning - only a few special tags, you can have a quick prototype in HTML - in minutes. -

-

- Once you have that prototype, it's easy to turn those styled tags - into working UI controls by using the joInterface class. Heck, - you can even take static HTML content and place it directly into - most of the UI widgets as a string, or by passing a reference to a - parent DOM element. -

-
-
-
-
- @@ -67,9 +23,8 @@ - - - + + diff --git a/samples/kitchensink/js/ajax.js b/samples/kitchensink/js/ajax.js deleted file mode 100644 index e69de29..0000000 diff --git a/samples/kitchensink/js/app.js b/samples/kitchensink/js/app.js index 862284f..be8019f 100644 --- a/samples/kitchensink/js/app.js +++ b/samples/kitchensink/js/app.js @@ -1,37 +1,21 @@ App = { load: function() { + // loading Jo is required jo.load(); - // grab the HTML for our about box - var about = joDOM.get("about").innerHTML; - - document.body.addEventListener('touchmove', function(e) { - e.preventDefault(); - joEvent.stop(e); - }, false); - - // this is a more complex UI with a nav bar and a toolbar - this.scn = new joScreen( - new joContainer([ - new joFlexcol([ - this.nav = new joNavbar(), - this.stack = new joStack() - ]), - this.toolbar = new joToolbar("This is a footer, neat huh?") - ]).setStyle({position: "absolute", top: "0", left: "0", bottom: "0", right: "0"}) + // typical card stack, nav and footer + this.screen = new joScreen( + new joFlexcol([ + this.nav = new joNavbar(), + this.stack = new joStackScroller(), + this.toolbar = new joToolbar("This is a toolbar") + ]) ); + // attach the nav to our stack this.nav.setStack(this.stack); - - joCache.set("about", function() { - var card = new joCard(about).setTitle("About"); - - return card; - }); - + + // push our menu card this.stack.push(joCache.get("menu")); - console.log(this); - - joGesture.backEvent.subscribe(this.stack.pop, this.stack); } }; diff --git a/samples/kitchensink/js/audio.js b/samples/kitchensink/js/audio.js deleted file mode 100644 index e69de29..0000000 diff --git a/samples/kitchensink/js/html.js b/samples/kitchensink/js/html.js new file mode 100644 index 0000000..227d02f --- /dev/null +++ b/samples/kitchensink/js/html.js @@ -0,0 +1,36 @@ +joCache.set("html", function() { + // create an HTML file loader + var file = new joFileSource("htmltest.html"); + + // HTML control, hook it up to file and subscribe to URL clicks + var html = new joHTML() + .setDataSource(file) + .selectEvent.subscribe(function(url) { + // a link was clicked, tell our file source to load its url + file.setQuery(url).load(); + }); + + // for added fun, subscribe to the filesource and + // keep a display of its URL and file size. + var info = new joLabel(); + file.changeEvent.subscribe(function(data) { + info.setData(file.query + " (" + data.length + " characters)"); + }); + + // the UI for this card + card = new joCard([ + new joGroup([ + new joHTML("

Inline HTML

This HTML was included inline, click the load button below to pull in another file asynchronously.

"), + new joButton("Load HTML File") + .selectEvent.subscribe(function() { file.load(); }, this) + ]), + // this is our dynamic HTML control defined above + new joGroup(html), + info + ]).setTitle("Embedded HTML Browser"); + + console.log(card); + + return card; +}); + diff --git a/samples/kitchensink/js/menu.js b/samples/kitchensink/js/menu.js index e9b33c9..8e47d29 100644 --- a/samples/kitchensink/js/menu.js +++ b/samples/kitchensink/js/menu.js @@ -4,15 +4,12 @@ joCache.set("menu", function() { // some inline data and chaining going on here, // dont be afraid, it'll all make sense later var card = new joCard([ - new joTitle("Select an option below"), new joMenu([ - { title: "About", id: "about" }, - { title: "Form Widgets", id: "widgets" }, - { title: "List Views", id: "lists" }, - { title: "Table View", id: "tables" }, - { title: "Popup Dialogs", id: "popups" }, - { title: "Ajax Calls", id: "ajax" }, - { title: "Themes and CSS", id: "themes" } + { title: "UI Widgets", id: "widgets" }, + { title: "Simple Table View", id: "table" }, + { title: "Embedded HTML Browser", id: "html" }, + { title: "Popups & Dialogs", id: "popups" }, + { title: "CSS Utility Functions", id: "themes" } ]).selectEvent.subscribe(function(id) { App.stack.push(joCache.get(id)); }) @@ -21,7 +18,8 @@ joCache.set("menu", function() { // hey, you don't have to make messy chained and // inlined code; that's a coding style decision // Jo doesn't pretend it should make for you. - card.setTitle("Jo Kitchen Sink Demo"); + card.setTitle("Jo App Framework Demos"); + // required return card; }); diff --git a/samples/kitchensink/js/popups.js b/samples/kitchensink/js/popups.js index a89d7dc..9342310 100644 --- a/samples/kitchensink/js/popups.js +++ b/samples/kitchensink/js/popups.js @@ -18,11 +18,11 @@ joCache.set("popups", function() { card.setTitle("Popup Dialogs"); simple.selectEvent.subscribe(function() { - App.scn.alert("This is an Alert", "It's a very simple call to the joScreen object. It's similar to the good ol' alert() function built into most JavaScript engines."); + App.screen.alert("This is an Alert", "It's a very simple call to the joScreen object. It's similar to the good ol' alert() function built into most JavaScript engines."); }); complex.selectEvent.subscribe(function() { - App.scn.showPopup(joCache.get("popup")); + App.screen.showPopup(joCache.get("popup")); }); return card; @@ -45,7 +45,7 @@ joCache.set("popup", function() { function pop() { console.log("hide popup"); - App.scn.hidePopup(); + App.screen.hidePopup(); } return popup; diff --git a/samples/kitchensink/js/table.js b/samples/kitchensink/js/table.js new file mode 100644 index 0000000..3f21ac3 --- /dev/null +++ b/samples/kitchensink/js/table.js @@ -0,0 +1,18 @@ +joCache.set("table", function() { + var back; + + var card = new joCard([ + new joTable([ + ["Name", "Phone", "Email"], + ["Bob", "555-1234", "bob@bob.not"], + ["Candy", "555-2345", "candy@candy.not"], + ["Doug", "555-3456", "doug@doug.not"], + ["Evan", "555-4567", "evan@evan.not"], + ["Frank", "555-5678", "frank@frank.not"] + ]).selectEvent.subscribe(function(index, table) { + console.log(table.getNodeData(table.getRow())); + }, this) + ]).setTitle("Table Demo"); + + return card; +}); diff --git a/samples/kitchensink/js/tables.js b/samples/kitchensink/js/tables.js deleted file mode 100644 index e69de29..0000000 diff --git a/samples/kitchensink/js/themes.js b/samples/kitchensink/js/themes.js index 9be5566..ac03ea8 100644 --- a/samples/kitchensink/js/themes.js +++ b/samples/kitchensink/js/themes.js @@ -2,7 +2,7 @@ joCache.set("themes", function() { var card, theme, size; card = new joCard([ - new joTitle("Pick a theme"), + new joCaption("Jo has a few built-in CSS munging functions, illustrated below."), new joGroup([ new joLabel("Colors"), theme = new joSelect([ @@ -17,7 +17,7 @@ joCache.set("themes", function() { "Funky" ], 0)) ]), - new joHTML("These theme options are all controlled with CSS. For this demo, we're dynamically setting styles inline using joDOM.applyCSSRule. Most apps should have their own style, and would not need to load CSS rules on the fly like this, but it makes for a more interesting demo."), + new joHTML("These app-level 'theme' options are all controlled with CSS. For this demo, we're dynamically setting styles inline using joDOM.applyCSSRule. Most apps should have their own style, and would not need to load CSS rules on the fly like this, but it makes for a more interesting demo."), new joHTML("WARNING: Your eyes may burn while applying these theme tweaks.") ]); diff --git a/samples/kitchensink/js/widgets.js b/samples/kitchensink/js/widgets.js index 354c674..d8fb1a5 100644 --- a/samples/kitchensink/js/widgets.js +++ b/samples/kitchensink/js/widgets.js @@ -1,4 +1,5 @@ joCache.set("widgets", function() { + var slider; var card = new joCard([ new joTitle("Input Boxes"), new joGroup([ @@ -6,11 +7,13 @@ joCache.set("widgets", function() { new joFlexrow(new joInput("Hello, Jo!")), new joLabel("joPasswordInput"), new joFlexrow(new joPasswordInput("password")), + new joLabel("joInput with Placeholder"), + new joFlexrow(new joInput("", "Placeholder Text")), new joLabel("joTextArea"), new joFlexrow(new joTextarea("This is some multi-line text, Jo!")), new joDivider(), new joFlexrow([ - new joLabel("Left Aligned").setStyle({className:"left", marginTop:"2px"}), + new joLabel("Left Aligned").setStyle({className: "left", marginTop: "2px"}), new joInput("From CSS").setStyle({width: "150px", marginBottom: "0"}) ]) ]), @@ -26,7 +29,10 @@ joCache.set("widgets", function() { "Chocolate Mousse", "Rum Raisin Ice Cream", "Fudge Sundae" - ]), + ]).openEvent.subscribe(function(data, select) { + console.log(select); + App.stack.scrollTo(select); + }), new joFlexrow([ new joLabel("joToggle").setStyle("left"), new joToggle(true) @@ -43,14 +49,6 @@ joCache.set("widgets", function() { new joFlexrow(new joInput("Hello again, Jo!")) ]) ]), -/* - new joLabel("Horizontal Scroller"), - new joScroller([ - new joFlexrow([ - "HI", "HELLO", "HOLA", "SUP", "CHEERS", "DUDE", "YO" - ]) - ]).setScroll(true, false).setStyle('iconz'), -*/ new joDivider(), new joButton("joButton").selectEvent.subscribe(function() { App.scn.alert("You pressed a button!"); @@ -69,4 +67,3 @@ joCache.set("widgets", function() { return card; }); -var slider; \ No newline at end of file diff --git a/samples/test.html b/samples/test.html index 1f74418..0e74e9f 100644 --- a/samples/test.html +++ b/samples/test.html @@ -4,10 +4,12 @@ + + joTest - +