mirror of
http://git.whoc.org.uk/git/password-manager.git
synced 2024-11-14 18:39:01 +01:00
Interim synchronization with internal repository
This is an intermir commit to share what is going on with the development of the new /delta version.
This commit is contained in:
parent
6dd16d9359
commit
f8da092f3d
File diff suppressed because one or more lines are too long
431
frontend/delta/fonts/IcoMoon/Clipperz Icon font.json
Executable file
431
frontend/delta/fonts/IcoMoon/Clipperz Icon font.json
Executable file
@ -0,0 +1,431 @@
|
|||||||
|
{
|
||||||
|
"IcoMoonType": "selection",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"icon": {
|
||||||
|
"paths": [
|
||||||
|
"M2.259 734.824h279.462v286.917h-279.462v-286.917z",
|
||||||
|
"M2.259 2.259h279.462v286.917h-279.462v-286.917z",
|
||||||
|
"M2.259 368.519h279.462v286.917h-279.462v-286.917z"
|
||||||
|
],
|
||||||
|
"width": 284,
|
||||||
|
"grid": 0,
|
||||||
|
"tags": [
|
||||||
|
"commands"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"order": 22,
|
||||||
|
"id": 0,
|
||||||
|
"prevSize": 32,
|
||||||
|
"code": 58894,
|
||||||
|
"name": "commands",
|
||||||
|
"ligatures": "commands"
|
||||||
|
},
|
||||||
|
"setIdx": 0,
|
||||||
|
"iconIdx": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": {
|
||||||
|
"paths": [
|
||||||
|
"M667.586 345.635v-338.544h-268.055v338.544l-299.967-121.263-90.486 257.986 310.037 104.527-198.134 262.808 224.514 164.237 184.802-279.685 203.382 279.685 221.11-164.237-203.382-262.808 319.397-107.080-90.486-257.986zM1220.574 2319.317z"
|
||||||
|
],
|
||||||
|
"width": 1080,
|
||||||
|
"grid": 0,
|
||||||
|
"tags": [
|
||||||
|
"logo"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"order": 4,
|
||||||
|
"id": 0,
|
||||||
|
"prevSize": 32,
|
||||||
|
"code": 58884,
|
||||||
|
"name": "logo",
|
||||||
|
"ligatures": "clipperz"
|
||||||
|
},
|
||||||
|
"setIdx": 1,
|
||||||
|
"iconIdx": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": {
|
||||||
|
"paths": [
|
||||||
|
"M96.188 0h288.562c52.906 0 126.796 30.606 164.204 68.014l446.99 446.99c37.408 37.408 37.408 98.624 0 136.032l-344.91 344.906c-37.408 37.41-98.622 37.41-136.030 0l-446.99-446.988c-37.408-37.41-68.014-111.302-68.014-164.204v-288.562c0-52.904 43.286-96.188 96.188-96.188zM224 320c53.020 0 96-42.98 96-96s-42.98-96-96-96-96 42.98-96 96 42.98 96 96 96z"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"tag",
|
||||||
|
"price"
|
||||||
|
],
|
||||||
|
"grid": 16
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": 48,
|
||||||
|
"order": 6,
|
||||||
|
"prevSize": 32,
|
||||||
|
"code": 58885,
|
||||||
|
"name": "tag",
|
||||||
|
"ligatures": "tag"
|
||||||
|
},
|
||||||
|
"setIdx": 2,
|
||||||
|
"iconIdx": 49
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": {
|
||||||
|
"paths": [
|
||||||
|
"M96 64h224c52.8 0 126.546 30.546 163.882 67.882l376.236 376.236c37.334 37.334 37.334 98.428 0 135.764l-280.236 280.234c-37.334 37.336-98.428 37.336-135.764 0l-376.234-376.234c-37.338-37.336-67.884-111.082-67.884-163.882v-224c0-52.8 43.2-96 96-96zM224 384c53.020 0 96-42.98 96-96s-42.98-96-96-96-96 42.98-96 96 42.98 96 96 96zM1001.374 598.626l-342.378 342.378c36.264 19.16 82.462 13.538 112.886-16.888l280.236-280.234c37.334-37.336 37.334-98.43 0-135.764l-376.236-376.236c-37.336-37.336-111.082-67.882-163.882-67.882l489.374 489.372c12.444 12.446 12.444 32.808 0 45.254z"
|
||||||
|
],
|
||||||
|
"width": 1088,
|
||||||
|
"tags": [
|
||||||
|
"tags",
|
||||||
|
"prices"
|
||||||
|
],
|
||||||
|
"grid": 16
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": 49,
|
||||||
|
"order": 1,
|
||||||
|
"prevSize": 32,
|
||||||
|
"code": 58880,
|
||||||
|
"name": "tags",
|
||||||
|
"ligatures": "tags"
|
||||||
|
},
|
||||||
|
"setIdx": 2,
|
||||||
|
"iconIdx": 50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": {
|
||||||
|
"paths": [
|
||||||
|
"M928 128h-832c-52.8 0-96 43.2-96 96v640c0 52.8 43.2 96 96 96h832c52.8 0 96-43.2 96-96v-640c0-52.8-43.2-96-96-96zM398.74 550.372l-270.74 210.892v-501.642l270.74 290.75zM176.38 256h671.24l-335.62 252-335.62-252zM409.288 561.698l102.712 110.302 102.71-110.302 210.554 270.302h-626.528l210.552-270.302zM625.26 550.372l270.74-290.75v501.642l-270.74-210.892z"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"envelope",
|
||||||
|
"mail",
|
||||||
|
"email",
|
||||||
|
"contact",
|
||||||
|
"letter"
|
||||||
|
],
|
||||||
|
"grid": 16
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": 64,
|
||||||
|
"order": 8,
|
||||||
|
"prevSize": 32,
|
||||||
|
"code": 58888,
|
||||||
|
"name": "envelope",
|
||||||
|
"ligatures": "email"
|
||||||
|
},
|
||||||
|
"setIdx": 2,
|
||||||
|
"iconIdx": 65
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": {
|
||||||
|
"paths": [
|
||||||
|
"M658.744 749.256l-210.744-210.746v-282.51h128v229.49l173.256 173.254zM512 0c-282.77 0-512 229.23-512 512s229.23 512 512 512 512-229.23 512-512-229.23-512-512-512zM512 896c-212.078 0-384-171.922-384-384s171.922-384 384-384c212.078 0 384 171.922 384 384 0 212.078-171.922 384-384 384z"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"clock",
|
||||||
|
"time",
|
||||||
|
"schedule"
|
||||||
|
],
|
||||||
|
"grid": 16
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": 72,
|
||||||
|
"order": 7,
|
||||||
|
"prevSize": 32,
|
||||||
|
"code": 58887,
|
||||||
|
"name": "clock",
|
||||||
|
"ligatures": "recent"
|
||||||
|
},
|
||||||
|
"setIdx": 2,
|
||||||
|
"iconIdx": 73
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": {
|
||||||
|
"paths": [
|
||||||
|
"M384 128c0-70.692 57.308-128 128-128 70.692 0 128 57.308 128 128 0 70.692-57.308 128-128 128-70.692 0-128-57.308-128-128zM655.53 240.47c0-70.692 57.308-128 128-128s128 57.308 128 128c0 70.692-57.308 128-128 128-70.692 0-128-57.308-128-128zM832 512c0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64zM719.53 783.53c0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64zM448.002 896c-0-0-0-0-0-0 0-35.346 28.654-64 64-64 35.346 0 64 28.654 64 64 0 0 0 0 0 0 0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64zM176.472 783.53c-0-0-0-0-0-0 0-35.346 28.654-64 64-64 35.346 0 64 28.654 64 64 0 0 0 0 0 0 0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64zM144.472 240.47c-0-0-0-0-0-0 0-53.019 42.981-96 96-96 53.019 0 96 42.981 96 96 0 0 0 0 0 0 0 53.019-42.981 96-96 96-53.019 0-96-42.981-96-96zM56 512c0-39.765 32.235-72 72-72s72 32.235 72 72c0 39.765-32.235 72-72 72-39.765 0-72-32.235-72-72z"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"spinner",
|
||||||
|
"loading",
|
||||||
|
"busy",
|
||||||
|
"wait",
|
||||||
|
"wheel"
|
||||||
|
],
|
||||||
|
"grid": 16
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": 120,
|
||||||
|
"order": 11,
|
||||||
|
"prevSize": 32,
|
||||||
|
"code": 58891,
|
||||||
|
"name": "spinner",
|
||||||
|
"ligatures": "loading"
|
||||||
|
},
|
||||||
|
"setIdx": 2,
|
||||||
|
"iconIdx": 121
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": {
|
||||||
|
"paths": [
|
||||||
|
"M992.262 871.396l-242.552-206.294c-25.074-22.566-51.89-32.926-73.552-31.926 57.256-67.068 91.842-154.078 91.842-249.176 0-212.078-171.922-384-384-384-212.076 0-384 171.922-384 384 0 212.078 171.922 384 384 384 95.098 0 182.108-34.586 249.176-91.844-1 21.662 9.36 48.478 31.926 73.552l206.294 242.552c35.322 39.246 93.022 42.554 128.22 7.356s31.892-92.898-7.354-128.22zM384 640c-141.384 0-256-114.616-256-256s114.616-256 256-256 256 114.616 256 256-114.614 256-256 256z"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"search",
|
||||||
|
"magnifier",
|
||||||
|
"lookup",
|
||||||
|
"find"
|
||||||
|
],
|
||||||
|
"grid": 16
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": 127,
|
||||||
|
"order": 5,
|
||||||
|
"prevSize": 32,
|
||||||
|
"code": 58886,
|
||||||
|
"name": "search",
|
||||||
|
"ligatures": "search"
|
||||||
|
},
|
||||||
|
"setIdx": 2,
|
||||||
|
"iconIdx": 128
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": {
|
||||||
|
"paths": [
|
||||||
|
"M832 448h-64v-192c0-141.384-114.616-256-256-256s-256 114.616-256 256v192h-64c-35.2 0-64 28.8-64 64v448c0 35.2 28.8 64 64 64h640c35.2 0 64-28.8 64-64v-448c0-35.2-28.8-64-64-64zM512 832c-35.346 0-64-28.654-64-64s28.654-64 64-64 64 28.654 64 64-28.654 64-64 64zM640 448h-256v-192c0-70.58 57.42-128 128-128s128 57.42 128 128v192z"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"lock",
|
||||||
|
"secure",
|
||||||
|
"private",
|
||||||
|
"encrypted"
|
||||||
|
],
|
||||||
|
"grid": 16
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": 136,
|
||||||
|
"order": 9,
|
||||||
|
"prevSize": 32,
|
||||||
|
"code": 58889,
|
||||||
|
"name": "lock",
|
||||||
|
"ligatures": "password"
|
||||||
|
},
|
||||||
|
"setIdx": 2,
|
||||||
|
"iconIdx": 137
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": {
|
||||||
|
"paths": [
|
||||||
|
"M64 192h896v192h-896zM64 448h896v192h-896zM64 704h896v192h-896z"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"menu",
|
||||||
|
"list",
|
||||||
|
"items",
|
||||||
|
"lines",
|
||||||
|
"options"
|
||||||
|
],
|
||||||
|
"grid": 16
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": 184,
|
||||||
|
"order": 14,
|
||||||
|
"prevSize": 32,
|
||||||
|
"code": 58881,
|
||||||
|
"name": "menu2",
|
||||||
|
"ligatures": "menu"
|
||||||
|
},
|
||||||
|
"setIdx": 2,
|
||||||
|
"iconIdx": 185
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": {
|
||||||
|
"paths": [
|
||||||
|
"M1014.662 822.66c-0.004-0.004-0.008-0.008-0.012-0.010l-310.644-310.65 310.644-310.65c0.004-0.004 0.008-0.006 0.012-0.010 3.344-3.346 5.762-7.254 7.312-11.416 4.246-11.376 1.824-24.682-7.324-33.83l-146.746-146.746c-9.148-9.146-22.45-11.566-33.828-7.32-4.16 1.55-8.070 3.968-11.418 7.31 0 0.004-0.004 0.006-0.008 0.010l-310.648 310.652-310.648-310.65c-0.004-0.004-0.006-0.006-0.010-0.010-3.346-3.342-7.254-5.76-11.414-7.31-11.38-4.248-24.682-1.826-33.83 7.32l-146.748 146.748c-9.148 9.148-11.568 22.452-7.322 33.828 1.552 4.16 3.97 8.072 7.312 11.416 0.004 0.002 0.006 0.006 0.010 0.010l310.65 310.648-310.65 310.652c-0.002 0.004-0.006 0.006-0.008 0.010-3.342 3.346-5.76 7.254-7.314 11.414-4.248 11.376-1.826 24.682 7.322 33.83l146.748 146.746c9.15 9.148 22.452 11.568 33.83 7.322 4.16-1.552 8.070-3.97 11.416-7.312 0.002-0.004 0.006-0.006 0.010-0.010l310.648-310.65 310.648 310.65c0.004 0.002 0.008 0.006 0.012 0.008 3.348 3.344 7.254 5.762 11.414 7.314 11.378 4.246 24.684 1.826 33.828-7.322l146.746-146.748c9.148-9.148 11.57-22.454 7.324-33.83-1.552-4.16-3.97-8.068-7.314-11.414z"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"close",
|
||||||
|
"cancel",
|
||||||
|
"quit",
|
||||||
|
"remove",
|
||||||
|
"cross"
|
||||||
|
],
|
||||||
|
"grid": 16
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": 253,
|
||||||
|
"order": 3,
|
||||||
|
"prevSize": 32,
|
||||||
|
"code": 58882,
|
||||||
|
"name": "close",
|
||||||
|
"ligatures": "failure, failed"
|
||||||
|
},
|
||||||
|
"setIdx": 2,
|
||||||
|
"iconIdx": 254
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": {
|
||||||
|
"paths": [
|
||||||
|
"M864 128l-480 480-224-224-160 160 384 384 640-640z"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"checkmark",
|
||||||
|
"tick",
|
||||||
|
"correct",
|
||||||
|
"accept",
|
||||||
|
"ok"
|
||||||
|
],
|
||||||
|
"grid": 16
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": 254,
|
||||||
|
"order": 2,
|
||||||
|
"prevSize": 32,
|
||||||
|
"code": 58883,
|
||||||
|
"name": "checkmark",
|
||||||
|
"ligatures": "done, ok"
|
||||||
|
},
|
||||||
|
"setIdx": 2,
|
||||||
|
"iconIdx": 255
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": {
|
||||||
|
"paths": [
|
||||||
|
"M819.2 102.4h-410.624c-56.32 0-101.376 45.056-101.376 101.376v410.624c0 56.32 46.080 102.4 102.4 102.4h409.6c56.32 0 102.4-46.080 102.4-102.4v-409.6c0-56.32-46.080-102.4-102.4-102.4zM819.2 614.4h-409.6v-409.6h409.6v409.6zM204.8 512h-102.4v307.2c0 56.32 46.080 102.4 102.4 102.4h307.2v-102.4h-307.2v-307.2z"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"popup",
|
||||||
|
"popout",
|
||||||
|
"new window"
|
||||||
|
],
|
||||||
|
"grid": 20
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": 35,
|
||||||
|
"order": 10,
|
||||||
|
"prevSize": 32,
|
||||||
|
"code": 58890,
|
||||||
|
"name": "popup",
|
||||||
|
"ligatures": "url"
|
||||||
|
},
|
||||||
|
"setIdx": 5,
|
||||||
|
"iconIdx": 35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": {
|
||||||
|
"paths": [
|
||||||
|
"M512 81.92c-237.568 0-430.080 192.614-430.080 430.080 0 237.568 192.563 430.080 430.080 430.080 237.517 0 430.080-192.563 430.080-430.080 0-237.517-192.563-430.080-430.080-430.080zM564.326 564.326v206.182h-104.653v-206.182h-206.234v-104.653h206.182v-206.234h104.704v206.182h206.182v104.704h-206.182z"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"plus",
|
||||||
|
"add",
|
||||||
|
"sum"
|
||||||
|
],
|
||||||
|
"grid": 20
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": 125,
|
||||||
|
"order": 16,
|
||||||
|
"prevSize": 32,
|
||||||
|
"code": 58895,
|
||||||
|
"name": "plus",
|
||||||
|
"ligatures": "add card"
|
||||||
|
},
|
||||||
|
"setIdx": 5,
|
||||||
|
"iconIdx": 125
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": {
|
||||||
|
"paths": [
|
||||||
|
"M585.574 231.219c-21.402 20.89-230.502 240.435-230.502 240.435-11.418 11.162-17.101 25.754-17.101 40.346s5.683 29.184 17.101 40.346c0 0 209.101 219.546 230.502 240.384 21.402 20.89 59.904 22.323 82.739 0 22.784-22.272 24.576-53.35-0.051-80.64l-191.846-200.090 191.846-200.090c24.627-27.341 22.835-58.419 0.051-80.691-22.886-22.272-61.389-20.89-82.739-0z"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"arrow-left",
|
||||||
|
"left",
|
||||||
|
"previous"
|
||||||
|
],
|
||||||
|
"grid": 20
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": 205,
|
||||||
|
"order": 12,
|
||||||
|
"prevSize": 32,
|
||||||
|
"code": 58892,
|
||||||
|
"name": "arrow-left",
|
||||||
|
"ligatures": "back"
|
||||||
|
},
|
||||||
|
"setIdx": 5,
|
||||||
|
"iconIdx": 205
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": {
|
||||||
|
"paths": [
|
||||||
|
"M438.426 231.219c21.402 20.89 230.502 240.435 230.502 240.435 11.469 11.162 17.152 25.754 17.152 40.346s-5.683 29.184-17.152 40.346c0 0-209.101 219.546-230.502 240.384-21.402 20.89-59.853 22.323-82.739 0-22.835-22.272-24.627-53.35 0-80.64l191.898-200.090-191.846-200.090c-24.627-27.341-22.835-58.419 0-80.691 22.835-22.272 61.338-20.89 82.688-0z"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"arrow-right",
|
||||||
|
"right",
|
||||||
|
"next"
|
||||||
|
],
|
||||||
|
"grid": 20
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": 208,
|
||||||
|
"order": 13,
|
||||||
|
"prevSize": 32,
|
||||||
|
"code": 58893,
|
||||||
|
"name": "arrow-right",
|
||||||
|
"ligatures": "show detail"
|
||||||
|
},
|
||||||
|
"setIdx": 5,
|
||||||
|
"iconIdx": 208
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"height": 1024,
|
||||||
|
"metadata": {
|
||||||
|
"name": "clipperz-icons"
|
||||||
|
},
|
||||||
|
"preferences": {
|
||||||
|
"fontPref": {
|
||||||
|
"prefix": "icon-",
|
||||||
|
"metadata": {
|
||||||
|
"fontFamily": "clipperz-icons",
|
||||||
|
"majorVersion": 1,
|
||||||
|
"minorVersion": 0
|
||||||
|
},
|
||||||
|
"showGlyphs": true,
|
||||||
|
"metrics": {
|
||||||
|
"emSize": 512,
|
||||||
|
"baseline": 6.25,
|
||||||
|
"whitespace": 50
|
||||||
|
},
|
||||||
|
"resetPoint": 58880,
|
||||||
|
"showQuickUse": true,
|
||||||
|
"quickUsageToken": false,
|
||||||
|
"showMetrics": true,
|
||||||
|
"showMetadata": false,
|
||||||
|
"autoHost": false,
|
||||||
|
"embed": true,
|
||||||
|
"showVersion": true
|
||||||
|
},
|
||||||
|
"imagePref": {
|
||||||
|
"color": 0,
|
||||||
|
"height": 32,
|
||||||
|
"columns": 16,
|
||||||
|
"margin": 16,
|
||||||
|
"png": false,
|
||||||
|
"sprites": true
|
||||||
|
},
|
||||||
|
"historySize": 100,
|
||||||
|
"showCodes": false,
|
||||||
|
"gridSize": 16,
|
||||||
|
"showLiga": true,
|
||||||
|
"showGrid": true,
|
||||||
|
"showGlyphs": true,
|
||||||
|
"showQuickUse": true,
|
||||||
|
"search": "",
|
||||||
|
"quickUsageToken": {
|
||||||
|
"UntitledProject1": "YzBlN2I0ZDQ5YTQyY2NjYjgwNGRkYzNhYzU4NDZhMDcjMiMxNDAzMTA2OTk5IyMj"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -21,11 +21,8 @@ refer to http://www.clipperz.com.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//Clipperz.Async = MochiKit.Async;
|
"use strict";
|
||||||
|
Clipperz.Base.module('Clipperz.Async');
|
||||||
|
|
||||||
if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
|
|
||||||
if (typeof(Clipperz.Async) == 'undefined') { Clipperz.Async = {}; }
|
|
||||||
|
|
||||||
Clipperz.Async.VERSION = "0.1";
|
Clipperz.Async.VERSION = "0.1";
|
||||||
Clipperz.Async.NAME = "Clipperz.Async";
|
Clipperz.Async.NAME = "Clipperz.Async";
|
||||||
@ -276,6 +273,12 @@ Clipperz.Base.extend(Clipperz.Async.Deferred, MochiKit.Async.Deferred, {
|
|||||||
}, this));
|
}, this));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'values': function () {
|
||||||
|
this.addCallback(MochiKit.Base.bind(function () {
|
||||||
|
return this.vars();
|
||||||
|
}, this));
|
||||||
|
},
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
'wait': function (someSeconds) {
|
'wait': function (someSeconds) {
|
||||||
@ -702,6 +705,6 @@ MochiKit.Base.update(Clipperz.Async, {
|
|||||||
|
|
||||||
//#############################################################################
|
//#############################################################################
|
||||||
|
|
||||||
CLIPPERZ_DEFERRED_LOGGING_ENABLED = true;
|
var CLIPPERZ_DEFERRED_LOGGING_ENABLED = true;
|
||||||
CLIPPERZ_DEFERRED_TRACING_ENABLED = false;
|
var CLIPPERZ_DEFERRED_TRACING_ENABLED = false;
|
||||||
CLIPPERZ_DEFERRED_CALL_LOGGING_ENABLED = false;
|
var CLIPPERZ_DEFERRED_CALL_LOGGING_ENABLED = false;
|
||||||
|
@ -21,6 +21,8 @@ refer to http://www.clipperz.com.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
|
if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
|
||||||
if (typeof(Clipperz.Base) == 'undefined') { Clipperz.Base = {}; }
|
if (typeof(Clipperz.Base) == 'undefined') { Clipperz.Base = {}; }
|
||||||
|
|
||||||
@ -189,6 +191,10 @@ MochiKit.Base.update(Clipperz.Base, {
|
|||||||
return Clipperz.Base.removeObjectFromArray(anObject, anArray);
|
return Clipperz.Base.removeObjectFromArray(anObject, anArray);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'arrayWithUniqueValues': function (anArray) {
|
||||||
|
return anArray.filter(function (value, index, self) { return self.indexOf(value) === index; });
|
||||||
|
},
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
'splitStringAtFixedTokenSize': function(aString, aTokenSize) {
|
'splitStringAtFixedTokenSize': function(aString, aTokenSize) {
|
||||||
|
@ -21,6 +21,7 @@ refer to http://www.clipperz.com.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
|
if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
@ -21,7 +21,8 @@ refer to http://www.clipperz.com.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
|
"use strict";
|
||||||
|
Clipperz.Base.module('Clipperz');
|
||||||
|
|
||||||
|
|
||||||
Clipperz.CSVProcessor = function(args) {
|
Clipperz.CSVProcessor = function(args) {
|
||||||
@ -32,9 +33,9 @@ Clipperz.CSVProcessor = function(args) {
|
|||||||
// this._string = undefined;
|
// this._string = undefined;
|
||||||
// this._fields = undefined;
|
// this._fields = undefined;
|
||||||
|
|
||||||
this._quoteChar = args['quoteChar'] || "\042";
|
this._quoteChar = args['quoteChar'] || "\0x42";
|
||||||
this._eol = args['eol'] || "";
|
this._eol = args['eol'] || "";
|
||||||
this._escapeChar = args['escapeChar'] || "\042";
|
this._escapeChar = args['escapeChar'] || "\0x42";
|
||||||
this._separatorChar = args['separatorChar'] || ",";
|
this._separatorChar = args['separatorChar'] || ",";
|
||||||
this._binary = args['binary'] || false;
|
this._binary = args['binary'] || false;
|
||||||
this._alwaysQuote = args['alwaysQuote'] || false;
|
this._alwaysQuote = args['alwaysQuote'] || false;
|
||||||
|
@ -293,7 +293,7 @@ Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new
|
|||||||
Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource = function(args) {
|
Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource = function(args) {
|
||||||
args = args || {};
|
args = args || {};
|
||||||
|
|
||||||
this._intervalTime = args.intervalTime || 1000;
|
this._intervalTime = args.intervalTime || 500;
|
||||||
this._browserCrypto = args.browserCrypto;
|
this._browserCrypto = args.browserCrypto;
|
||||||
|
|
||||||
Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
|
Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
|
||||||
@ -318,7 +318,7 @@ Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource.prototype = MochiKit.Base.upda
|
|||||||
var bytesToCollect;
|
var bytesToCollect;
|
||||||
|
|
||||||
if (this.boostMode() == true) {
|
if (this.boostMode() == true) {
|
||||||
bytesToCollect = 64;
|
bytesToCollect = 256;
|
||||||
} else {
|
} else {
|
||||||
bytesToCollect = 8;
|
bytesToCollect = 8;
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ MochiKit.Base.update(Clipperz.Crypto.SRP, {
|
|||||||
return Clipperz.Crypto.SRP._n;
|
return Clipperz.Crypto.SRP._n;
|
||||||
},
|
},
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//.........................................................................
|
||||||
|
|
||||||
'g': function() {
|
'g': function() {
|
||||||
if (Clipperz.Crypto.SRP._g == null) {
|
if (Clipperz.Crypto.SRP._g == null) {
|
||||||
@ -66,6 +66,8 @@ MochiKit.Base.update(Clipperz.Crypto.SRP, {
|
|||||||
return Clipperz.Crypto.SRP._g;
|
return Clipperz.Crypto.SRP._g;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
//.........................................................................
|
||||||
|
|
||||||
'k': function() {
|
'k': function() {
|
||||||
if (Clipperz.Crypto.SRP._k == null) {
|
if (Clipperz.Crypto.SRP._k == null) {
|
||||||
// Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt(this.stringHash(this.n().asString() + this.g().asString()), 16);
|
// Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt(this.stringHash(this.n().asString() + this.g().asString()), 16);
|
||||||
|
@ -21,8 +21,8 @@ refer to http://www.clipperz.com.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
|
"use strict";
|
||||||
if (typeof(Clipperz.DOM) == 'undefined') { Clipperz.DOM = {}; }
|
Clipperz.Base.module('Clipperz.DOM');
|
||||||
|
|
||||||
Clipperz.DOM.VERSION = "0.1";
|
Clipperz.DOM.VERSION = "0.1";
|
||||||
Clipperz.DOM.NAME = "Clipperz.DOM";
|
Clipperz.DOM.NAME = "Clipperz.DOM";
|
||||||
|
@ -21,8 +21,8 @@ refer to http://www.clipperz.com.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
|
"use strict";
|
||||||
if (typeof(Clipperz.Date) == 'undefined') { Clipperz.Date = {}; }
|
Clipperz.Base.module('Clipperz.Date');
|
||||||
|
|
||||||
Clipperz.Date.VERSION = "0.1";
|
Clipperz.Date.VERSION = "0.1";
|
||||||
Clipperz.Date.NAME = "Clipperz.Date";
|
Clipperz.Date.NAME = "Clipperz.Date";
|
||||||
|
@ -30,6 +30,7 @@ Clipperz.PM.DataModel.Record = function(args) {
|
|||||||
Clipperz.PM.DataModel.Record.superclass.constructor.apply(this, arguments);
|
Clipperz.PM.DataModel.Record.superclass.constructor.apply(this, arguments);
|
||||||
|
|
||||||
this._updateDate = (args.updateDate ? Clipperz.PM.Date.parse(args.updateDate) : Clipperz.Base.exception.raise('MandatoryParameter'));
|
this._updateDate = (args.updateDate ? Clipperz.PM.Date.parse(args.updateDate) : Clipperz.Base.exception.raise('MandatoryParameter'));
|
||||||
|
this._accessDate = (args.accessDate ? Clipperz.PM.Date.parse(args.accessDate) : Clipperz.Base.exception.raise('MandatoryParameter'));
|
||||||
|
|
||||||
this._retrieveIndexDataFunction = args.retrieveIndexDataFunction || Clipperz.Base.exception.raise('MandatoryParameter');
|
this._retrieveIndexDataFunction = args.retrieveIndexDataFunction || Clipperz.Base.exception.raise('MandatoryParameter');
|
||||||
this._updateIndexDataFunction = args.updateIndexDataFunction || Clipperz.Base.exception.raise('MandatoryParameter');
|
this._updateIndexDataFunction = args.updateIndexDataFunction || Clipperz.Base.exception.raise('MandatoryParameter');
|
||||||
@ -40,6 +41,8 @@ Clipperz.PM.DataModel.Record = function(args) {
|
|||||||
|
|
||||||
this._createNewDirectLoginFunction = args.createNewDirectLoginFunction || null;
|
this._createNewDirectLoginFunction = args.createNewDirectLoginFunction || null;
|
||||||
|
|
||||||
|
this._tags = [];
|
||||||
|
|
||||||
this._directLogins = {};
|
this._directLogins = {};
|
||||||
|
|
||||||
this._versions = {};
|
this._versions = {};
|
||||||
@ -128,22 +131,109 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.Record, Clipperz.PM.DataModel.Encrypt
|
|||||||
return deferredResult;
|
return deferredResult;
|
||||||
},
|
},
|
||||||
|
|
||||||
//=========================================================================
|
//============================================================================
|
||||||
/*
|
/*
|
||||||
'key': function () {
|
'key': function () {
|
||||||
return this.getIndexDataForKey('key');
|
return this.getIndexDataForKey('key');
|
||||||
},
|
},
|
||||||
*/
|
*/
|
||||||
//=========================================================================
|
//============================================================================
|
||||||
|
|
||||||
|
'fullLabel': function () {
|
||||||
|
return this.getIndexDataForKey('label');
|
||||||
|
},
|
||||||
|
|
||||||
|
'updateFullLabelWithTags': function (someTags) {
|
||||||
|
return Clipperz.Async.callbacks("Record.updateFullLabelWithTags", [
|
||||||
|
MochiKit.Base.method(this, 'label'),
|
||||||
|
function (aLabel) {
|
||||||
|
return aLabel + ' ' + MochiKit.Base.map(function (aTag) { return Clipperz.PM.DataModel.Record.tagChar + aTag; }, MochiKit.Base.keys(someTags)).join(' ');
|
||||||
|
},
|
||||||
|
MochiKit.Base.method(this, 'setIndexDataForKey', 'label')
|
||||||
|
], {trace:false});
|
||||||
|
},
|
||||||
|
|
||||||
|
//............................................................................
|
||||||
|
|
||||||
|
'tagChar': function () {
|
||||||
|
return Clipperz.PM.DataModel.Record.tagChar;
|
||||||
|
},
|
||||||
|
|
||||||
|
'tagRegExp': function () {
|
||||||
|
return new RegExp('\\' + this.tagChar() + '(\\w+)', 'g');
|
||||||
|
},
|
||||||
|
|
||||||
|
'trimSpacesRegExp': function () {
|
||||||
|
return new RegExp('^\\s+|\\s+$', 'g');
|
||||||
|
},
|
||||||
|
|
||||||
|
//............................................................................
|
||||||
|
|
||||||
|
'filterOutTags': function (aValue) {
|
||||||
|
var value;
|
||||||
|
|
||||||
|
value = aValue;
|
||||||
|
value = value.replace(this.tagRegExp(), '');
|
||||||
|
value = value.replace(this.trimSpacesRegExp(), '');
|
||||||
|
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
|
||||||
'label': function () {
|
'label': function () {
|
||||||
return this.getIndexDataForKey('label');
|
return Clipperz.Async.callbacks("Record.label", [
|
||||||
|
MochiKit.Base.method(this, 'fullLabel'),
|
||||||
|
MochiKit.Base.method(this, 'filterOutTags')
|
||||||
|
], {trace:false});
|
||||||
|
},
|
||||||
|
|
||||||
|
'setLabel': function (aValue) {
|
||||||
|
return this.setIndexDataForKey('label', aValue); // [???]
|
||||||
},
|
},
|
||||||
|
|
||||||
//.........................................................................
|
//.........................................................................
|
||||||
|
|
||||||
'setLabel': function (aValue) {
|
'extractTags': function (aLabel) {
|
||||||
return this.setIndexDataForKey('label', aValue);
|
var tagRegEx;
|
||||||
|
var result;
|
||||||
|
var match;
|
||||||
|
|
||||||
|
result = {};
|
||||||
|
tagRegEx = this.tagRegExp();
|
||||||
|
match = tagRegEx.exec(aLabel);
|
||||||
|
while (match != null) {
|
||||||
|
result[match[1]] = true;
|
||||||
|
match = tagRegEx.exec(aLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
'tags': function () {
|
||||||
|
return Clipperz.Async.callbacks("Record.label", [
|
||||||
|
MochiKit.Base.method(this, 'fullLabel'),
|
||||||
|
MochiKit.Base.method(this, 'extractTags'),
|
||||||
|
MochiKit.Base.keys
|
||||||
|
], {trace:false});
|
||||||
|
},
|
||||||
|
|
||||||
|
'addTag': function (aNewTag) {
|
||||||
|
//console.log("ADD TAG", aNewTag);
|
||||||
|
return Clipperz.Async.callbacks("Record.addTag", [
|
||||||
|
MochiKit.Base.method(this, 'fullLabel'),
|
||||||
|
MochiKit.Base.method(this, 'extractTags'),
|
||||||
|
function (someTags) { someTags[aNewTag] = true; console.log("UPDATED TAGS", someTags); return someTags; },
|
||||||
|
MochiKit.Base.method(this, 'updateFullLabelWithTags')
|
||||||
|
], {trace:false});
|
||||||
|
},
|
||||||
|
|
||||||
|
'removeTag': function (aTag) {
|
||||||
|
//console.log("ADD TAG", aNewTag);
|
||||||
|
return Clipperz.Async.callbacks("Record.removeTag", [
|
||||||
|
MochiKit.Base.method(this, 'fullLabel'),
|
||||||
|
MochiKit.Base.method(this, 'extractTags'),
|
||||||
|
function (someTags) { delete someTags[aTag]; return someTags; },
|
||||||
|
MochiKit.Base.method(this, 'updateFullLabelWithTags')
|
||||||
|
], {trace:false});
|
||||||
},
|
},
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
@ -183,6 +273,10 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.Record, Clipperz.PM.DataModel.Encrypt
|
|||||||
return MochiKit.Async.succeed(this._updateDate);
|
return MochiKit.Async.succeed(this._updateDate);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'accessDate': function () {
|
||||||
|
return MochiKit.Async.succeed(this._accessDate);
|
||||||
|
},
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
||||||
'favicon': function () {
|
'favicon': function () {
|
||||||
@ -208,7 +302,7 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.Record, Clipperz.PM.DataModel.Encrypt
|
|||||||
deferredResult = new Clipperz.Async.Deferred("Record.searchableContent", {trace:false});
|
deferredResult = new Clipperz.Async.Deferred("Record.searchableContent", {trace:false});
|
||||||
|
|
||||||
deferredResult.collectResults({
|
deferredResult.collectResults({
|
||||||
'recordLabel': MochiKit.Base.method(this, 'label'),
|
'recordLabel': MochiKit.Base.method(this, 'fullLabel'),
|
||||||
'directLoginLabels': [
|
'directLoginLabels': [
|
||||||
MochiKit.Base.method(this, 'directLoginReferences'),
|
MochiKit.Base.method(this, 'directLoginReferences'),
|
||||||
MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.itemgetter('label'))
|
MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.itemgetter('label'))
|
||||||
@ -889,3 +983,20 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.Record, Clipperz.PM.DataModel.Encrypt
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Clipperz.PM.DataModel.Record.defaultCardInfo = {
|
||||||
|
'_rowObject': MochiKit.Async.succeed,
|
||||||
|
'_reference': MochiKit.Base.methodcaller('reference'),
|
||||||
|
'_searchableContent': MochiKit.Base.methodcaller('searchableContent'),
|
||||||
|
'_accessDate': MochiKit.Base.methodcaller('accessDate'),
|
||||||
|
'label': MochiKit.Base.methodcaller('label'),
|
||||||
|
'favicon': MochiKit.Base.methodcaller('favicon')
|
||||||
|
};
|
||||||
|
Clipperz.PM.DataModel.Record.defaultSearchField = '_searchableContent';
|
||||||
|
|
||||||
|
Clipperz.PM.DataModel.Record.tagChar = '#';
|
||||||
|
Clipperz.PM.DataModel.Record.regExpForTag = function (aTag) {
|
||||||
|
return new RegExp('\\' + Clipperz.PM.DataModel.Record.tagChar + aTag, 'g');
|
||||||
|
};
|
||||||
|
Clipperz.PM.DataModel.Record.regExpForSearch = function (aSearch) {
|
||||||
|
return new RegExp(aSearch.replace(/[^A-Za-z0-9]/g, '\\$&'), 'i');
|
||||||
|
};
|
||||||
|
@ -25,26 +25,26 @@ try { if (typeof(Clipperz.PM.DataModel.User) == 'undefined') { throw ""; }} catc
|
|||||||
throw "Clipperz.PM.DataModel.User.Subscription depends on Clipperz.PM.DataModel.User!";
|
throw "Clipperz.PM.DataModel.User.Subscription depends on Clipperz.PM.DataModel.User!";
|
||||||
}
|
}
|
||||||
|
|
||||||
Clipperz.PM.DataModel.User.Subscription = function(args) {
|
Clipperz.PM.DataModel.User.AccountInfo = function(args) {
|
||||||
this._attributes = args;
|
this._attributes = args;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Clipperz.Base.extend(Clipperz.PM.DataModel.User.Subscription, Object, {
|
Clipperz.Base.extend(Clipperz.PM.DataModel.User.AccountInfo, Object, {
|
||||||
|
|
||||||
'features': function () {
|
'features': function () {
|
||||||
return this._attributes['features'];
|
return this._attributes['features'];
|
||||||
},
|
},
|
||||||
|
|
||||||
'type': function () {
|
'featureSet': function () {
|
||||||
return this._attributes['type'];
|
return this._attributes['featureSet'];
|
||||||
},
|
},
|
||||||
|
|
||||||
'validity': function () {
|
'validity': function () {
|
||||||
return {
|
return {
|
||||||
'from': this._attributes['fromDate'],
|
// 'from': this._attributes['fromDate'],
|
||||||
'to': this._attributes['toDate']
|
'to': this._attributes['expirationDate']
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
@ -133,6 +133,7 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.Legacy, Clipperz.PM.DataM
|
|||||||
'retrieveIndexDataFunction': MochiKit.Base.method(this, 'getRecordIndexData'),
|
'retrieveIndexDataFunction': MochiKit.Base.method(this, 'getRecordIndexData'),
|
||||||
'updateIndexDataFunction': MochiKit.Base.method(this, 'updateRecordIndexData'),
|
'updateIndexDataFunction': MochiKit.Base.method(this, 'updateRecordIndexData'),
|
||||||
'updateDate': someObjectData['recordsStats'][reference]['updateDate'],
|
'updateDate': someObjectData['recordsStats'][reference]['updateDate'],
|
||||||
|
'accessDate': someObjectData['recordsStats'][reference]['accessDate'],
|
||||||
|
|
||||||
'retrieveDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'getDirectLoginIndexData'),
|
'retrieveDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'getDirectLoginIndexData'),
|
||||||
'setDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'setDirectLoginIndexData'),
|
'setDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'setDirectLoginIndexData'),
|
||||||
|
@ -29,7 +29,7 @@ if (typeof(Clipperz.PM.DataModel.User.Header) == 'undefined') { Clipperz.PM.Data
|
|||||||
|
|
||||||
Clipperz.PM.DataModel.User.Header.RecordIndex = function(args) {
|
Clipperz.PM.DataModel.User.Header.RecordIndex = function(args) {
|
||||||
Clipperz.PM.DataModel.User.Header.RecordIndex.superclass.constructor.apply(this, arguments);
|
Clipperz.PM.DataModel.User.Header.RecordIndex.superclass.constructor.apply(this, arguments);
|
||||||
|
//console.log("RECORD INDEX ARGS", args);
|
||||||
this._recordsData = new Clipperz.PM.DataModel.EncryptedRemoteObject({
|
this._recordsData = new Clipperz.PM.DataModel.EncryptedRemoteObject({
|
||||||
'name': 'recordsData',
|
'name': 'recordsData',
|
||||||
'retrieveKeyFunction': args.retrieveKeyFunction,
|
'retrieveKeyFunction': args.retrieveKeyFunction,
|
||||||
@ -37,9 +37,7 @@ Clipperz.PM.DataModel.User.Header.RecordIndex = function(args) {
|
|||||||
'data': args.recordsData['data'],
|
'data': args.recordsData['data'],
|
||||||
'version': args.encryptedDataVersion,
|
'version': args.encryptedDataVersion,
|
||||||
'recordsStats': args.recordsStats
|
'recordsStats': args.recordsStats
|
||||||
}//,
|
}
|
||||||
// 'encryptedDataKeypath': 'data',
|
|
||||||
// 'encryptedVersionKeypath': 'version'
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this._directLoginsData = new Clipperz.PM.DataModel.EncryptedRemoteObject({
|
this._directLoginsData = new Clipperz.PM.DataModel.EncryptedRemoteObject({
|
||||||
@ -48,11 +46,10 @@ Clipperz.PM.DataModel.User.Header.RecordIndex = function(args) {
|
|||||||
'remoteData': {
|
'remoteData': {
|
||||||
'data': args.directLoginsData['data'],
|
'data': args.directLoginsData['data'],
|
||||||
'version': args.encryptedDataVersion
|
'version': args.encryptedDataVersion
|
||||||
}//,
|
}
|
||||||
// 'encryptedDataKeypath': 'data',
|
|
||||||
// 'encryptedVersionKeypath': 'version'
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this._tagsData =
|
||||||
this._lock = new MochiKit.Async.DeferredLock();
|
this._lock = new MochiKit.Async.DeferredLock();
|
||||||
this._transientState = null;
|
this._transientState = null;
|
||||||
|
|
||||||
@ -154,9 +151,6 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.RecordIndex, Object, {
|
|||||||
},
|
},
|
||||||
|
|
||||||
'setDirectLoginIndexData': function (aDirectLoginReference, aKey, aValue) {
|
'setDirectLoginIndexData': function (aDirectLoginReference, aKey, aValue) {
|
||||||
//if (MochiKit.Base.isUndefinedOrNull(this.directLoginsIndex()[aDirectLoginReference])) {
|
|
||||||
// throw "PIPPO";
|
|
||||||
//}
|
|
||||||
return this.directLoginsData().setValue(this.directLoginsIndex()[aDirectLoginReference] + '.' + aKey, aValue);
|
return this.directLoginsData().setValue(this.directLoginsIndex()[aDirectLoginReference] + '.' + aKey, aValue);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -182,8 +176,6 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.RecordIndex, Object, {
|
|||||||
innerDeferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.records <inner deferred>", {trace:false});
|
innerDeferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.records <inner deferred>", {trace:false});
|
||||||
innerDeferredResult.collectResults({
|
innerDeferredResult.collectResults({
|
||||||
'records': [
|
'records': [
|
||||||
// MochiKit.Base.method(this.recordsData(), 'getObjectDataStore'),
|
|
||||||
// MochiKit.Base.methodcaller('values')
|
|
||||||
MochiKit.Base.method(this.recordsData(), 'values')
|
MochiKit.Base.method(this.recordsData(), 'values')
|
||||||
],
|
],
|
||||||
'recordsStats': [
|
'recordsStats': [
|
||||||
@ -191,8 +183,6 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.RecordIndex, Object, {
|
|||||||
MochiKit.Base.itemgetter('recordsStats')
|
MochiKit.Base.itemgetter('recordsStats')
|
||||||
],
|
],
|
||||||
'directLogins': [
|
'directLogins': [
|
||||||
// MochiKit.Base.method(this.directLoginsData(), 'getObjectDataStore'),
|
|
||||||
// MochiKit.Base.methodcaller('values')
|
|
||||||
MochiKit.Base.method(this.directLoginsData(), 'values')
|
MochiKit.Base.method(this.directLoginsData(), 'values')
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
@ -210,11 +200,13 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.RecordIndex, Object, {
|
|||||||
var record;
|
var record;
|
||||||
var reference;
|
var reference;
|
||||||
var updateDate;
|
var updateDate;
|
||||||
|
var accessDate;
|
||||||
|
|
||||||
reference = recordsInvertedIndex[indexReference];
|
reference = recordsInvertedIndex[indexReference];
|
||||||
|
|
||||||
if (typeof(someData['recordsStats'][reference]) != 'undefined') {
|
if (typeof(someData['recordsStats'][reference]) != 'undefined') {
|
||||||
updateDate = someData['recordsStats'][reference]['updateDate'];
|
updateDate = someData['recordsStats'][reference]['updateDate'];
|
||||||
|
accessDate = someData['recordsStats'][reference]['accessDate'];
|
||||||
|
|
||||||
record = new Clipperz.PM.DataModel.Record({
|
record = new Clipperz.PM.DataModel.Record({
|
||||||
'reference': reference,
|
'reference': reference,
|
||||||
@ -224,6 +216,7 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.RecordIndex, Object, {
|
|||||||
'retrieveIndexDataFunction': MochiKit.Base.method(this, 'getRecordIndexData'),
|
'retrieveIndexDataFunction': MochiKit.Base.method(this, 'getRecordIndexData'),
|
||||||
'updateIndexDataFunction': MochiKit.Base.method(this, 'updateRecordIndexData'),
|
'updateIndexDataFunction': MochiKit.Base.method(this, 'updateRecordIndexData'),
|
||||||
'updateDate': updateDate,
|
'updateDate': updateDate,
|
||||||
|
'accessDate': accessDate,
|
||||||
|
|
||||||
'retrieveDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'getDirectLoginIndexData'),
|
'retrieveDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'getDirectLoginIndexData'),
|
||||||
'setDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'setDirectLoginIndexData'),
|
'setDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'setDirectLoginIndexData'),
|
||||||
@ -235,13 +228,10 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.RecordIndex, Object, {
|
|||||||
this._records[reference] = record;
|
this._records[reference] = record;
|
||||||
} else {
|
} else {
|
||||||
Clipperz.log("SKIPPING record " + reference + " as there are no stas associated - " + Clipperz.Base.serializeJSON(someData['records'][reference]));
|
Clipperz.log("SKIPPING record " + reference + " as there are no stas associated - " + Clipperz.Base.serializeJSON(someData['records'][reference]));
|
||||||
// # skip the record, as it seems it is not present in the DB
|
|
||||||
// updateDate = Clipperz.PM.Date.formatDateWithUTCFormat(new Date());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (indexReference in someData['directLogins']) {
|
for (indexReference in someData['directLogins']) {
|
||||||
// var directLogin;
|
|
||||||
var reference;
|
var reference;
|
||||||
var record;
|
var record;
|
||||||
|
|
||||||
@ -249,7 +239,6 @@ Clipperz.log("SKIPPING record " + reference + " as there are no stas associated
|
|||||||
record = this._records[recordsInvertedIndex[someData['directLogins'][indexReference]['record']]];
|
record = this._records[recordsInvertedIndex[someData['directLogins'][indexReference]['record']]];
|
||||||
|
|
||||||
if (record != null) {
|
if (record != null) {
|
||||||
// directLogin = new Clipperz.PM.DataModel.DirectLogin({
|
|
||||||
new Clipperz.PM.DataModel.DirectLogin({
|
new Clipperz.PM.DataModel.DirectLogin({
|
||||||
'reference': reference,
|
'reference': reference,
|
||||||
'record': record
|
'record': record
|
||||||
@ -301,6 +290,7 @@ Clipperz.log("SKIPPING record " + reference + " as there are no stas associated
|
|||||||
'retrieveIndexDataFunction': MochiKit.Base.method(this, 'getRecordIndexData'),
|
'retrieveIndexDataFunction': MochiKit.Base.method(this, 'getRecordIndexData'),
|
||||||
'updateIndexDataFunction': MochiKit.Base.method(this, 'updateRecordIndexData'),
|
'updateIndexDataFunction': MochiKit.Base.method(this, 'updateRecordIndexData'),
|
||||||
'updateDate': Clipperz.PM.Date.formatDateWithUTCFormat(new Date()),
|
'updateDate': Clipperz.PM.Date.formatDateWithUTCFormat(new Date()),
|
||||||
|
'accessDate': Clipperz.PM.Date.formatDateWithUTCFormat(new Date()),
|
||||||
|
|
||||||
'retrieveDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'getDirectLoginIndexData'),
|
'retrieveDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'getDirectLoginIndexData'),
|
||||||
'setDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'setDirectLoginIndexData'),
|
'setDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'setDirectLoginIndexData'),
|
||||||
@ -384,10 +374,6 @@ Clipperz.log("SKIPPING record " + reference + " as there are no stas associated
|
|||||||
|
|
||||||
'deleteAllCleanTextData': function () {
|
'deleteAllCleanTextData': function () {
|
||||||
return Clipperz.Async.callbacks("User.Header.RecordIndex.deleteAllCleanTextData", [
|
return Clipperz.Async.callbacks("User.Header.RecordIndex.deleteAllCleanTextData", [
|
||||||
// MochiKit.Base.method(this, 'records'),
|
|
||||||
// MochiKit.Base.values,
|
|
||||||
// MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('deleteAllCleanTextData')),
|
|
||||||
|
|
||||||
MochiKit.Base.method(this, 'recordsData'),
|
MochiKit.Base.method(this, 'recordsData'),
|
||||||
MochiKit.Base.methodcaller('deleteAllCleanTextData'),
|
MochiKit.Base.methodcaller('deleteAllCleanTextData'),
|
||||||
MochiKit.Base.method(this, 'directLoginsData'),
|
MochiKit.Base.method(this, 'directLoginsData'),
|
||||||
@ -410,21 +396,9 @@ Clipperz.log("SKIPPING record " + reference + " as there are no stas associated
|
|||||||
MochiKit.Base.method(this, 'directLoginsData'),
|
MochiKit.Base.method(this, 'directLoginsData'),
|
||||||
MochiKit.Base.methodcaller('hasAnyCleanTextData')
|
MochiKit.Base.methodcaller('hasAnyCleanTextData')
|
||||||
],
|
],
|
||||||
// 'records': [
|
|
||||||
// MochiKit.Base.method(this, 'records'),
|
|
||||||
// MochiKit.Base.values,
|
|
||||||
// MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('hasAnyCleanTextData')),
|
|
||||||
// Clipperz.Async.collectAll
|
|
||||||
// ]
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// deferredResult.addCallback(MochiKit.Base.values);
|
|
||||||
// deferredResult.addCallback(MochiKit.Base.flattenArguments);
|
|
||||||
// deferredResult.addCallback(function(someValues) {
|
|
||||||
// return MochiKit.Iter.some(someValues, MochiKit.Base.operator.identity);
|
|
||||||
// });
|
|
||||||
deferredResult.addCallback(Clipperz.Async.or);
|
deferredResult.addCallback(Clipperz.Async.or);
|
||||||
|
|
||||||
deferredResult.callback();
|
deferredResult.callback();
|
||||||
|
|
||||||
return deferredResult;
|
return deferredResult;
|
||||||
@ -447,11 +421,6 @@ Clipperz.log("SKIPPING record " + reference + " as there are no stas associated
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
deferredResult.addCallback(Clipperz.Async.or);
|
deferredResult.addCallback(Clipperz.Async.or);
|
||||||
// deferredResult.addCallback(MochiKit.Base.values);
|
|
||||||
// deferredResult.addCallback(MochiKit.Base.flattenArguments);
|
|
||||||
// deferredResult.addCallback(function(someValues) {
|
|
||||||
// return MochiKit.Iter.some(someValues, MochiKit.Base.operator.identity);
|
|
||||||
// });
|
|
||||||
deferredResult.callback();
|
deferredResult.callback();
|
||||||
|
|
||||||
return deferredResult;
|
return deferredResult;
|
||||||
@ -482,9 +451,6 @@ Clipperz.log("SKIPPING record " + reference + " as there are no stas associated
|
|||||||
MochiKit.Base.method(this, 'recordsData'),
|
MochiKit.Base.method(this, 'recordsData'),
|
||||||
MochiKit.Base.methodcaller('revertChanges'),
|
MochiKit.Base.methodcaller('revertChanges'),
|
||||||
|
|
||||||
// MochiKit.Base.method(this, 'directLoginsData'),
|
|
||||||
// MochiKit.Base.methodcaller('revertChanges'),
|
|
||||||
|
|
||||||
MochiKit.Base.method(this, 'records'),
|
MochiKit.Base.method(this, 'records'),
|
||||||
MochiKit.Base.bind(function (someRecords) {
|
MochiKit.Base.bind(function (someRecords) {
|
||||||
var recordReference;
|
var recordReference;
|
||||||
@ -500,22 +466,10 @@ Clipperz.log("SKIPPING record " + reference + " as there are no stas associated
|
|||||||
}
|
}
|
||||||
}, this),
|
}, this),
|
||||||
|
|
||||||
// MochiKit.Base.method(this, 'directLogins'),
|
|
||||||
MochiKit.Base.bind(function () {
|
MochiKit.Base.bind(function () {
|
||||||
var directLoginReference;
|
var directLoginReference;
|
||||||
|
|
||||||
// this.transientState().setValue('newDirectLoginReferences' + '.' + newDirectLogin.reference(), newDirectLogin);
|
|
||||||
//
|
|
||||||
// this.directLoginsIndex()[newDirectLogin.reference()] = newDirectLoginIndexValue;
|
|
||||||
// this.directLoginsData().setValue(this.directLoginsIndex()[newDirectLogin.reference()], {'record': this.recordsIndex()[aRecord.reference()]});
|
|
||||||
|
|
||||||
|
|
||||||
// for (directLoginReference in this.transientState().getValue('deleteDirectLoginReferences')) {
|
|
||||||
// someDirectLogins[directLoginReference] = this.transientState().getValue('deleteDirectLoginReferences' + '.' + recordReference);
|
|
||||||
// }
|
|
||||||
|
|
||||||
for (directLoginReference in this.transientState().getValue('newDirectLoginReferences')) {
|
for (directLoginReference in this.transientState().getValue('newDirectLoginReferences')) {
|
||||||
// this.directLoginsData().removeValue(this.directLoginsIndex()[directLoginReference]);
|
|
||||||
delete this.directLoginsIndex()[directLoginReference];
|
delete this.directLoginsIndex()[directLoginReference];
|
||||||
}
|
}
|
||||||
}, this),
|
}, this),
|
||||||
|
@ -41,7 +41,7 @@ Clipperz.PM.DataModel.User = function (args) {
|
|||||||
this._connection = null;
|
this._connection = null;
|
||||||
this._connectionVersion = 'current';
|
this._connectionVersion = 'current';
|
||||||
|
|
||||||
this._subscription = null;
|
this._accountInfo = null;
|
||||||
this._serverData = null;
|
this._serverData = null;
|
||||||
// this._serverLockValue = null;
|
// this._serverLockValue = null;
|
||||||
this._transientState = null;
|
this._transientState = null;
|
||||||
@ -78,12 +78,12 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
|||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
// this.setSubscription(new Clipperz.PM.DataModel.User.Subscription(someServerData['subscription']));
|
// this.setSubscription(new Clipperz.PM.DataModel.User.Subscription(someServerData['subscription']));
|
||||||
'subscription': function () {
|
'accountInfo': function () {
|
||||||
return this._subscription;
|
return this._accountInfo;
|
||||||
},
|
},
|
||||||
|
|
||||||
'setSubscription': function (aValue) {
|
'setAccountInfo': function (aValue) {
|
||||||
this._subscription = aValue;
|
this._accountInfo = aValue;
|
||||||
},
|
},
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
@ -247,19 +247,16 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
|||||||
var deferredResult;
|
var deferredResult;
|
||||||
|
|
||||||
deferredResult = new Clipperz.Async.Deferred("User.login", {trace:false});
|
deferredResult = new Clipperz.Async.Deferred("User.login", {trace:false});
|
||||||
// deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':3});
|
|
||||||
deferredResult.addMethod(this, 'getPassphrase');
|
deferredResult.addMethod(this, 'getPassphrase');
|
||||||
deferredResult.addCallback(Clipperz.PM.DataModel.OneTimePassword.isValidOneTimePasswordValue);
|
deferredResult.addCallback(Clipperz.PM.DataModel.OneTimePassword.isValidOneTimePasswordValue);
|
||||||
deferredResult.addCallback(Clipperz.Async.deferredIf("Is the passphrase an OTP", [
|
deferredResult.addCallback(Clipperz.Async.deferredIf("Is the passphrase an OTP", [
|
||||||
// MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':1}),
|
|
||||||
MochiKit.Base.method(this, 'getCredentials'),
|
MochiKit.Base.method(this, 'getCredentials'),
|
||||||
MochiKit.Base.method(this.connection(), 'redeemOneTimePassword'),
|
MochiKit.Base.method(this.connection(), 'redeemOneTimePassword'),
|
||||||
MochiKit.Base.method(this.data(), 'setValue', 'passphrase')
|
MochiKit.Base.method(this.data(), 'setValue', 'passphrase')
|
||||||
], []));
|
], []));
|
||||||
deferredResult.addErrback(MochiKit.Base.method(this, 'getPassphrase'));
|
deferredResult.addErrback(MochiKit.Base.method(this, 'getPassphrase'));
|
||||||
deferredResult.addMethod(this.connection(), 'login', false);
|
deferredResult.addMethod(this.connection(), 'login', false);
|
||||||
deferredResult.addMethod(this, 'setupConnectionInfo');
|
deferredResult.addMethod(this, 'setupAccountInfo');
|
||||||
// deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'userSuccessfullyLoggedIn');
|
|
||||||
deferredResult.addErrback (MochiKit.Base.method(this, 'handleConnectionFallback'));
|
deferredResult.addErrback (MochiKit.Base.method(this, 'handleConnectionFallback'));
|
||||||
|
|
||||||
deferredResult.callback();
|
deferredResult.callback();
|
||||||
@ -295,9 +292,10 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
'setupConnectionInfo': function (aValue) {
|
'setupAccountInfo': function (aValue) {
|
||||||
|
//console.log("User.setupAccountInfo", aValue, aValue['accountInfo']);
|
||||||
// this.setLoginInfo(aValue['loginInfo']);
|
// this.setLoginInfo(aValue['loginInfo']);
|
||||||
this.setSubscription(new Clipperz.PM.DataModel.User.Subscription(aValue['subscription']));
|
this.setAccountInfo(new Clipperz.PM.DataModel.User.AccountInfo(aValue['accountInfo']));
|
||||||
},
|
},
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
@ -511,6 +509,19 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
|||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
||||||
|
'getTags': function () {
|
||||||
|
return Clipperz.Async.callbacks("User.getTags", [
|
||||||
|
MochiKit.Base.method(this, 'getRecords'),
|
||||||
|
MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('tags')),
|
||||||
|
Clipperz.Async.collectAll,
|
||||||
|
MochiKit.Base.flattenArray,
|
||||||
|
Clipperz.Base.arrayWithUniqueValues
|
||||||
|
|
||||||
|
], {trace:false});
|
||||||
|
},
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
|
||||||
'getRecords': function () {
|
'getRecords': function () {
|
||||||
return Clipperz.Async.callbacks("User.getRecords", [
|
return Clipperz.Async.callbacks("User.getRecords", [
|
||||||
MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'),
|
MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'),
|
||||||
@ -519,6 +530,36 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
|||||||
], {trace:false});
|
], {trace:false});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'getRecordsInfo': function (someInfo, shouldIncludeArchivedCards) {
|
||||||
|
return Clipperz.Async.callbacks("User.getRecordsInfo", [
|
||||||
|
MochiKit.Base.method(this, 'getRecords'),
|
||||||
|
MochiKit.Base.partial(MochiKit.Base.map, Clipperz.Async.collectResults("collectResults", someInfo, {trace:false})),
|
||||||
|
Clipperz.Async.collectAll
|
||||||
|
], {trace:false});
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
'filterRecordsInfo': function (someArgs) {
|
||||||
|
var info = (someArgs.info ? someArgs.info : Clipperz.PM.DataModel.Record.defaultCardInfo);
|
||||||
|
var searchField = (someArgs.searchField ? someArgs.searchField : Clipperz.PM.DataModel.Record.defaultSearchField);
|
||||||
|
var includeArchived = (someArgs.includeArchived ? someArgs.includeArchived : false);
|
||||||
|
var regExp = (someArgs.regExp ? someArgs.regExp : Clipperz.PM.DataModel.Record.regExpForSearch(''));
|
||||||
|
|
||||||
|
if (someArgs.regExp) {
|
||||||
|
regExp = regExp;
|
||||||
|
} else if (someArgs.search) {
|
||||||
|
regExp = Clipperz.PM.DataModel.Record.regExpForSearch(someArgs.search);
|
||||||
|
} else if (someArgs.tag) {
|
||||||
|
regExp = Clipperz.PM.DataModel.Record.regExpForTag(someArgs.tag);
|
||||||
|
} else {
|
||||||
|
regExp = Clipperz.PM.DataModel.Record.regExpForSearch('');
|
||||||
|
};
|
||||||
|
|
||||||
|
return Clipperz.Async.callbacks("User.filterRecordsInfo", [
|
||||||
|
MochiKit.Base.method(this, 'getRecordsInfo', info, includeArchived),
|
||||||
|
MochiKit.Base.partial(MochiKit.Base.filter, function (aCardInfo) { regExp.lastIndex = 0; return regExp.test(aCardInfo[searchField]);})
|
||||||
|
], {trace:false});
|
||||||
|
},
|
||||||
|
*/
|
||||||
'recordWithLabel': function (aLabel) {
|
'recordWithLabel': function (aLabel) {
|
||||||
return Clipperz.Async.callbacks("User.recordWithLabel", [
|
return Clipperz.Async.callbacks("User.recordWithLabel", [
|
||||||
MochiKit.Base.method(this, 'getRecords'),
|
MochiKit.Base.method(this, 'getRecords'),
|
||||||
|
@ -152,7 +152,7 @@ Clipperz.PM.Proxy.prototype = MochiKit.Base.update(null, {
|
|||||||
'sendMessage': function (aFunctionName, someParameters) {
|
'sendMessage': function (aFunctionName, someParameters) {
|
||||||
var deferredResult;
|
var deferredResult;
|
||||||
|
|
||||||
console.log("PROXY.sendMessage", aFunctionName, someParameters);
|
//console.log("PROXY.sendMessage", aFunctionName, someParameters);
|
||||||
// TODO: read actual application version for a property set at build time
|
// TODO: read actual application version for a property set at build time
|
||||||
deferredResult = new Clipperz.Async.Deferred("Proxy.sendMessage", {trace:false});
|
deferredResult = new Clipperz.Async.Deferred("Proxy.sendMessage", {trace:false});
|
||||||
deferredResult.addMethod(this, '_sendMessage', aFunctionName, 'fake-app-version');
|
deferredResult.addMethod(this, '_sendMessage', aFunctionName, 'fake-app-version');
|
||||||
|
@ -57,7 +57,7 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.JSON, Clipperz.PM.Proxy, {
|
|||||||
version: aVersion,
|
version: aVersion,
|
||||||
parameters: Clipperz.Base.serializeJSON(someParameters)
|
parameters: Clipperz.Base.serializeJSON(someParameters)
|
||||||
};
|
};
|
||||||
console.log("PROXY.JSON._sendMessage", parameters);
|
//console.log("PROXY.JSON._sendMessage", parameters);
|
||||||
deferredResult = new Clipperz.Async.Deferred("Proxy.JSON._sendMessage", {trace:false});
|
deferredResult = new Clipperz.Async.Deferred("Proxy.JSON._sendMessage", {trace:false});
|
||||||
deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'remoteRequestSent');
|
deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'remoteRequestSent');
|
||||||
deferredResult.addCallback(MochiKit.Async.doXHR, this.url(), {
|
deferredResult.addCallback(MochiKit.Async.doXHR, this.url(), {
|
||||||
|
@ -296,14 +296,14 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, {
|
|||||||
throw "user already exists";
|
throw "user already exists";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
|
throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
result: {
|
result: {
|
||||||
'lock': this.data()['users'][someParameters['credentials']['C']]['lock'],
|
'lock': this.data()['users'][someParameters['credentials']['C']]['lock'],
|
||||||
'result': 'done'
|
'result': 'done'
|
||||||
},
|
},
|
||||||
toll: this.getTollForRequestType('CONNECT')
|
toll: this.getTollForRequestType('CONNECT')
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,7 +334,7 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, {
|
|||||||
randomBytes = Clipperz.Crypto.Base.generateRandomSeed();
|
randomBytes = Clipperz.Crypto.Base.generateRandomSeed();
|
||||||
aConnection['b'] = new Clipperz.Crypto.BigInt(randomBytes, 16);
|
aConnection['b'] = new Clipperz.Crypto.BigInt(randomBytes, 16);
|
||||||
v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16);
|
v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16);
|
||||||
aConnection['B'] = v.add(Clipperz.Crypto.SRP.g().powerModule(aConnection['b'], Clipperz.Crypto.SRP.n()));
|
aConnection['B'] = (Clipperz.Crypto.SRP.k().multiply(v)).add(Clipperz.Crypto.SRP.g().powerModule(aConnection['b'], Clipperz.Crypto.SRP.n()));
|
||||||
|
|
||||||
aConnection['A'] = someParameters.parameters.A;
|
aConnection['A'] = someParameters.parameters.A;
|
||||||
|
|
||||||
@ -343,21 +343,65 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, {
|
|||||||
|
|
||||||
nextTollRequestType = 'CONNECT';
|
nextTollRequestType = 'CONNECT';
|
||||||
} else if (someParameters.message == "credentialCheck") {
|
} else if (someParameters.message == "credentialCheck") {
|
||||||
var v, u, S, A, K, M1;
|
var v, u, s, S, A, K, M1;
|
||||||
|
var stringHash = function (aValue) {
|
||||||
|
return Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2);
|
||||||
|
};
|
||||||
|
|
||||||
v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16);
|
v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16);
|
||||||
u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(aConnection['B'].asString(10))).toHexString(), 16);
|
|
||||||
A = new Clipperz.Crypto.BigInt(aConnection['A'], 16);
|
A = new Clipperz.Crypto.BigInt(aConnection['A'], 16);
|
||||||
|
u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + aConnection['B'].asString(10))).toHexString(), 16);
|
||||||
|
s = new Clipperz.Crypto.BigInt(aConnection['userData']['s'], 16);
|
||||||
S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n());
|
S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n());
|
||||||
|
|
||||||
K = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(S.asString(10))).toHexString().slice(2);
|
K = stringHash(S.asString(10));
|
||||||
|
|
||||||
M1 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + aConnection['B'].asString(10) + K)).toHexString().slice(2);
|
M1 = stringHash(
|
||||||
|
"597626870978286801440197562148588907434001483655788865609375806439877501869636875571920406529" +
|
||||||
|
stringHash(aConnection['C']) +
|
||||||
|
s.asString(10) +
|
||||||
|
A.asString(10) +
|
||||||
|
aConnection['B'].asString(10) +
|
||||||
|
K
|
||||||
|
);
|
||||||
if (someParameters.parameters.M1 == M1) {
|
if (someParameters.parameters.M1 == M1) {
|
||||||
var M2;
|
var M2;
|
||||||
|
|
||||||
M2 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + someParameters.parameters.M1 + K)).toHexString().slice(2);
|
M2 = stringHash(
|
||||||
|
A.asString(10) +
|
||||||
|
someParameters.parameters.M1 +
|
||||||
|
K
|
||||||
|
);
|
||||||
result['M2'] = M2;
|
result['M2'] = M2;
|
||||||
|
result['accountInfo'] = {
|
||||||
|
'currentSubscriptionType': "FAN",
|
||||||
|
'expirationDate': "Tue, 21 April 2015 11:59:12 UTC",
|
||||||
|
'featureSet': "FULL",
|
||||||
|
'features': [
|
||||||
|
'UPDATE_CREDENTIALS',
|
||||||
|
'EDIT_CARD',
|
||||||
|
'CARD_DETAILS',
|
||||||
|
'ADD_CARD',
|
||||||
|
'DELETE_CARD',
|
||||||
|
'OFFLINE_COPY',
|
||||||
|
'LIST_CARDS'
|
||||||
|
],
|
||||||
|
'isExpired': false,
|
||||||
|
'isExpiring': false,
|
||||||
|
'latestActiveLevel': "PAYING",
|
||||||
|
'latestActiveThreshold': "5.00000000",
|
||||||
|
'paymentVerificationPending': false,
|
||||||
|
'payments': [
|
||||||
|
{
|
||||||
|
'amount': "0.08500000",
|
||||||
|
'currency': "BTC",
|
||||||
|
'date': "Mon, 21 April 2014 12:11:12 UTC",
|
||||||
|
'reference': "cad577106f8747ae1b0fad3f139f4b4644301a0608dd931f758ad18c1766cabe",
|
||||||
|
'value': "5.23730000"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'referenceDate': "Tue, 22 July 2014 15:47:08 UTC"
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Client checksum verification failed! Expected <" + M1 + ">, received <" + someParameters.parameters.M1 + ">.", "Error");
|
throw new Error("Client checksum verification failed! Expected <" + M1 + ">, received <" + someParameters.parameters.M1 + ">.", "Error");
|
||||||
}
|
}
|
||||||
@ -426,6 +470,7 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, {
|
|||||||
recordsStats = {};
|
recordsStats = {};
|
||||||
for (recordReference in aConnection['userData']['records']) {
|
for (recordReference in aConnection['userData']['records']) {
|
||||||
recordsStats[recordReference] = {
|
recordsStats[recordReference] = {
|
||||||
|
'accessDate': aConnection['userData']['records'][recordReference]['accessDate'],
|
||||||
'updateDate': aConnection['userData']['records'][recordReference]['updateDate']
|
'updateDate': aConnection['userData']['records'][recordReference]['updateDate']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
56
frontend/delta/js/Clipperz/PM/UI/Components/AccountStatus.js
Normal file
56
frontend/delta/js/Clipperz/PM/UI/Components/AccountStatus.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
Clipperz.Base.module('Clipperz.PM.UI.Components');
|
||||||
|
|
||||||
|
Clipperz.PM.UI.Components.AccountStatus = React.createClass({
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
'currentSubscriptionType': React.PropTypes.oneOf(['EARLY_ADOPTER', 'FRIEND', 'FAN', 'DEVOTEE', 'PATRON', 'TRIAL', 'TRIAL_EXPIRED', 'PAYMENT_FAILED_2', 'EXPIRED', 'PAYMENT_FAILED', 'VERIFYING_PAYMENT', 'VERIFYING_PAYMENT_2']).isRequired,
|
||||||
|
'expirationDate': React.PropTypes.string.isRequired,
|
||||||
|
'featureSet': React.PropTypes.oneOf(['TRIAL', 'EXPIRED', 'FULL']).isRequired,
|
||||||
|
'isExpired': React.PropTypes.bool.isRequired,
|
||||||
|
'isExpiring': React.PropTypes.bool.isRequired,
|
||||||
|
'paymentVerificationPending': React.PropTypes.bool.isRequired,
|
||||||
|
},
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
//console.log("AccountStatus props", this.props);
|
||||||
|
var classes = {
|
||||||
|
'accountStatus': true,
|
||||||
|
'isExpiring': this.props['isExpiring'],
|
||||||
|
'isExpired': this.props['isExpired'],
|
||||||
|
};
|
||||||
|
|
||||||
|
classes[this.props['featureSet']] = true;
|
||||||
|
|
||||||
|
return React.DOM.div({'className':React.addons.classSet(classes)}, [
|
||||||
|
React.DOM.span({'className': 'level'}, this.props['featureSet']),
|
||||||
|
React.DOM.span({'className': 'expirationDate'}, this.props['expirationDate'])
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
});
|
53
frontend/delta/js/Clipperz/PM/UI/Components/Button.js
Normal file
53
frontend/delta/js/Clipperz/PM/UI/Components/Button.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
Clipperz.Base.module('Clipperz.PM.UI.Components');
|
||||||
|
|
||||||
|
Clipperz.PM.UI.Components.Button = React.createClass({
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
'eventName': React.PropTypes.string.isRequired,
|
||||||
|
'label': React.PropTypes.string.isRequired,
|
||||||
|
'handler': React.PropTypes.func.isRequired,
|
||||||
|
'className': React.PropTypes.string
|
||||||
|
},
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
var classes = {
|
||||||
|
'button': true
|
||||||
|
};
|
||||||
|
if (typeof(this.props['className']) != 'undefined') {
|
||||||
|
classes[this.props['className']] = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
return React.DOM.div({className:React.addons.classSet(classes), onClick:this.props['handler']}, [
|
||||||
|
React.DOM.div({className:this.props['eventName']}, [
|
||||||
|
React.DOM.h3({className:'label'}, this.props['label'])
|
||||||
|
])
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
});
|
@ -1,195 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Copyright 2008-2013 Clipperz Srl
|
|
||||||
|
|
||||||
This file is part of Clipperz, the online password manager.
|
|
||||||
For further information about its features and functionalities please
|
|
||||||
refer to http://www.clipperz.com.
|
|
||||||
|
|
||||||
* Clipperz is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU Affero General Public License as published
|
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
* Clipperz is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
* You should have received a copy of the GNU Affero General Public
|
|
||||||
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
Clipperz.PM.UI.Components.CardDetail = React.createClass({
|
|
||||||
|
|
||||||
getDefaultProps: function () {
|
|
||||||
return {
|
|
||||||
// searchDelay: 0.3
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
propTypes: {
|
|
||||||
card: React.PropTypes.object.isRequired
|
|
||||||
},
|
|
||||||
|
|
||||||
getInitialState: function () {
|
|
||||||
return {
|
|
||||||
// showSearch: false,
|
|
||||||
// searchTimer: null,
|
|
||||||
unmaskedFields: new Clipperz.Set(),
|
|
||||||
starred: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
handleDirectLoginClick: function (aDirectLoginReference, anEvent) {
|
|
||||||
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'runDirectLogin', {record:this.props.card['reference'], directLogin:aDirectLoginReference});
|
|
||||||
},
|
|
||||||
|
|
||||||
toggleFieldVisibility: function (aField, anEvent) {
|
|
||||||
var unmaskedFields;
|
|
||||||
var fieldReference;
|
|
||||||
|
|
||||||
unmaskedFields = this.state['unmaskedFields'];
|
|
||||||
fieldReference = aField['reference']
|
|
||||||
if (unmaskedFields.contains(fieldReference)) {
|
|
||||||
unmaskedFields.remove(fieldReference)
|
|
||||||
} else {
|
|
||||||
unmaskedFields.add(fieldReference)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({'unmaskedFields': unmaskedFields});
|
|
||||||
},
|
|
||||||
|
|
||||||
handleGoAction: function (aField, anEvent) {
|
|
||||||
var newWindow;
|
|
||||||
|
|
||||||
newWindow = MochiKit.DOM.currentWindow().open(aField['value'], '_blank');
|
|
||||||
newWindow.focus();
|
|
||||||
},
|
|
||||||
|
|
||||||
handleEmailAction: function (aField, anEvent) {
|
|
||||||
MochiKit.DOM.currentWindow().location = 'mailto:' + aField['value'];
|
|
||||||
},
|
|
||||||
|
|
||||||
//=========================================================================
|
|
||||||
|
|
||||||
normalizeFieldValue: function (aValue) {
|
|
||||||
var result = [];
|
|
||||||
var rows = aValue.split('\n');
|
|
||||||
|
|
||||||
for (var i = 0; i < rows.length; i++) {
|
|
||||||
if (i > 0) {
|
|
||||||
result.push(React.DOM.br());
|
|
||||||
}
|
|
||||||
result.push(rows[i].replace(/[\s]/g, '\u00A0'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
renderFieldActionButton: function (aField) {
|
|
||||||
// var actionLabel;
|
|
||||||
var result;
|
|
||||||
|
|
||||||
if (aField['actionType'] == 'URL') {
|
|
||||||
result = React.DOM.div({className:'actionWrapper', onClick:MochiKit.Base.method(this, 'handleGoAction', aField)}, [
|
|
||||||
React.DOM.a({className:aField['actionType']}, "go")
|
|
||||||
]);
|
|
||||||
} else if (aField['actionType'] == 'PASSWORD') {
|
|
||||||
var icon;
|
|
||||||
|
|
||||||
if (this.state['unmaskedFields'].contains(aField['reference'])) {
|
|
||||||
icon = "unlocked";
|
|
||||||
} else {
|
|
||||||
icon = "locked";
|
|
||||||
}
|
|
||||||
result = React.DOM.div({className:'actionWrapper', onClick:MochiKit.Base.method(this, 'toggleFieldVisibility', aField)}, [
|
|
||||||
React.DOM.a({className:aField['actionType']}, icon)
|
|
||||||
]);
|
|
||||||
} else if (aField['actionType'] == 'EMAIL') {
|
|
||||||
result = React.DOM.div({className:'actionWrapper', onClick:MochiKit.Base.method(this, 'handleEmailAction', aField)}, [
|
|
||||||
React.DOM.a({className:aField['actionType']}, "email")
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
result = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
renderField: function (aField) {
|
|
||||||
//console.log("FIELD", aField);
|
|
||||||
var fieldExtraClass;
|
|
||||||
|
|
||||||
fieldExtraClass = aField['actionType'];
|
|
||||||
if (this.state['unmaskedFields'].contains(aField['reference'])) {
|
|
||||||
fieldExtraClass = fieldExtraClass + ' unlocked';
|
|
||||||
}
|
|
||||||
|
|
||||||
return React.DOM.div({className:'listItem ' + fieldExtraClass, key:aField['reference']}, [
|
|
||||||
React.DOM.div({className:'fieldWrapper'}, [
|
|
||||||
React.DOM.div({className:'fieldInnerWrapper'}, [
|
|
||||||
React.DOM.div({className:'labelWrapper'}, React.DOM.span({className:'label'}, aField['label'])),
|
|
||||||
React.DOM.div({className:'valueWrapper'}, React.DOM.span({className:'value ' + fieldExtraClass}, this.normalizeFieldValue(aField['value'])))
|
|
||||||
])
|
|
||||||
]),
|
|
||||||
this.renderFieldActionButton(aField)
|
|
||||||
// React.DOM.div({className:'actionWrapper'}, [
|
|
||||||
// React.DOM.div({className:aField['actionType']}, actionLabel)
|
|
||||||
// ])
|
|
||||||
]);
|
|
||||||
},
|
|
||||||
|
|
||||||
renderDirectLogin: function (aDirectLogin) {
|
|
||||||
//console.log("DIRECT LOGIN", aDirectLogin);
|
|
||||||
return React.DOM.div({className:'listItem', onClick:MochiKit.Base.method(this, 'handleDirectLoginClick', aDirectLogin['reference'])}, [
|
|
||||||
React.DOM.div({className:'labelWrapper'}, React.DOM.span({className:'label'}, aDirectLogin['label'])),
|
|
||||||
React.DOM.div({className:'faviconWrapper'}, React.DOM.img({className:'favicon', src:aDirectLogin['favicon']})),
|
|
||||||
React.DOM.div({className:'directLoginLinkWrapper'}, React.DOM.span({className:'directLoginLink'}, "go"))
|
|
||||||
]);
|
|
||||||
},
|
|
||||||
|
|
||||||
handleBackClick: function (anEvent) {
|
|
||||||
// window.history.back();
|
|
||||||
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'goBack');
|
|
||||||
},
|
|
||||||
|
|
||||||
handleStarClick: function (anEvent) {
|
|
||||||
this.setState({starred: !this.state['starred']});
|
|
||||||
},
|
|
||||||
|
|
||||||
//=========================================================================
|
|
||||||
|
|
||||||
render: function () {
|
|
||||||
var card = this.props.card;
|
|
||||||
// var starredStatus = (this.state['starred'] ? "starred" : "unstarred");
|
|
||||||
|
|
||||||
if ((typeof(card['fields']) != 'undefined') && (card['notes'] != '')) {
|
|
||||||
card['fields'].push({ 'actionType': 'NOTES', 'isHidden': false, 'label': "notes", 'reference': "notes", 'value': card['notes'] })
|
|
||||||
}
|
|
||||||
|
|
||||||
return React.DOM.div({className:'cardDetail'}, [
|
|
||||||
React.DOM.div({className:'header'}, [
|
|
||||||
React.DOM.div({className:'titleWrapper'}, React.DOM.div({className:'title'}, card.title)),
|
|
||||||
React.DOM.div({className:'backWrapper'}, React.DOM.a({className:'button back', onClick:this.handleBackClick}, "back")),
|
|
||||||
// React.DOM.div({className:'starWrapper'}, React.DOM.a({className:'star', onClick:this.handleStarClick}, starredStatus))
|
|
||||||
]),
|
|
||||||
React.DOM.div({className:'content'}, [
|
|
||||||
card.fields ? React.DOM.div({className:'fields'}, MochiKit.Base.map(this.renderField, card.fields)) : null,
|
|
||||||
card.directLogins ? React.DOM.div({className:'directLogins'}, MochiKit.Base.map(this.renderDirectLogin, card.directLogins)): null
|
|
||||||
]),
|
|
||||||
React.DOM.div({className:'footer'}, [
|
|
||||||
/*
|
|
||||||
// React.DOM.a({className:'cancel'}, "cancel"),
|
|
||||||
// React.DOM.a({className:'save'}, "save")
|
|
||||||
|
|
||||||
React.DOM.a({className:'cancel button'}, "failed"),
|
|
||||||
React.DOM.a({className:'save button'}, "done")
|
|
||||||
*/
|
|
||||||
])
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//=========================================================================
|
|
||||||
});
|
|
@ -1,168 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Copyright 2008-2013 Clipperz Srl
|
|
||||||
|
|
||||||
This file is part of Clipperz, the online password manager.
|
|
||||||
For further information about its features and functionalities please
|
|
||||||
refer to http://www.clipperz.com.
|
|
||||||
|
|
||||||
* Clipperz is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU Affero General Public License as published
|
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
* Clipperz is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
* You should have received a copy of the GNU Affero General Public
|
|
||||||
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
Clipperz.PM.UI.Components.CardList = React.createClass({
|
|
||||||
|
|
||||||
getDefaultProps: function () {
|
|
||||||
return {
|
|
||||||
selectedCard: null,
|
|
||||||
searchDelay: 0.3
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
propTypes: {
|
|
||||||
searchDelay: React.PropTypes.number
|
|
||||||
},
|
|
||||||
|
|
||||||
getInitialState: function () {
|
|
||||||
return {
|
|
||||||
showSearch: false,
|
|
||||||
searchTimer: null,
|
|
||||||
searchText: '',
|
|
||||||
// passphrase: '',
|
|
||||||
// pin: ''
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
//=========================================================================
|
|
||||||
|
|
||||||
toggleSearch: function (anEvent) {
|
|
||||||
var showSearchBox;
|
|
||||||
|
|
||||||
showSearchBox = !this.state.showSearch;
|
|
||||||
|
|
||||||
this.setState({showSearch: showSearchBox});
|
|
||||||
|
|
||||||
if (showSearchBox) {
|
|
||||||
MochiKit.Async.callLater(0.1, MochiKit.Base.method(this, 'focusOnSearchField'));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
updateSearchText: function (anEvent) {
|
|
||||||
var searchText;
|
|
||||||
|
|
||||||
searchText = anEvent.target.value;
|
|
||||||
//console.log(">>> updateSearchText", searchText);
|
|
||||||
|
|
||||||
if ((this.state['searchTimer'] != null) && (searchText != this.state['searchText'])) {
|
|
||||||
this.state['searchTimer'].cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (searchText != this.state['searchText']) {
|
|
||||||
this.state['searchText'] = searchText;
|
|
||||||
this.state['searchTimer'] = MochiKit.Async.callLater(this.props['searchDelay'], MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'searchCards', searchText);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
focusOnSearchField: function () {
|
|
||||||
console.log("focusOnSearchField", this.refs['searchField']);
|
|
||||||
this.refs['searchField'].getDOMNode.focus();
|
|
||||||
},
|
|
||||||
|
|
||||||
searchBox: function () {
|
|
||||||
var result;
|
|
||||||
|
|
||||||
if (this.state.showSearch) {
|
|
||||||
result = React.DOM.div({className:'searchBox'}, [
|
|
||||||
React.DOM.div(null, [
|
|
||||||
React.DOM.input({type:'search', placeholder:"search", ref:'searchField', onChange:this.updateSearchText})
|
|
||||||
])
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
result = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
//=========================================================================
|
|
||||||
|
|
||||||
showPreferences: function (anEvent) {
|
|
||||||
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'showPreferences', anEvent);
|
|
||||||
},
|
|
||||||
|
|
||||||
//=========================================================================
|
|
||||||
|
|
||||||
cardItem: function (aRecordReference) {
|
|
||||||
var reference = aRecordReference['_reference'];
|
|
||||||
var selectedCard = (reference == this.props.selectedCard);
|
|
||||||
|
|
||||||
// TODO: verify if it is possible to put the onClick handler on the container 'div', instead of adding it to each 'div' item.
|
|
||||||
return React.DOM.div({className:'listItem', key:reference, onClick:MochiKit.Base.method(this, 'handleClickOnCardDetail', reference)}, [
|
|
||||||
React.DOM.div({className:'labelWrapper'}, React.DOM.span({className:'label'}, aRecordReference.label)),
|
|
||||||
// React.DOM.div({className:'labelWrapper'}, React.DOM.span({className:'label'}, aRecordReference.label + ' ' + aRecordReference.label + ' ' + aRecordReference.label + ' ' + aRecordReference.label + ' ' + aRecordReference.label)),
|
|
||||||
React.DOM.div({className:'faviconWrapper'}, aRecordReference.favicon ? React.DOM.img({className:'favicon', src:aRecordReference.favicon}) : React.DOM.div({className:'favicon'}, '\u00A0')),
|
|
||||||
React.DOM.div({className:'detailLinkWrapper'}, React.DOM.span({className:'detailLink ' + (selectedCard ? 'icon-spin' : '')}, (selectedCard ? "loading" : "detail")))
|
|
||||||
]);
|
|
||||||
},
|
|
||||||
|
|
||||||
handleClickOnCardDetail: function (aRecordReference, anEvent) {
|
|
||||||
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'showRecord', aRecordReference);
|
|
||||||
},
|
|
||||||
|
|
||||||
cardListItems: function () {
|
|
||||||
var list;
|
|
||||||
var result;
|
|
||||||
|
|
||||||
list = this.props['cardList'];
|
|
||||||
|
|
||||||
if (typeof(list) != 'undefined') {
|
|
||||||
result = MochiKit.Base.map(MochiKit.Base.method(this, 'cardItem'), list);
|
|
||||||
} else {
|
|
||||||
result = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
//=========================================================================
|
|
||||||
|
|
||||||
handleChange: function (anEvent) {
|
|
||||||
// var refs = this.refs;
|
|
||||||
// var refName = MochiKit.Base.filter(function (aRefName) { return refs[aRefName].getDOMNode() == anEvent.target}, MochiKit.Base.keys(this.refs))[0];
|
|
||||||
// var newState = {};
|
|
||||||
//
|
|
||||||
// newState[refName] = event.target.value;
|
|
||||||
// this.setState(newState);
|
|
||||||
},
|
|
||||||
|
|
||||||
//=========================================================================
|
|
||||||
|
|
||||||
render: function() {
|
|
||||||
return React.DOM.div(null, [
|
|
||||||
React.DOM.div({className:'header'}, [
|
|
||||||
React.DOM.a({className:'account'}, 'clipperz'),
|
|
||||||
React.DOM.div({className:'features'}, [
|
|
||||||
// React.DOM.a({className:'addCard'}, 'add'),
|
|
||||||
React.DOM.a({className:'search ' + (this.state.showSearch ? 'selected' : ''), onClick:this.toggleSearch}, 'search'),
|
|
||||||
React.DOM.a({className:'settings', onClick:this.showPreferences}, 'settings')
|
|
||||||
]),
|
|
||||||
// this.searchBox()
|
|
||||||
]),
|
|
||||||
this.searchBox(),
|
|
||||||
React.DOM.div({className:'content cardList'}, this.cardListItems()),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//=========================================================================
|
|
||||||
});
|
|
101
frontend/delta/js/Clipperz/PM/UI/Components/CardToolbar.js
Normal file
101
frontend/delta/js/Clipperz/PM/UI/Components/CardToolbar.js
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
Clipperz.Base.module('Clipperz.PM.UI.Components');
|
||||||
|
|
||||||
|
Clipperz.PM.UI.Components.CardToolbar = React.createClass({
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
// 'style': React.PropTypes.oneOf(['extra-short', 'narrow', 'wide', 'extra-wide']).isRequired,
|
||||||
|
'style': React.PropTypes.oneOf(Clipperz_PM_UI_availableStyles).isRequired,
|
||||||
|
'enableSidePanels': React.PropTypes.bool.isRequired,
|
||||||
|
'accountStatus': React.PropTypes.object.isRequired,
|
||||||
|
'messageBox': React.PropTypes.object.isRequired,
|
||||||
|
'filter': React.PropTypes.object.isRequired
|
||||||
|
},
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
selectionToggleHandler: function (anEvent) {
|
||||||
|
//console.log("selectionToggleHandler");
|
||||||
|
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'toggleSelectionPanel');
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
settingsToggleHandler: function (anEvent) {
|
||||||
|
//console.log("settingsToggleHandler");
|
||||||
|
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'toggleSettingsPanel');
|
||||||
|
},
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
renderWithSidePanels: function () {
|
||||||
|
return [
|
||||||
|
React.DOM.div({className:'selectionToggle'}, [
|
||||||
|
Clipperz.PM.UI.Components.Button({eventName:'selectionToggleButton', label:"tags", handler:this.selectionToggleHandler})
|
||||||
|
]),
|
||||||
|
this.renderWithoutSidePanels(),
|
||||||
|
React.DOM.div({className:'settingsToggle'}, [
|
||||||
|
Clipperz.PM.UI.Components.Button({eventName:'settingsToggleButton', label:"menu", handler:this.settingsToggleHandler})
|
||||||
|
])
|
||||||
|
];
|
||||||
|
},
|
||||||
|
|
||||||
|
renderWithoutSidePanels: function () {
|
||||||
|
var result;
|
||||||
|
|
||||||
|
if (this.props['filter']) {
|
||||||
|
if (this.props['filter']['type'] == 'RECENT') {
|
||||||
|
result = [React.DOM.div({className:'clipperz'}, [React.DOM.span({className:'logo recent'}, "recent")])];
|
||||||
|
} else if (this.props['filter']['type'] == 'TAG') {
|
||||||
|
result = [React.DOM.div({className:'clipperz'}, [
|
||||||
|
React.DOM.span({className:'logo tag'}, "tag"),
|
||||||
|
React.DOM.span({className:'value'}, this.props['filter']['value'])
|
||||||
|
])];
|
||||||
|
} else if (this.props['filter']['type'] == 'SEARCH') {
|
||||||
|
result = [React.DOM.div({className:'clipperz'}, [
|
||||||
|
React.DOM.span({className:'logo search'}, "search"),
|
||||||
|
React.DOM.span({className:'value'}, this.props['filter']['value'])
|
||||||
|
])];
|
||||||
|
} else {
|
||||||
|
result = [React.DOM.div({className:'clipperz'}, [React.DOM.span({className:'logo clipperz'}, "clipperz")])];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = [React.DOM.div({className:'clipperz'}, [React.DOM.span({className:'logo clipperz'}, "clipperz")])];
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
//console.log("CardToolbar props", this.props);
|
||||||
|
return React.DOM.div({className:'cardToolbar ' + this.props['style']}, [
|
||||||
|
// React.DOM.div({className:'header'}, this.props['enableSidePanels'] ? this.renderWithSidePanels() : this.renderWithoutSidePanels()),
|
||||||
|
React.DOM.header({}, this.props['enableSidePanels'] ? this.renderWithSidePanels() : this.renderWithoutSidePanels()),
|
||||||
|
Clipperz.PM.UI.Components.AccountStatus(this.props['accountStatus']),
|
||||||
|
Clipperz.PM.UI.Components.MessageBox(this.props['messageBox']),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
});
|
66
frontend/delta/js/Clipperz/PM/UI/Components/Cards/List.js
Normal file
66
frontend/delta/js/Clipperz/PM/UI/Components/Cards/List.js
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
Clipperz.Base.module('Clipperz.PM.UI.Components.Cards');
|
||||||
|
|
||||||
|
Clipperz.PM.UI.Components.Cards.List = React.createClass({
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
'cards': React.PropTypes.array,
|
||||||
|
'selectedCard': React.PropTypes.string
|
||||||
|
},
|
||||||
|
|
||||||
|
handleClick: function (anEvent) {
|
||||||
|
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'cardSelected', {'reference':anEvent.currentTarget.dataset.reference, 'label':anEvent.currentTarget.dataset.label});
|
||||||
|
},
|
||||||
|
|
||||||
|
renderItem: function (anItem) {
|
||||||
|
var classes = {
|
||||||
|
'selected': this.props['selectedCard'] ? this.props['selectedCard']['_reference'] == anItem['_reference'] : false
|
||||||
|
};
|
||||||
|
|
||||||
|
return React.DOM.li({'className':React.addons.classSet(classes), 'onClick': this.handleClick, 'key':anItem['_reference'], 'data-reference':anItem['_reference'], 'data-label':anItem['label']}, [
|
||||||
|
React.DOM.span({'className':'favicon'}, [ React.DOM.img({src:anItem['favicon']})]),
|
||||||
|
React.DOM.span({'className':'label'}, anItem['label']),
|
||||||
|
// React.DOM.span({'className':'action'}, 'show detail')
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
var cards = this.props['cards'] ? this.props['cards'] : [];
|
||||||
|
var classes = {
|
||||||
|
'cardList': true,
|
||||||
|
'loadingCard': this.props['selectedCard'] && this.props['selectedCard']['_reference'] && this.props['selectedCard']['loading']
|
||||||
|
};
|
||||||
|
classes[this.props['style']] = true;
|
||||||
|
|
||||||
|
return React.DOM.div({'key':'cardList', 'className':React.addons.classSet(classes)}, [
|
||||||
|
React.DOM.ul({}, MochiKit.Base.map(this.renderItem, cards))
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
});
|
133
frontend/delta/js/Clipperz/PM/UI/Components/Cards/Toolbar.js
Normal file
133
frontend/delta/js/Clipperz/PM/UI/Components/Cards/Toolbar.js
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
Clipperz.Base.module('Clipperz.PM.UI.Components.Cards');
|
||||||
|
|
||||||
|
Clipperz.PM.UI.Components.Cards.Toolbar = React.createClass({
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
// 'label': React.PropTypes.string.isRequired,
|
||||||
|
// 'loading': React.PropTypes.bool,
|
||||||
|
},
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
getInitialState: function() {
|
||||||
|
return {'showCommandMenu': false };
|
||||||
|
},
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
commands: function () {
|
||||||
|
return {
|
||||||
|
'delete': {
|
||||||
|
'label': "delete",
|
||||||
|
'broadcastEvent': 'deleteCard'
|
||||||
|
},
|
||||||
|
'archive': {
|
||||||
|
'label': "archive",
|
||||||
|
'broadcastEvent': 'archiveCard'
|
||||||
|
},
|
||||||
|
// 'share': {
|
||||||
|
// 'label': "share",
|
||||||
|
// 'broadcastEvent': 'shareCard'
|
||||||
|
// },
|
||||||
|
'edit': {
|
||||||
|
'label': "edit",
|
||||||
|
'broadcastEvent': 'editCard'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
exit: function (anEvent) {
|
||||||
|
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'goBackToMainPage', {'reference':this.props['_reference']});
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleMenu: function (anEvent) {
|
||||||
|
this.setState({'showCommandMenu': !this.state['showCommandMenu'] });
|
||||||
|
},
|
||||||
|
|
||||||
|
selectCommandItem: function (anEvent) {
|
||||||
|
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, anEvent.target.dataset['broadcastEvent'], {'reference':this.props['_reference']});
|
||||||
|
},
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
renderCommands: function () {
|
||||||
|
var commandHandler = this.selectCommandItem;
|
||||||
|
|
||||||
|
return React.DOM.ul({}, MochiKit.Base.map(function (aCommand) {
|
||||||
|
return React.DOM.li({}, [React.DOM.span({'onClick':commandHandler, 'data-broadcast-event':aCommand['broadcastEvent']}, aCommand['label'])]);
|
||||||
|
}, MochiKit.Base.values(this.commands())));
|
||||||
|
},
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
renderNarrow: function () {
|
||||||
|
return [
|
||||||
|
React.DOM.div({}, [
|
||||||
|
React.DOM.div({'className':'back', 'onClick': this.exit}, 'back'),
|
||||||
|
React.DOM.div({'className':'cardMenuOptions', 'onClick':this.toggleMenu}, 'commands'),
|
||||||
|
React.DOM.div({'className':React.addons.classSet({'commandMenu':true, 'show':this.state['showCommandMenu']})}, [
|
||||||
|
React.DOM.div({'className':'commandMenuMask', 'onClick':this.toggleMenu}),
|
||||||
|
React.DOM.div({'className':'commandMenu'}, this.renderCommands())
|
||||||
|
])
|
||||||
|
])
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
renderOther: function () {
|
||||||
|
return [this.renderCommands()];
|
||||||
|
},
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
renderLayout: function (aLayout) {
|
||||||
|
var result;
|
||||||
|
|
||||||
|
if (aLayout == 'narrow') {
|
||||||
|
result = this.renderNarrow();
|
||||||
|
} else {
|
||||||
|
result = this.renderOther();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
var style = this.props['style'];
|
||||||
|
var classes = {
|
||||||
|
'cardDetailToolbar': true,
|
||||||
|
};
|
||||||
|
classes[style] = true;
|
||||||
|
|
||||||
|
return React.DOM.div({'className':React.addons.classSet(classes)}, this.renderLayout(style));
|
||||||
|
},
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
});
|
161
frontend/delta/js/Clipperz/PM/UI/Components/Cards/View.js
Normal file
161
frontend/delta/js/Clipperz/PM/UI/Components/Cards/View.js
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
Clipperz.Base.module('Clipperz.PM.UI.Components.Cards');
|
||||||
|
|
||||||
|
Clipperz.PM.UI.Components.Cards.View = React.createClass({
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
'label': React.PropTypes.string.isRequired,
|
||||||
|
'loading': React.PropTypes.bool,
|
||||||
|
},
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
renderEmpty: function () {
|
||||||
|
return React.DOM.h4({}, "EMPTY");
|
||||||
|
},
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
renderLoading: function () {
|
||||||
|
return React.DOM.div({className:'loading'},[
|
||||||
|
this.renderLabel(),
|
||||||
|
React.DOM.h5({className:'message'}, "loading")
|
||||||
|
/*
|
||||||
|
React.DOM.div({className:'overlay'}, [
|
||||||
|
React.DOM.div({className:'spinner'}, [
|
||||||
|
React.DOM.div({className:'bar01'}),
|
||||||
|
React.DOM.div({className:'bar02'}),
|
||||||
|
React.DOM.div({className:'bar03'}),
|
||||||
|
React.DOM.div({className:'bar04'}),
|
||||||
|
React.DOM.div({className:'bar05'}),
|
||||||
|
React.DOM.div({className:'bar06'}),
|
||||||
|
React.DOM.div({className:'bar07'}),
|
||||||
|
React.DOM.div({className:'bar08'}),
|
||||||
|
React.DOM.div({className:'bar09'}),
|
||||||
|
React.DOM.div({className:'bar10'}),
|
||||||
|
React.DOM.div({className:'bar11'}),
|
||||||
|
React.DOM.div({className:'bar12'})
|
||||||
|
])
|
||||||
|
])
|
||||||
|
*/
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
renderLabel: function (aLabel) {
|
||||||
|
return React.DOM.h3({'className':'cardLabel'}, aLabel);
|
||||||
|
},
|
||||||
|
|
||||||
|
renderNotes: function (someNotes) {
|
||||||
|
return React.DOM.div({'className':'cardNotes'}, someNotes);
|
||||||
|
},
|
||||||
|
|
||||||
|
//............................................................................
|
||||||
|
|
||||||
|
renderTag: function (aTag) {
|
||||||
|
return React.DOM.div({'className':'cardTag'}, aTag);
|
||||||
|
},
|
||||||
|
|
||||||
|
renderTags: function (someTags) {
|
||||||
|
return React.DOM.div({'className':'cardTags'}, MochiKit.Base.map(this.renderTag, someTags));
|
||||||
|
},
|
||||||
|
|
||||||
|
//............................................................................
|
||||||
|
|
||||||
|
renderField: function (aField) {
|
||||||
|
var cardFieldClasses = {};
|
||||||
|
var cardFieldValueClasses = {};
|
||||||
|
|
||||||
|
cardFieldClasses['cardField'] = true;
|
||||||
|
cardFieldClasses[aField['actionType']] = true;
|
||||||
|
cardFieldClasses['hidden'] = aField['isHidden'];
|
||||||
|
|
||||||
|
cardFieldValueClasses['fieldValue'] = true;
|
||||||
|
cardFieldValueClasses[aField['actionType']] = true;
|
||||||
|
cardFieldValueClasses['hidden'] = aField['isHidden'];
|
||||||
|
|
||||||
|
return React.DOM.div({'className':React.addons.classSet(cardFieldClasses)}, [
|
||||||
|
React.DOM.div({'className':'fieldValues'}, [
|
||||||
|
React.DOM.div({'className':'fieldLabel'}, aField['label']),
|
||||||
|
React.DOM.div({'className':React.addons.classSet(cardFieldValueClasses)}, aField['value']),
|
||||||
|
]),
|
||||||
|
React.DOM.div({'className':'fieldAction action'}, aField['actionType'].toLowerCase())
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
|
||||||
|
renderFields: function (someFields) {
|
||||||
|
return React.DOM.div({'className':'cardFields'}, MochiKit.Base.map(this.renderField, someFields));
|
||||||
|
},
|
||||||
|
|
||||||
|
//............................................................................
|
||||||
|
|
||||||
|
renderDirectLogin: function (aDirectLogin) {
|
||||||
|
return React.DOM.div({'className':'cardDirectLogin'}, [
|
||||||
|
React.DOM.span({'className':'directLoginLabel'}, aDirectLogin['label']),
|
||||||
|
React.DOM.div({'className':'directLoginAction action'}, 'DIRECT LOGIN')
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
|
||||||
|
renderDirectLogins: function (someDirectLogins) {
|
||||||
|
return React.DOM.div({'className':'cardDirectLogins'}, MochiKit.Base.map(this.renderDirectLogin, someDirectLogins));
|
||||||
|
},
|
||||||
|
|
||||||
|
//............................................................................
|
||||||
|
|
||||||
|
renderCard: function () {
|
||||||
|
return React.DOM.div({'className':'view'},[
|
||||||
|
Clipperz.PM.UI.Components.Cards.Toolbar(this.props),
|
||||||
|
React.DOM.div({'className':'content'}, [
|
||||||
|
this.renderLabel(this.props['label']),
|
||||||
|
this.renderTags(this.props['tags']),
|
||||||
|
this.renderNotes(this.props['notes']),
|
||||||
|
this.renderFields(this.props['fields']),
|
||||||
|
this.renderDirectLogins(this.props['directLogins'])
|
||||||
|
])
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
var result;
|
||||||
|
|
||||||
|
if (this.props['loading'] == true) {
|
||||||
|
result = this.renderLoading();
|
||||||
|
} else if (this.props['label']) {
|
||||||
|
result = this.renderCard();
|
||||||
|
} else {
|
||||||
|
result = this.renderEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
});
|
@ -21,6 +21,8 @@ refer to http://www.clipperz.com.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
Clipperz.Base.module('Clipperz.PM.UI.Components');
|
||||||
|
|
||||||
Clipperz.PM.UI.Components.Checkbox = React.createClass({
|
Clipperz.PM.UI.Components.Checkbox = React.createClass({
|
||||||
// http://development.tobypitman.com/iphoneCheckboxes/iphoneCheckboxes2.html
|
// http://development.tobypitman.com/iphoneCheckboxes/iphoneCheckboxes2.html
|
||||||
|
|
||||||
|
40
frontend/delta/js/Clipperz/PM/UI/Components/ExpiredPanel.js
Normal file
40
frontend/delta/js/Clipperz/PM/UI/Components/ExpiredPanel.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
Clipperz.Base.module('Clipperz.PM.UI.Components');
|
||||||
|
|
||||||
|
Clipperz.PM.UI.Components.ExpiredPanel = React.createClass({
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
// featureSet: React.PropTypes.oneOf(['FULL', 'EXPIRED', 'TRIAL']).isRequired,
|
||||||
|
// 'level': React.PropTypes.oneOf(['hide', 'info', 'warning', 'error']).isRequired
|
||||||
|
},
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
return React.DOM.div({className:'expiredPanel'}, "EXPIRED PANEL");
|
||||||
|
},
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
});
|
47
frontend/delta/js/Clipperz/PM/UI/Components/MessageBox.js
Normal file
47
frontend/delta/js/Clipperz/PM/UI/Components/MessageBox.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
Clipperz.Base.module('Clipperz.PM.UI.Components');
|
||||||
|
|
||||||
|
Clipperz.PM.UI.Components.MessageBox = React.createClass({
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
'level': React.PropTypes.oneOf(['HIDE', 'INFO', 'WARNING', 'ERROR']).isRequired,
|
||||||
|
'message': React.PropTypes.string.isRequired
|
||||||
|
},
|
||||||
|
|
||||||
|
getDefaultProps: function () {
|
||||||
|
return {
|
||||||
|
level: 'HIDE',
|
||||||
|
message: ''
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
return React.DOM.div({className:'messageBox ' + this.props['level']}, this.props['message']);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
});
|
@ -21,13 +21,13 @@ refer to http://www.clipperz.com.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Clipperz.PM.UI.Components.PageTemplate = React.createClass({
|
Clipperz.Base.module('Clipperz.PM.UI.Components.Pages');
|
||||||
render: function() {
|
|
||||||
return React.DOM.div(null, [
|
Clipperz.PM.UI.Components.Pages.CardDetailPage = React.createClass({
|
||||||
React.DOM.div({'className': 'header'}, [
|
|
||||||
React.DOM.h1(null, "clipperz")
|
render: function () {
|
||||||
]),
|
// return React.DOM.header({'className':''})
|
||||||
React.DOM.div({'className': 'content'}, this.props.innerComponent)
|
return Clipperz.PM.UI.Components.Cards.View(this.props['selectedCard']);
|
||||||
])
|
|
||||||
}
|
},
|
||||||
});
|
});
|
@ -21,11 +21,13 @@ refer to http://www.clipperz.com.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Clipperz.PM.UI.Components.ErrorPage = React.createClass({
|
Clipperz.Base.module('Clipperz.PM.UI.Components.Pages');
|
||||||
|
|
||||||
|
Clipperz.PM.UI.Components.Pages.ErrorPage = React.createClass({
|
||||||
|
|
||||||
getDefaultProps: function () {
|
getDefaultProps: function () {
|
||||||
return {
|
return {
|
||||||
template: Clipperz.PM.UI.Components.PageTemplate
|
// template: Clipperz.PM.UI.Components.PageTemplate
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -36,11 +38,11 @@ Clipperz.PM.UI.Components.ErrorPage = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
_render: function () {
|
render: function () {
|
||||||
return React.DOM.div({className:'error-message'}, this.props.message);
|
return React.DOM.div({className:'error-message'}, this.props.message);
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function () {
|
// render: function () {
|
||||||
return new this.props.template({'innerComponent': this._render()});
|
// return new this.props.template({'innerComponent': this._render()});
|
||||||
}
|
// }
|
||||||
});
|
});
|
@ -21,24 +21,26 @@ refer to http://www.clipperz.com.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Clipperz.PM.UI.Components.LoginForm = React.createClass({
|
"use strict";
|
||||||
|
Clipperz.Base.module('Clipperz.PM.UI.Components.Pages');
|
||||||
|
|
||||||
|
Clipperz.PM.UI.Components.Pages.LoginPage = React.createClass({
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
mode: React.PropTypes.oneOf(['CREDENTIALS','PIN']).isRequired,
|
||||||
|
isNewUserRegistrationAvailable: React.PropTypes.bool.isRequired,
|
||||||
|
disabled: React.PropTypes.bool.isRequired
|
||||||
|
},
|
||||||
|
/*
|
||||||
getDefaultProps: function () {
|
getDefaultProps: function () {
|
||||||
return {
|
return {
|
||||||
mode: 'CREDENTIALS',
|
mode: 'CREDENTIALS',
|
||||||
isNewUserRegistrationAvailable: false,
|
isNewUserRegistrationAvailable: false,
|
||||||
disabled: false,
|
disabled: false,
|
||||||
template: Clipperz.PM.UI.Components.PageTemplate
|
// template: Clipperz.PM.UI.Components.PageTemplate
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
*/
|
||||||
propTypes: {
|
|
||||||
mode: React.PropTypes.oneOf(['CREDENTIALS','PIN']),
|
|
||||||
isNewUserRegistrationAvailable: React.PropTypes.bool,
|
|
||||||
disabled: React.PropTypes.bool,
|
|
||||||
template: React.PropTypes.func
|
|
||||||
},
|
|
||||||
|
|
||||||
getInitialState: function () {
|
getInitialState: function () {
|
||||||
return {
|
return {
|
||||||
username: '',
|
username: '',
|
||||||
@ -54,7 +56,7 @@ Clipperz.PM.UI.Components.LoginForm = React.createClass({
|
|||||||
var refName = MochiKit.Base.filter(function (aRefName) { return refs[aRefName].getDOMNode() == anEvent.target}, MochiKit.Base.keys(this.refs))[0];
|
var refName = MochiKit.Base.filter(function (aRefName) { return refs[aRefName].getDOMNode() == anEvent.target}, MochiKit.Base.keys(this.refs))[0];
|
||||||
var newState = {};
|
var newState = {};
|
||||||
|
|
||||||
newState[refName] = event.target.value;
|
newState[refName] = anEvent.target.value;
|
||||||
this.setState(newState);
|
this.setState(newState);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -86,25 +88,21 @@ Clipperz.PM.UI.Components.LoginForm = React.createClass({
|
|||||||
((this.state['username'] != '') && (this.state['passphrase'] != ''))
|
((this.state['username'] != '') && (this.state['passphrase'] != ''))
|
||||||
||
|
||
|
||||||
(this.state['pin'] != '')
|
(this.state['pin'] != '')
|
||||||
) && !this.props['disabled'];
|
)
|
||||||
|
&&
|
||||||
|
!this.props['disabled'];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
loginForm: function () {
|
loginForm: function () {
|
||||||
registrationLink = React.DOM.div({'className':'registrationLink'}, [
|
return React.DOM.form({'className':'loginForm credentials', 'onChange':this.handleChange, 'onSubmit':this.handleCredentialSubmit}, [
|
||||||
React.DOM.a({'onClick':this.handleRegistrationLinkClick}, "Sign up")
|
React.DOM.div(null,[
|
||||||
]);
|
React.DOM.label({'htmlFor' :'name'}, "username"),
|
||||||
return React.DOM.div({'className':'loginForm credentials'},[
|
React.DOM.input({'type':'text', 'name':'name', 'ref':'username', 'placeholder':"username", 'key':'username', 'autoCapitalize':'none'}),
|
||||||
React.DOM.form({onChange: this.handleChange, onSubmit:this.handleCredentialSubmit}, [
|
React.DOM.label({'htmlFor' :'passphrase'}, "passphrase"),
|
||||||
React.DOM.div(null,[
|
React.DOM.input({'type':'password', 'name':'passphrase', 'ref':'passphrase', 'placeholder':"passphrase", 'key':'passphrase'})
|
||||||
React.DOM.label({'for' :'name'}, "username"),
|
|
||||||
React.DOM.input({'type':'text', 'name':'name', 'ref':'username', 'placeholder':"username", 'key':'username', 'autoCapitalize':'none'}),
|
|
||||||
React.DOM.label({'for' :'passphrase'}, "passphrase"),
|
|
||||||
React.DOM.input({'type':'password', 'name':'passphrase', 'ref':'passphrase', 'placeholder':"passphrase", 'key':'passphrase'})
|
|
||||||
]),
|
|
||||||
React.DOM.button({'type':'submit', 'disabled':!this.shouldEnableLoginButton(), 'className':'button'}, "login")
|
|
||||||
]),
|
]),
|
||||||
this.props.isNewUserRegistrationAvailable ? registrationLink : null
|
React.DOM.button({'type':'submit', 'disabled':!this.shouldEnableLoginButton(), 'className':'button'}, "login")
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -121,14 +119,12 @@ Clipperz.PM.UI.Components.LoginForm = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
pinForm: function () {
|
pinForm: function () {
|
||||||
return React.DOM.div({'className':'loginForm pin'},[
|
return React.DOM.form({'className':'loginForm pin', 'onChange':this.handleChange, 'onSubmit':this.handlePINSubmit}, [
|
||||||
React.DOM.form({onChange: this.handleChange, onSubmit:this.handlePINSubmit}, [
|
React.DOM.div(null,[
|
||||||
React.DOM.div(null,[
|
React.DOM.label({'for':'pin'}, "pin"),
|
||||||
React.DOM.label({'for':'pin'}, "pin"),
|
React.DOM.input({'type':'text', 'name':'pin', 'ref':'pin', placeholder:"PIN", 'key':'pin', 'autocapitalize':'none'})
|
||||||
React.DOM.input({'type':'text', 'name':'pin', 'ref':'pin', placeholder:"PIN", 'key':'pin', 'autocapitalize':'none'})
|
]),
|
||||||
]),
|
React.DOM.button({'type':'submit', 'disabled':this.props.disabled, 'className':'button'}, "login")
|
||||||
React.DOM.button({'type':'submit', 'disabled':this.props.disabled, 'className':'button'}, "login")
|
|
||||||
])
|
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -145,6 +141,16 @@ Clipperz.PM.UI.Components.LoginForm = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
return new this.props.template({'innerComponent': this.props.mode == 'PIN' ? this.pinForm() : this.loginForm()});
|
var registrationLink = React.DOM.div({'className':'registrationLink'}, [
|
||||||
|
React.DOM.a({'onClick':this.handleRegistrationLinkClick}, "Sign up")
|
||||||
|
]);
|
||||||
|
|
||||||
|
return React.DOM.div({'className':'loginForm ' + this.props['style']}, [
|
||||||
|
React.DOM.header({}, 'clipperz'),
|
||||||
|
React.DOM.div({'className':'form'}, [
|
||||||
|
this.props.mode == 'PIN' ? this.pinForm() : this.loginForm(),
|
||||||
|
]),
|
||||||
|
this.props.isNewUserRegistrationAvailable ? registrationLink : null
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
});
|
});
|
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
Clipperz.Base.module('Clipperz.PM.UI.Components.Pages');
|
||||||
|
|
||||||
|
Clipperz.PM.UI.Components.Pages.MainPage = React.createClass({
|
||||||
|
|
||||||
|
getDefaultProps: function () {
|
||||||
|
return {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
'messageBox': React.PropTypes.object.isRequired,
|
||||||
|
// 'featureSet': React.PropTypes.oneOf(['FULL', 'EXPIRED', 'TRIAL']),
|
||||||
|
'accountStatus': React.PropTypes.object.isRequired,
|
||||||
|
// 'mediaQueryStyle': React.PropTypes.oneOf(['extra-short', 'narrow', 'wide', 'extra-wide']).isRequired,
|
||||||
|
'style': React.PropTypes.oneOf(Clipperz_PM_UI_availableStyles).isRequired,
|
||||||
|
// 'cards': React.PropTypes.deferred.isRequired
|
||||||
|
},
|
||||||
|
|
||||||
|
getInitialState: function () {
|
||||||
|
return {
|
||||||
|
// shouldStoreDataLocally: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
var classes = {
|
||||||
|
'mainPage': true
|
||||||
|
};
|
||||||
|
classes[this.props['style']] = true;
|
||||||
|
//console.log("MainPage.cards", this.props['cards'], this.props['cards'].state());
|
||||||
|
|
||||||
|
return React.DOM.div({className:React.addons.classSet(classes)}, [
|
||||||
|
this.props['style'] != 'extra-wide' ? Clipperz.PM.UI.Components.Panels.SelectionPanel(this.props) : null,
|
||||||
|
Clipperz.PM.UI.Components.Panels.MainPanel(this.props),
|
||||||
|
Clipperz.PM.UI.Components.Panels.ExtraFeaturesPanel(this.props)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
});
|
@ -21,7 +21,9 @@ refer to http://www.clipperz.com.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Clipperz.PM.UI.Components.RegistrationWizard = React.createClass({
|
Clipperz.Base.module('Clipperz.PM.UI.Components.Pages');
|
||||||
|
|
||||||
|
Clipperz.PM.UI.Components.Pages.RegistrationPage = React.createClass({
|
||||||
|
|
||||||
getDefaultProps: function () {
|
getDefaultProps: function () {
|
||||||
return {
|
return {
|
||||||
@ -31,7 +33,7 @@ Clipperz.PM.UI.Components.RegistrationWizard = React.createClass({
|
|||||||
{name:'TERMS_OF_SERVICE', label:'registration', _label:'terms', description:"Check our terms of service"}
|
{name:'TERMS_OF_SERVICE', label:'registration', _label:'terms', description:"Check our terms of service"}
|
||||||
],
|
],
|
||||||
disabled: false,
|
disabled: false,
|
||||||
template: Clipperz.PM.UI.Components.PageTemplate
|
// template: Clipperz.PM.UI.Components.PageTemplate
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -166,16 +168,16 @@ Clipperz.PM.UI.Components.RegistrationWizard = React.createClass({
|
|||||||
|
|
||||||
render_CREDENTIALS: function () {
|
render_CREDENTIALS: function () {
|
||||||
return React.DOM.div(null,[
|
return React.DOM.div(null,[
|
||||||
React.DOM.label({'for':'name'}, "username"),
|
React.DOM.label({'htmlFor':'name'}, "username"),
|
||||||
React.DOM.input({'type':'text', 'name':'name', 'ref':'username', 'placeholder':"username", 'key':'username', 'autoCapitalize':'none'/*, value:this.state.username*/}),
|
React.DOM.input({'type':'text', 'name':'name', 'ref':'username', 'placeholder':"username", 'key':'username', 'autoCapitalize':'none'/*, value:this.state.username*/}),
|
||||||
React.DOM.label({'for':'passphrase'}, "passphrase"),
|
React.DOM.label({'htmlFor':'passphrase'}, "passphrase"),
|
||||||
React.DOM.input({'type':'password', 'name':'passphrase', 'ref':'passphrase', 'placeholder':"passphrase", 'key':'passphrase'/*, value:this.state.passphrase*/})
|
React.DOM.input({'type':'password', 'name':'passphrase', 'ref':'passphrase', 'placeholder':"passphrase", 'key':'passphrase'/*, value:this.state.passphrase*/})
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
render_PASSWORD_VERIFICATION: function () {
|
render_PASSWORD_VERIFICATION: function () {
|
||||||
return React.DOM.div(null,[
|
return React.DOM.div(null,[
|
||||||
React.DOM.label({'for':'verify_passphrase'}, "passphrase"),
|
React.DOM.label({'htmlFor':'verify_passphrase'}, "passphrase"),
|
||||||
React.DOM.input({'type':'password', 'name':'verify_passphrase', 'ref':'verify_passphrase', 'placeholder':"verify passphrase", 'key':'verify_passphrase'})
|
React.DOM.input({'type':'password', 'name':'verify_passphrase', 'ref':'verify_passphrase', 'placeholder':"verify passphrase", 'key':'verify_passphrase'})
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
@ -183,12 +185,12 @@ Clipperz.PM.UI.Components.RegistrationWizard = React.createClass({
|
|||||||
render_TERMS_OF_SERVICE: function () {
|
render_TERMS_OF_SERVICE: function () {
|
||||||
return React.DOM.div(null, [
|
return React.DOM.div(null, [
|
||||||
React.DOM.div({className:'checkboxBlock'}, [
|
React.DOM.div({className:'checkboxBlock'}, [
|
||||||
React.DOM.label({'for':'no_password_recovery'}, "I understand that Clipperz will not be able to recover a lost passphrase."),
|
React.DOM.label({'htmlFor':'no_password_recovery'}, "I understand that Clipperz will not be able to recover a lost passphrase."),
|
||||||
React.DOM.input({'type':'checkbox', 'name':'no_password_recovery', 'ref':'no_password_recovery', 'key':'no_password_recovery'}),
|
React.DOM.input({'type':'checkbox', 'name':'no_password_recovery', 'ref':'no_password_recovery', 'key':'no_password_recovery'}),
|
||||||
React.DOM.p(null, "I understand that Clipperz will not be able to recover a lost passphrase.")
|
React.DOM.p(null, "I understand that Clipperz will not be able to recover a lost passphrase.")
|
||||||
]),
|
]),
|
||||||
React.DOM.div({className:'checkboxBlock'}, [
|
React.DOM.div({className:'checkboxBlock'}, [
|
||||||
React.DOM.label({'for':'agree_terms_of_service'}, "I have read and agreed to the Terms of Service."),
|
React.DOM.label({'htmlFor':'agree_terms_of_service'}, "I have read and agreed to the Terms of Service."),
|
||||||
React.DOM.input({'type':'checkbox', 'name':'agree_terms_of_service', 'ref':'agree_terms_of_service', 'key':'agree_terms_of_service'}),
|
React.DOM.input({'type':'checkbox', 'name':'agree_terms_of_service', 'ref':'agree_terms_of_service', 'key':'agree_terms_of_service'}),
|
||||||
React.DOM.p(null, [
|
React.DOM.p(null, [
|
||||||
"I have read and agreed to the ",
|
"I have read and agreed to the ",
|
||||||
@ -208,7 +210,7 @@ Clipperz.PM.UI.Components.RegistrationWizard = React.createClass({
|
|||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
_render: function () {
|
render: function () {
|
||||||
return React.DOM.div({'className':'registrationForm'},[
|
return React.DOM.div({'className':'registrationForm'},[
|
||||||
React.DOM.form({onChange: this.handleChange}, [
|
React.DOM.form({onChange: this.handleChange}, [
|
||||||
React.DOM.div({'className':'steps'}, MochiKit.Base.map(this.renderStep, this.props['steps']))
|
React.DOM.div({'className':'steps'}, MochiKit.Base.map(this.renderStep, this.props['steps']))
|
||||||
@ -216,9 +218,9 @@ Clipperz.PM.UI.Components.RegistrationWizard = React.createClass({
|
|||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function () {
|
// render: function () {
|
||||||
return new this.props.template({'innerComponent': this._render()});
|
// return new this.props.template({'innerComponent': this._render()});
|
||||||
},
|
// },
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
Clipperz.Base.module('Clipperz.PM.UI.Components.Panels');
|
||||||
|
|
||||||
|
Clipperz.PM.UI.Components.Panels.ExtraFeaturesPanel = React.createClass({
|
||||||
|
|
||||||
|
settingsToggleHandler: function (anEvent) {
|
||||||
|
//console.log("settingsToggleHandler");
|
||||||
|
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'toggleSettingsPanel');
|
||||||
|
},
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
var classes = {
|
||||||
|
'panel': true,
|
||||||
|
'right': true,
|
||||||
|
'open': this.props['settingsPanelStatus'] == 'OPEN'
|
||||||
|
}
|
||||||
|
|
||||||
|
return React.DOM.div({key:'extraFeaturesPanel', id:'extraFeaturesPanel', className:React.addons.classSet(classes)}, [
|
||||||
|
React.DOM.header({}, [
|
||||||
|
React.DOM.div({className:'settingsToggle'}, [
|
||||||
|
Clipperz.PM.UI.Components.Button({eventName:'settingsToggleButton', label:"menu", handler:this.settingsToggleHandler})
|
||||||
|
])
|
||||||
|
]),
|
||||||
|
React.DOM.h2({}, "Extra features")
|
||||||
|
]);
|
||||||
|
/*
|
||||||
|
<div id="extraFeaturesPanel" class="panel extraFeatures">
|
||||||
|
|
||||||
|
<div class="warnings">
|
||||||
|
<ul>
|
||||||
|
<li>Synchronize local data</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Account</li>
|
||||||
|
<li>Subscription</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Local Data</li>
|
||||||
|
<li>OTP</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="donation">
|
||||||
|
<a>Make a donation</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
});
|
193
frontend/delta/js/Clipperz/PM/UI/Components/Panels/MainPanel.js
Normal file
193
frontend/delta/js/Clipperz/PM/UI/Components/Panels/MainPanel.js
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
Clipperz.Base.module('Clipperz.PM.UI.Components.Panels');
|
||||||
|
|
||||||
|
Clipperz.PM.UI.Components.Panels.MainPanel = React.createClass({
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
'messageBox': React.PropTypes.object.isRequired,
|
||||||
|
'featureSet': React.PropTypes.oneOf(['FULL', 'EXPIRED', 'TRIAL']).isRequired,
|
||||||
|
'style': React.PropTypes.oneOf(Clipperz_PM_UI_availableStyles).isRequired,
|
||||||
|
},
|
||||||
|
|
||||||
|
getDefaultProps: function () {
|
||||||
|
return {
|
||||||
|
featureSet: 'FULL'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
style: function () {
|
||||||
|
return this.props['style'];
|
||||||
|
},
|
||||||
|
|
||||||
|
featureSet: function () {
|
||||||
|
return this.props['featureSet'];
|
||||||
|
},
|
||||||
|
|
||||||
|
handleMaskClick: function () {
|
||||||
|
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'maskClick');
|
||||||
|
},
|
||||||
|
|
||||||
|
handleAddCardClick: function () {
|
||||||
|
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'addCardClick');
|
||||||
|
},
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
renderToolbarFrame: function (anInnerComponent) {
|
||||||
|
return React.DOM.div({'className':'cardToolbarFrame'}, [
|
||||||
|
this.renderToolbar(),
|
||||||
|
anInnerComponent
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
|
||||||
|
renderCardFrame: function (firstColumnComponents, secondColumnComponents) {
|
||||||
|
var addCardButton = React.DOM.div({'className': 'addCardButton', 'onClick':this.handleAddCardClick}, 'add card');
|
||||||
|
|
||||||
|
return React.DOM.div({'key':'cardContent', 'className':'cardContent'}, [
|
||||||
|
React.DOM.div({'className':'cardListColumn column'}, [addCardButton, firstColumnComponents]),
|
||||||
|
React.DOM.div({'className':'cardDetail column right'}, secondColumnComponents)
|
||||||
|
])
|
||||||
|
},
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
renderToolbar: function () {
|
||||||
|
var cardToolbarProps;
|
||||||
|
|
||||||
|
cardToolbarProps = MochiKit.Base.merge(this.props, {
|
||||||
|
'key': 'toolbar',
|
||||||
|
'style': this.style(),
|
||||||
|
'enableSidePanels': (this.props['featureSet'] != 'EXPIRED')
|
||||||
|
});
|
||||||
|
|
||||||
|
return Clipperz.PM.UI.Components.CardToolbar(cardToolbarProps);
|
||||||
|
},
|
||||||
|
|
||||||
|
renderExpiredPanel: function () {
|
||||||
|
return this.featureSet() == 'EXPIRED' ? Clipperz.PM.UI.Components.ExpiredPanel(this.props) : null;
|
||||||
|
},
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
viewComponentProps: function () {
|
||||||
|
var result;
|
||||||
|
|
||||||
|
result = this.props['selectedCard'];
|
||||||
|
if (result) {
|
||||||
|
result['style'] = this.props['style'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
renderExtraWide: function () {
|
||||||
|
return [
|
||||||
|
React.DOM.div({'className':'selection subpanel'}, [Clipperz.PM.UI.Components.Selections(this.props)]),
|
||||||
|
React.DOM.div({'className':'cardContent subpanel'}, [
|
||||||
|
this.renderToolbarFrame(
|
||||||
|
this.renderCardFrame(
|
||||||
|
[Clipperz.PM.UI.Components.Cards.List(this.props)],
|
||||||
|
[
|
||||||
|
this.renderExpiredPanel(),
|
||||||
|
Clipperz.PM.UI.Components.Cards.View(this.viewComponentProps())
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
])
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
renderWide: function () {
|
||||||
|
return [
|
||||||
|
this.renderToolbarFrame(
|
||||||
|
this.renderCardFrame(
|
||||||
|
[Clipperz.PM.UI.Components.Cards.List(this.props)],
|
||||||
|
[
|
||||||
|
this.renderExpiredPanel(),
|
||||||
|
Clipperz.PM.UI.Components.Cards.View(this.viewComponentProps())
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
];
|
||||||
|
},
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
renderNarrow: function () {
|
||||||
|
return this.renderCardFrame(
|
||||||
|
this.renderToolbarFrame([
|
||||||
|
this.renderExpiredPanel(),
|
||||||
|
Clipperz.PM.UI.Components.Cards.List(this.props),
|
||||||
|
]),
|
||||||
|
[Clipperz.PM.UI.Components.Cards.View(this.viewComponentProps())]
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
renderLayout: function (aLayout) {
|
||||||
|
var result;
|
||||||
|
|
||||||
|
if (aLayout == 'extra-wide') {
|
||||||
|
result = this.renderExtraWide();
|
||||||
|
} else if (aLayout == 'wide') {
|
||||||
|
result = this.renderWide();
|
||||||
|
} else if (aLayout == 'narrow') {
|
||||||
|
result = this.renderNarrow();
|
||||||
|
} else if (aLayout == 'extra-short') {
|
||||||
|
result = this.renderNarrow();
|
||||||
|
} else {
|
||||||
|
Clipperz.Base.exception.raise('UnknownType');
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
//console.log("MainPanel.cards", this.props['cards']);
|
||||||
|
var classes = {
|
||||||
|
'panel': true,
|
||||||
|
'left': this.props['selectionPanelStatus'] == 'OPEN',
|
||||||
|
'right': this.props['settingsPanelStatus'] == 'OPEN',
|
||||||
|
'open': this.props['selectionPanelStatus'] == 'OPEN' || this.props['settingsPanelStatus'] == 'OPEN'
|
||||||
|
};
|
||||||
|
classes[this.style()] = true;
|
||||||
|
|
||||||
|
return React.DOM.div({'key':'mainPanel', 'id':'mainPanel', 'className':React.addons.classSet(classes)}, [
|
||||||
|
React.DOM.div({'className':'mask', 'onClick': this.handleMaskClick}),
|
||||||
|
React.DOM.div({'className':'container'},
|
||||||
|
// this.style() == 'extra-wide' ? this.renderExtraWide() : this.renderOther()
|
||||||
|
this.renderLayout(this.style())
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
});
|
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
Clipperz.Base.module('Clipperz.PM.UI.Components.Panels');
|
||||||
|
|
||||||
|
Clipperz.PM.UI.Components.Panels.SelectionPanel = React.createClass({
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
selectionPanelStatus: React.PropTypes.oneOf(['OPEN', 'CLOSED']).isRequired
|
||||||
|
},
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
//console.log("SelectionPanel", this.props);
|
||||||
|
var classes = React.addons.classSet({
|
||||||
|
'panel': true,
|
||||||
|
'left': true,
|
||||||
|
'open': this.props['selectionPanelStatus'] == 'OPEN'
|
||||||
|
});
|
||||||
|
|
||||||
|
return React.DOM.div({'key':'selectionPanel', 'id':'selectionPanel', 'className':classes}, [
|
||||||
|
Clipperz.PM.UI.Components.Selections(this.props),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
});
|
@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Copyright 2008-2013 Clipperz Srl
|
|
||||||
|
|
||||||
This file is part of Clipperz, the online password manager.
|
|
||||||
For further information about its features and functionalities please
|
|
||||||
refer to http://www.clipperz.com.
|
|
||||||
|
|
||||||
* Clipperz is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU Affero General Public License as published
|
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
* Clipperz is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
* You should have received a copy of the GNU Affero General Public
|
|
||||||
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
Clipperz.PM.UI.Components.PreferencePage = React.createClass({
|
|
||||||
|
|
||||||
getDefaultProps: function () {
|
|
||||||
return {
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
propTypes: {
|
|
||||||
// card: React.PropTypes.object.isRequired
|
|
||||||
// checked: React.PropTypes.boolean.isRequired
|
|
||||||
},
|
|
||||||
|
|
||||||
getInitialState: function () {
|
|
||||||
// return {
|
|
||||||
// shouldStoreDataLocally: false
|
|
||||||
// };
|
|
||||||
},
|
|
||||||
|
|
||||||
handleBackClick: function (anEvent) {
|
|
||||||
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'goBack');
|
|
||||||
},
|
|
||||||
|
|
||||||
toggleShouldStoreDataLocally: function (anEvent) {
|
|
||||||
// this.setState({shouldStoreDataLocally: !this.state['shouldStoreDataLocally']});
|
|
||||||
Clipperz.PM.DataModel.devicePreferences.setShouldStoreDataLocally(!Clipperz.PM.DataModel.devicePreferences.shouldStoreDataLocally());
|
|
||||||
this.setState({});
|
|
||||||
},
|
|
||||||
|
|
||||||
shouldStoreDataLocally: function () {
|
|
||||||
return Clipperz.PM.DataModel.devicePreferences.shouldStoreDataLocally();
|
|
||||||
},
|
|
||||||
|
|
||||||
syncNow: function (anEvent) {
|
|
||||||
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'synchronizeLocalData');
|
|
||||||
},
|
|
||||||
|
|
||||||
//=========================================================================
|
|
||||||
|
|
||||||
render: function () {
|
|
||||||
return React.DOM.div({className:'preferences'}, [
|
|
||||||
React.DOM.div({className:'header'}, [
|
|
||||||
React.DOM.div({className:'titleWrapper'}, React.DOM.div({className:'title'}, "Preferences")),
|
|
||||||
React.DOM.div({className:'backWrapper'}, React.DOM.a({className:'button back', onClick:this.handleBackClick}, "back")),
|
|
||||||
]),
|
|
||||||
React.DOM.div({className:'content'}, [
|
|
||||||
React.DOM.form(null, [
|
|
||||||
React.DOM.div({className:'section'}, [
|
|
||||||
React.DOM.h4(null, "Local storage"),
|
|
||||||
React.DOM.p(null, "Store you account data locally for offline viewing"),
|
|
||||||
new Clipperz.PM.UI.Components.Checkbox({'id':'shouldStoreLocally_checkbox', 'checked':this.shouldStoreDataLocally(), 'eventHandler':this.toggleShouldStoreDataLocally}),
|
|
||||||
this.shouldStoreDataLocally() ? React.DOM.div({className:'syncInfo'}, [
|
|
||||||
// React.DOM.h5(null, "data were never synchronized before"),
|
|
||||||
React.DOM.a({className:'button', onClick:this.syncNow}, "Sync now")
|
|
||||||
]) : null
|
|
||||||
])
|
|
||||||
])
|
|
||||||
]),
|
|
||||||
React.DOM.div({className:'footer'}, [
|
|
||||||
|
|
||||||
])
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//=========================================================================
|
|
||||||
});
|
|
57
frontend/delta/js/Clipperz/PM/UI/Components/Selections.js
Normal file
57
frontend/delta/js/Clipperz/PM/UI/Components/Selections.js
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
Clipperz.Base.module('Clipperz.PM.UI.Components');
|
||||||
|
|
||||||
|
Clipperz.PM.UI.Components.Selections = React.createClass({
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
|
||||||
|
selectAll: function (anEvent) {
|
||||||
|
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'selectAllCards');
|
||||||
|
},
|
||||||
|
|
||||||
|
selectRecent: function (anEvent) {
|
||||||
|
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'selectRecentCards');
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
//console.log("Selections", this.props);
|
||||||
|
return React.DOM.div({'key':'selections', 'id':'selections'}, [
|
||||||
|
React.DOM.ul({'className':'defaultSet'}, [
|
||||||
|
React.DOM.li({'className':'allCards', onClick: this.selectAll}, "All"),
|
||||||
|
React.DOM.li({'className':'recentCards', onClick: this.selectRecent}, "Recent")
|
||||||
|
]),
|
||||||
|
React.DOM.div({'className':'search'}, [
|
||||||
|
React.DOM.form({'className':'searchForm'}, [
|
||||||
|
React.DOM.label({'htmlFor':'searchValue'}, 'search'),
|
||||||
|
React.DOM.input({'type':'text', 'id':'searchValue', 'name':'search'})
|
||||||
|
])
|
||||||
|
]),
|
||||||
|
React.DOM.ul({'className':'tagList'}, MochiKit.Base.map(function (aTag) { return Clipperz.PM.UI.Components.TagIndexItem({'label':aTag}); }, this.props['tags'] ? this.props['tags'] : []))
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
});
|
45
frontend/delta/js/Clipperz/PM/UI/Components/TagIndexItem.js
Normal file
45
frontend/delta/js/Clipperz/PM/UI/Components/TagIndexItem.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
Clipperz.Base.module('Clipperz.PM.UI.Components');
|
||||||
|
|
||||||
|
Clipperz.PM.UI.Components.TagIndexItem = React.createClass({
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
'label': React.PropTypes.string.isRequired,
|
||||||
|
},
|
||||||
|
|
||||||
|
handleClick: function (anEvent) {
|
||||||
|
//console.log("TAG INDEX ITEM - handle click TAG", anEvent.target.dataset.tag);
|
||||||
|
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'tagSelected', anEvent.target.dataset.tag);
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
return React.DOM.li({onClick: this.handleClick, 'data-tag':this.props['label']}, this.props['label']);
|
||||||
|
},
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
});
|
@ -23,17 +23,17 @@ refer to http://www.clipperz.com.
|
|||||||
|
|
||||||
Clipperz.Base.module('Clipperz.PM.UI');
|
Clipperz.Base.module('Clipperz.PM.UI');
|
||||||
|
|
||||||
Clipperz.PM.UI.DirectLoginRunner = function(args) {
|
Clipperz.PM.UI.DirectLoginController = function(args) {
|
||||||
this._directLogin = args['directLogin'] || Clipperz.Base.exception.raise('MandatoryParameter');
|
this._directLogin = args['directLogin'] || Clipperz.Base.exception.raise('MandatoryParameter');
|
||||||
this._target = Clipperz.PM.Crypto.randomKey();
|
this._target = Clipperz.PM.Crypto.randomKey();
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
MochiKit.Base.update(Clipperz.PM.UI.DirectLoginRunner.prototype, {
|
MochiKit.Base.update(Clipperz.PM.UI.DirectLoginController.prototype, {
|
||||||
|
|
||||||
'toString': function() {
|
'toString': function() {
|
||||||
return "Clipperz.PM.UI.DirectLoginRunner";
|
return "Clipperz.PM.UI.DirectLoginController";
|
||||||
},
|
},
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -237,19 +237,19 @@ MochiKit.Base.update(Clipperz.PM.UI.DirectLoginRunner.prototype, {
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
Clipperz.PM.UI.DirectLoginRunner.openDirectLogin = function (aDirectLogin) {
|
Clipperz.PM.UI.DirectLoginController.openDirectLogin = function (aDirectLogin) {
|
||||||
var runner;
|
var runner;
|
||||||
|
|
||||||
runner = new Clipperz.PM.UI.DirectLoginRunner({directLogin:aDirectLogin});
|
runner = new Clipperz.PM.UI.DirectLoginController({directLogin:aDirectLogin});
|
||||||
return runner.run();
|
return runner.run();
|
||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
Clipperz.PM.UI.DirectLoginRunner.testDirectLogin = function (aDirectLogin) {
|
Clipperz.PM.UI.DirectLoginController.testDirectLogin = function (aDirectLogin) {
|
||||||
var runner;
|
var runner;
|
||||||
|
|
||||||
runner = new Clipperz.PM.UI.DirectLoginRunner({directLogin:aDirectLogin});
|
runner = new Clipperz.PM.UI.DirectLoginController({directLogin:aDirectLogin});
|
||||||
return runner.test();
|
return runner.test();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,31 +21,65 @@ refer to http://www.clipperz.com.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
Clipperz.Base.module('Clipperz.PM.UI');
|
Clipperz.Base.module('Clipperz.PM.UI');
|
||||||
|
|
||||||
Clipperz.PM.UI.MainController = function() {
|
Clipperz.PM.UI.MainController = function() {
|
||||||
var pages;
|
var genericPageProperties;
|
||||||
|
|
||||||
// this._proxy = null;
|
// this._proxy = null;
|
||||||
|
this._mediaQueryStyle = "narrow";
|
||||||
this._user = null;
|
this._user = null;
|
||||||
this._filter = '';
|
this._filter = {'type':'ALL'};
|
||||||
|
|
||||||
// this._currentPage = 'loadingPage';
|
this._isSelectionPanelOpen = false;
|
||||||
|
this._isSettingsPanelOpen = false;
|
||||||
|
|
||||||
this._pageStack = ['loadingPage'];
|
this._pageStack = ['loadingPage'];
|
||||||
this._overlay = new Clipperz.PM.UI.Components.Overlay();
|
this._overlay = new Clipperz.PM.UI.Components.Overlay();
|
||||||
pages = {
|
|
||||||
'loginPage': new Clipperz.PM.UI.Components.LoginForm(),
|
|
||||||
'registrationPage': new Clipperz.PM.UI.Components.RegistrationWizard(),
|
|
||||||
'cardListPage': new Clipperz.PM.UI.Components.CardList(),
|
|
||||||
'cardDetailPage': new Clipperz.PM.UI.Components.CardDetail({card: {}}),
|
|
||||||
'preferencePage': new Clipperz.PM.UI.Components.PreferencePage(),
|
|
||||||
'errorPage': new Clipperz.PM.UI.Components.ErrorPage({message:''})
|
|
||||||
};
|
|
||||||
|
|
||||||
MochiKit.Base.map(function (anId) {React.renderComponent(pages[anId], MochiKit.DOM.getElement(anId))}, MochiKit.Base.keys(pages));
|
this._isTouchDevice = ('ontouchstart' in window || 'onmsgesturechange' in window);
|
||||||
this._pages = pages;
|
this._isDesktop = window.screenX != 0 && !this._isTouchDevice;
|
||||||
this.registerForNotificationCenterEvents();
|
this._hasKeyboard = this._isDesktop;
|
||||||
|
|
||||||
|
this._closeMaskAction = null;
|
||||||
|
|
||||||
|
this._pages = {};
|
||||||
|
this.renderPages([
|
||||||
|
'loginPage',
|
||||||
|
'registrationPage',
|
||||||
|
'mainPage',
|
||||||
|
'cardDetailPage',
|
||||||
|
'errorPage',
|
||||||
|
]);
|
||||||
|
|
||||||
|
this.registerForNotificationCenterEvents([
|
||||||
|
'doLogin',
|
||||||
|
'registerNewUser',
|
||||||
|
'showRegistrationForm',
|
||||||
|
'goBack',
|
||||||
|
|
||||||
|
'toggleSelectionPanel',
|
||||||
|
'toggleSettingsPanel',
|
||||||
|
|
||||||
|
'matchMediaQuery',
|
||||||
|
'unmatchMediaQuery',
|
||||||
|
|
||||||
|
'selectAllCards',
|
||||||
|
'selectRecentCards',
|
||||||
|
'tagSelected',
|
||||||
|
|
||||||
|
'cardSelected',
|
||||||
|
|
||||||
|
'addCardClick',
|
||||||
|
'deleteCard',
|
||||||
|
'archiveCard',
|
||||||
|
'editCard',
|
||||||
|
|
||||||
|
'goBackToMainPage',
|
||||||
|
'maskClick',
|
||||||
|
]);
|
||||||
|
|
||||||
MochiKit.Signal.connect(MochiKit.DOM.currentDocument(), 'onselectionchange', this, 'selectionChangeHandler');
|
MochiKit.Signal.connect(MochiKit.DOM.currentDocument(), 'onselectionchange', this, 'selectionChangeHandler');
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
@ -125,26 +159,30 @@ console.log("THE BROWSER IS OFFLINE");
|
|||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
||||||
registerForNotificationCenterEvents: function () {
|
capitaliseFirstLetter: function (aValue) {
|
||||||
var events = [
|
return aValue.charAt(0).toUpperCase() + aValue.slice(1);
|
||||||
'doLogin',
|
},
|
||||||
'registerNewUser',
|
|
||||||
'showRegistrationForm',
|
|
||||||
'goBack',
|
|
||||||
'showRecord',
|
|
||||||
'searchCards',
|
|
||||||
'showPreferences',
|
|
||||||
'runDirectLogin',
|
|
||||||
'synchronizeLocalData'
|
|
||||||
];
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
MochiKit.Base.map(function (anEvent) {
|
renderPages: function (pages) {
|
||||||
MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, anEvent, MochiKit.Base.method(self, anEvent));
|
var self = this;
|
||||||
}, events);
|
MochiKit.Iter.forEach(pages, function (aPageName) {
|
||||||
|
//console.log("RENDERING", aPageName);
|
||||||
|
self._pages[aPageName] = React.renderComponent(
|
||||||
|
Clipperz.PM.UI.Components.Pages[self.capitaliseFirstLetter(aPageName)](self.pageProperties(aPageName)),
|
||||||
|
MochiKit.DOM.getElement(aPageName)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
registerForNotificationCenterEvents: function (events) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
MochiKit.Iter.forEach(events, function (anEvent) {
|
||||||
|
MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, anEvent, MochiKit.Base.method(self, anEvent + '_handler'));
|
||||||
|
});
|
||||||
|
|
||||||
// MochiKit.Signal.connect(window, 'onpopstate', MochiKit.Base.method(this, 'historyGoBack'));
|
// MochiKit.Signal.connect(window, 'onpopstate', MochiKit.Base.method(this, 'historyGoBack'));
|
||||||
MochiKit.Signal.connect(window, 'onbeforeunload', MochiKit.Base.method(this, 'shouldExitApp'));
|
// MochiKit.Signal.connect(window, 'onbeforeunload', MochiKit.Base.method(this, 'shouldExitApp'));
|
||||||
},
|
},
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
@ -198,11 +236,13 @@ console.log("THE BROWSER IS OFFLINE");
|
|||||||
this.pages()['loginPage'].setProps({'mode':this.loginMode(), 'isNewUserRegistrationAvailable':canRegisterNewUsers});
|
this.pages()['loginPage'].setProps({'mode':this.loginMode(), 'isNewUserRegistrationAvailable':canRegisterNewUsers});
|
||||||
|
|
||||||
if (shouldShowRegistrationForm) {
|
if (shouldShowRegistrationForm) {
|
||||||
this.showRegistrationForm();
|
this.showRegistrationForm_handler();
|
||||||
} else {
|
} else {
|
||||||
this.showLoginForm();
|
this.showLoginForm();
|
||||||
}
|
}
|
||||||
this.overlay().done("", 0.5);
|
|
||||||
|
// this.overlay().done("", 0.5);
|
||||||
|
this.overlay().hide();
|
||||||
},
|
},
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
@ -216,7 +256,7 @@ console.log("THE BROWSER IS OFFLINE");
|
|||||||
MochiKit.Async.callLater(0.5, MochiKit.Base.method(loginFormPage, 'setInitialFocus'));
|
MochiKit.Async.callLater(0.5, MochiKit.Base.method(loginFormPage, 'setInitialFocus'));
|
||||||
},
|
},
|
||||||
|
|
||||||
showRegistrationForm: function () {
|
showRegistrationForm_handler: function () {
|
||||||
var currentPage;
|
var currentPage;
|
||||||
var registrationPage;
|
var registrationPage;
|
||||||
|
|
||||||
@ -230,7 +270,12 @@ console.log("THE BROWSER IS OFFLINE");
|
|||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
||||||
doLogin: function (event) {
|
doLogin_handler: function (event) {
|
||||||
|
return this.doLogin(event);
|
||||||
|
},
|
||||||
|
|
||||||
|
doLogin: function (someCredentials) {
|
||||||
|
var deferredResult;
|
||||||
var credentials;
|
var credentials;
|
||||||
var getPassphraseDelegate;
|
var getPassphraseDelegate;
|
||||||
var user;
|
var user;
|
||||||
@ -240,10 +285,10 @@ console.log("THE BROWSER IS OFFLINE");
|
|||||||
this.overlay().show("logging in");
|
this.overlay().show("logging in");
|
||||||
this.pages()['loginPage'].setProps({disabled:true});
|
this.pages()['loginPage'].setProps({disabled:true});
|
||||||
|
|
||||||
if ('pin' in event) {
|
if ('pin' in someCredentials) {
|
||||||
credentials = Clipperz.PM.PIN.credentialsWithPIN(event['pin']);
|
credentials = Clipperz.PM.PIN.credentialsWithPIN(someCredentials['pin']);
|
||||||
} else {
|
} else {
|
||||||
credentials = event;
|
credentials = someCredentials;
|
||||||
}
|
}
|
||||||
getPassphraseDelegate = MochiKit.Base.partial(MochiKit.Async.succeed, credentials.passphrase);
|
getPassphraseDelegate = MochiKit.Base.partial(MochiKit.Async.succeed, credentials.passphrase);
|
||||||
user = new Clipperz.PM.DataModel.User({'username':credentials.username, 'getPassphraseFunction':getPassphraseDelegate});
|
user = new Clipperz.PM.DataModel.User({'username':credentials.username, 'getPassphraseFunction':getPassphraseDelegate});
|
||||||
@ -254,18 +299,16 @@ console.log("THE BROWSER IS OFFLINE");
|
|||||||
deferredResult.addMethod(user, 'login');
|
deferredResult.addMethod(user, 'login');
|
||||||
deferredResult.addMethod(Clipperz.PM.PIN, 'resetFailedAttemptCount');
|
deferredResult.addMethod(Clipperz.PM.PIN, 'resetFailedAttemptCount');
|
||||||
deferredResult.addMethod(this, 'setUser', user);
|
deferredResult.addMethod(this, 'setUser', user);
|
||||||
|
|
||||||
// deferredResult.addMethod(this, 'setupApplication');
|
|
||||||
deferredResult.addMethod(this, 'runApplication');
|
deferredResult.addMethod(this, 'runApplication');
|
||||||
deferredResult.addMethod(this.overlay(), 'done', "", 1);
|
deferredResult.addMethod(this.overlay(), 'done', "", 1);
|
||||||
deferredResult.addErrback(MochiKit.Base.method(this, 'genericErrorHandler', event));
|
deferredResult.addErrback(MochiKit.Base.method(this, 'genericErrorHandler', someCredentials));
|
||||||
deferredResult.addErrback(MochiKit.Base.bind(function (anEvent, anError) {
|
deferredResult.addErrback(MochiKit.Base.bind(function (anEvent, anError) {
|
||||||
if (anError['isPermanent'] != true) {
|
if (anError['isPermanent'] != true) {
|
||||||
this.pages()['loginPage'].setProps({disabled:false, 'mode':this.loginMode()});
|
this.pages()['loginPage'].setProps({disabled:false, 'mode':this.loginMode()});
|
||||||
this.pages()['loginPage'].setInitialFocus();
|
this.pages()['loginPage'].setInitialFocus();
|
||||||
}
|
}
|
||||||
return anError;
|
return anError;
|
||||||
}, this, event))
|
}, this, someCredentials))
|
||||||
deferredResult.callback();
|
deferredResult.callback();
|
||||||
|
|
||||||
return deferredResult;
|
return deferredResult;
|
||||||
@ -273,19 +316,19 @@ console.log("THE BROWSER IS OFFLINE");
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
registerNewUser: function (credentials) {
|
registerNewUser_handler: function (credentials) {
|
||||||
var deferredResult;
|
var deferredResult;
|
||||||
|
|
||||||
this.overlay().show("creating user");
|
this.overlay().show("creating user");
|
||||||
|
|
||||||
this.pages()['registrationPage'].setProps({disabled:true});
|
this.pages()['registrationPage'].setProps({disabled:true});
|
||||||
deferredResult = new Clipperz.Async.Deferred('MainController.registerNewUser', {trace:false});
|
deferredResult = new Clipperz.Async.Deferred('MainController.registerNewUser', {trace:true});
|
||||||
deferredResult.addCallback(Clipperz.PM.DataModel.User.registerNewAccount,
|
deferredResult.addCallback(Clipperz.PM.DataModel.User.registerNewAccount,
|
||||||
credentials['username'],
|
credentials['username'],
|
||||||
MochiKit.Base.partial(MochiKit.Async.succeed, credentials['passphrase'])
|
MochiKit.Base.partial(MochiKit.Async.succeed, credentials['passphrase'])
|
||||||
);
|
);
|
||||||
deferredResult.addMethod(this, 'doLogin', credentials);
|
deferredResult.addMethod(this, 'doLogin', credentials);
|
||||||
deferredResult.addErrback(MochiKit.Base.method(this, 'genericErrorHandler', event));
|
deferredResult.addErrback(MochiKit.Base.method(this, 'genericErrorHandler', credentials));
|
||||||
deferredResult.addErrback(MochiKit.Base.bind(function (anError) {
|
deferredResult.addErrback(MochiKit.Base.bind(function (anError) {
|
||||||
if (anError['isPermanent'] != true) {
|
if (anError['isPermanent'] != true) {
|
||||||
this.pages()['registrationPage'].setProps({disabled:false});
|
this.pages()['registrationPage'].setProps({disabled:false});
|
||||||
@ -307,109 +350,222 @@ console.log("THE BROWSER IS OFFLINE");
|
|||||||
},
|
},
|
||||||
|
|
||||||
setUser: function (aUser) {
|
setUser: function (aUser) {
|
||||||
|
console.log("SET USER", aUser);
|
||||||
this._user = aUser;
|
this._user = aUser;
|
||||||
return this._user;
|
return this._user;
|
||||||
},
|
},
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
||||||
allCardInfo: function () {
|
|
||||||
var deferredResult;
|
|
||||||
var cardInfo;
|
|
||||||
|
|
||||||
cardInfo = {
|
|
||||||
'_rowObject': MochiKit.Async.succeed,
|
|
||||||
'_reference': MochiKit.Base.methodcaller('reference'),
|
|
||||||
'_searchableContent': MochiKit.Base.methodcaller('searchableContent'),
|
|
||||||
'label': MochiKit.Base.methodcaller('label'),
|
|
||||||
'favicon': MochiKit.Base.methodcaller('favicon')
|
|
||||||
};
|
|
||||||
|
|
||||||
deferredResult = new Clipperz.Async.Deferred('MainController.allCardInfo', {trace:false});
|
|
||||||
deferredResult.addMethod(this.user(), 'getRecords');
|
|
||||||
deferredResult.addCallback(MochiKit.Base.map, Clipperz.Async.collectResults("CardList.value - collectResults", cardInfo, {trace:false}));
|
|
||||||
deferredResult.addCallback(Clipperz.Async.collectAll);
|
|
||||||
deferredResult.callback();
|
|
||||||
|
|
||||||
return deferredResult;
|
|
||||||
},
|
|
||||||
|
|
||||||
filterCards: function (someCardInfo) {
|
|
||||||
var filter;
|
|
||||||
var filterRegExp;
|
|
||||||
var result;
|
|
||||||
|
|
||||||
filter = this.filter().replace(/[^A-Za-z0-9]/g, "\\$&");
|
|
||||||
filterRegExp = new RegExp(filter, "i");
|
|
||||||
result = MochiKit.Base.filter(function (aCardInfo) { return filterRegExp.test(aCardInfo['_searchableContent'])}, someCardInfo);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
sortCards: function (someCardInfo) {
|
|
||||||
return someCardInfo.sort(Clipperz.Base.caseInsensitiveKeyComparator('label'));
|
|
||||||
},
|
|
||||||
|
|
||||||
showRecordList: function () {
|
|
||||||
var deferredResult;
|
|
||||||
|
|
||||||
deferredResult = new Clipperz.Async.Deferred('MainController.showRecordList', {trace:false});
|
|
||||||
deferredResult.addMethod(this, 'allCardInfo');
|
|
||||||
deferredResult.addMethod(this, 'filterCards');
|
|
||||||
deferredResult.addMethod(this, 'sortCards');
|
|
||||||
deferredResult.addCallback(MochiKit.Base.bind(function (someRecordInfo) {
|
|
||||||
this.pages()['cardListPage'].setProps({cardList: someRecordInfo});
|
|
||||||
}, this));
|
|
||||||
deferredResult.callback();
|
|
||||||
|
|
||||||
return deferredResult;
|
|
||||||
},
|
|
||||||
|
|
||||||
filter: function () {
|
filter: function () {
|
||||||
return this._filter;
|
return this._filter;
|
||||||
},
|
},
|
||||||
|
|
||||||
setFilter: function (aValue) {
|
setFilter: function (aType, aValue) {
|
||||||
this._filter = aValue;
|
this._filter = {'type':aType, 'value':aValue};
|
||||||
|
return this._filter;
|
||||||
},
|
},
|
||||||
|
|
||||||
searchCards: function (someParameters) {
|
//----------------------------------------------------------------------------
|
||||||
//console.log("SEARCH CARDS", someParameters);
|
|
||||||
this.setFilter(someParameters);
|
|
||||||
this.showRecordList();
|
|
||||||
},
|
|
||||||
|
|
||||||
//=========================================================================
|
collectFieldInfo: function (aField) {
|
||||||
|
var deferredResult;
|
||||||
|
|
||||||
runApplication: function () {
|
deferredResult = new Clipperz.Async.Deferred('MainController.collectFieldInfo', {trace:false});
|
||||||
MochiKit.Signal.connect(window, 'onpopstate', MochiKit.Base.method(this, 'historyGoBack'));
|
deferredResult.addMethod(aField, 'reference');
|
||||||
/// TODO: remove this TEST HACK
|
deferredResult.setValue('_reference');
|
||||||
this.moveInPage(this.currentPage(), 'cardListPage');
|
deferredResult.addMethod(aField, 'label');
|
||||||
return this.showRecordList();
|
deferredResult.setValue('label');
|
||||||
|
deferredResult.addMethod(aField, 'value');
|
||||||
|
deferredResult.setValue('value');
|
||||||
|
deferredResult.addMethod(aField, 'actionType');
|
||||||
|
deferredResult.setValue('actionType');
|
||||||
|
deferredResult.addMethod(aField, 'isHidden');
|
||||||
|
deferredResult.setValue('isHidden');
|
||||||
|
deferredResult.values();
|
||||||
|
|
||||||
// this.moveInPage(this.currentPage(), 'preferencePage');
|
|
||||||
},
|
|
||||||
|
|
||||||
showRecord: function (aRecordReference) {
|
|
||||||
//console.log("Show Record", aRecordReference);
|
|
||||||
var deferredResult;
|
|
||||||
|
|
||||||
this.pages()['cardListPage'].setProps({selectedCard:aRecordReference});
|
|
||||||
deferredResult = new Clipperz.Async.Deferred('MainController.runApplication', {trace:false});
|
|
||||||
deferredResult.addMethod(this.user(), 'getRecord', aRecordReference);
|
|
||||||
deferredResult.addMethodcaller('content');
|
|
||||||
deferredResult.addCallback(MochiKit.Base.bind(function (aCard) {
|
|
||||||
//console.log("CARD DETAILS", aCard);
|
|
||||||
this.pages()['cardDetailPage'].setProps({card: aCard});
|
|
||||||
this.pages()['cardListPage'].setProps({selectedCard: null});
|
|
||||||
}, this));
|
|
||||||
deferredResult.addMethod(this, 'moveInPage', this.currentPage(), 'cardDetailPage', true);
|
|
||||||
deferredResult.callback();
|
deferredResult.callback();
|
||||||
|
|
||||||
return deferredResult;
|
return deferredResult;
|
||||||
},
|
},
|
||||||
|
|
||||||
runDirectLogin: function (someParameters) {
|
collectDirectLoginInfo: function (aDirectLogin) {
|
||||||
|
var deferredResult;
|
||||||
|
|
||||||
|
deferredResult = new Clipperz.Async.Deferred('MainController.collectDirectLoginInfo', {trace:false});
|
||||||
|
deferredResult.addMethod(aDirectLogin, 'reference');
|
||||||
|
deferredResult.setValue('_reference');
|
||||||
|
deferredResult.addMethod(aDirectLogin, 'label');
|
||||||
|
deferredResult.setValue('label');
|
||||||
|
deferredResult.addMethod(aDirectLogin, 'favicon');
|
||||||
|
deferredResult.setValue('favicon');
|
||||||
|
deferredResult.values();
|
||||||
|
|
||||||
|
deferredResult.callback();
|
||||||
|
|
||||||
|
return deferredResult;
|
||||||
|
},
|
||||||
|
|
||||||
|
collectRecordInfo: function (aRecord) {
|
||||||
|
var deferredResult;
|
||||||
|
|
||||||
|
deferredResult = new Clipperz.Async.Deferred('MainController.collectRecordInfo', {trace:false});
|
||||||
|
deferredResult.addMethod(aRecord, 'reference');
|
||||||
|
deferredResult.setValue('_reference');
|
||||||
|
deferredResult.addMethod(aRecord, 'label');
|
||||||
|
deferredResult.setValue('label');
|
||||||
|
deferredResult.addMethod(aRecord, 'notes');
|
||||||
|
deferredResult.setValue('notes');
|
||||||
|
deferredResult.addMethod(aRecord, 'tags');
|
||||||
|
deferredResult.setValue('tags');
|
||||||
|
|
||||||
|
deferredResult.addMethod(aRecord, 'fields');
|
||||||
|
deferredResult.addCallback(MochiKit.Base.values);
|
||||||
|
deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.method(this, 'collectFieldInfo'));
|
||||||
|
deferredResult.addCallback(Clipperz.Async.collectAll);
|
||||||
|
deferredResult.setValue('fields');
|
||||||
|
|
||||||
|
deferredResult.addMethod(aRecord, 'directLogins');
|
||||||
|
deferredResult.addCallback(MochiKit.Base.values);
|
||||||
|
deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.method(this, 'collectDirectLoginInfo'));
|
||||||
|
deferredResult.addCallback(Clipperz.Async.collectAll);
|
||||||
|
deferredResult.setValue('directLogins');
|
||||||
|
|
||||||
|
deferredResult.values();
|
||||||
|
|
||||||
|
deferredResult.callback();
|
||||||
|
|
||||||
|
return deferredResult;
|
||||||
|
},
|
||||||
|
|
||||||
|
updateSelectedCard: function (someInfo) {
|
||||||
|
var deferredResult;
|
||||||
|
|
||||||
|
if (someInfo == null) {
|
||||||
|
this.setPageProperties('mainPage', 'selectedCard', {});
|
||||||
|
deferredResult = MochiKit.Async.succeed();
|
||||||
|
} else {
|
||||||
|
this.setPageProperties('mainPage', 'selectedCard', {'loading':true, 'label':someInfo['label'], '_reference':someInfo['reference']});
|
||||||
|
|
||||||
|
deferredResult = new Clipperz.Async.Deferred('MainController.updateSelectedCard', {trace:false});
|
||||||
|
deferredResult.addMethod(this.user(), 'getRecord', someInfo['reference']);
|
||||||
|
deferredResult.addMethod(this, 'collectRecordInfo');
|
||||||
|
|
||||||
|
//console.log("MEDIA QUERY STYLE", this.mediaQueryStyle());
|
||||||
|
deferredResult.addMethod(this, 'setPageProperties', 'mainPage', 'selectedCard');
|
||||||
|
if (this.mediaQueryStyle() == 'narrow') {
|
||||||
|
deferredResult.addMethod(this, 'setPageProperties', 'cardDetailPage', 'selectedCard');
|
||||||
|
deferredResult.addMethod(this, 'moveInPage', this.currentPage(), 'cardDetailPage');
|
||||||
|
// deferredResult.addCallback(function (aValue) { console.log("SHOULD SLIDE IN PAGE DETAIL"); return aValue; });
|
||||||
|
//console.log("SHOULD SLIDE IN PAGE DETAIL");
|
||||||
|
}
|
||||||
|
|
||||||
|
MochiKit.Async.callLater(0.1, MochiKit.Base.method(deferredResult, 'callback'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return deferredResult;
|
||||||
|
},
|
||||||
|
|
||||||
|
//............................................................................
|
||||||
|
|
||||||
|
regExpFilterGenerator: function (aRegExp, aSearchField) {
|
||||||
|
var searchField = aSearchField ? aSearchField : Clipperz.PM.DataModel.Record.defaultSearchField;
|
||||||
|
|
||||||
|
return function (aCardInfo) {
|
||||||
|
aRegExp.lastIndex = 0;
|
||||||
|
return aRegExp.test(aCardInfo[searchField]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
selectedCardReference: function () {
|
||||||
|
return this.pages()['mainPage'].props &&
|
||||||
|
this.pages()['mainPage'].props['selectedCard'] &&
|
||||||
|
this.pages()['mainPage'].props['selectedCard'] &&
|
||||||
|
this.pages()['mainPage'].props['selectedCard']['_reference']
|
||||||
|
? this.pages()['mainPage'].props['selectedCard']['_reference']
|
||||||
|
: '';
|
||||||
|
},
|
||||||
|
|
||||||
|
isSelectedCardStillVisible: function (someCards) {
|
||||||
|
var result;
|
||||||
|
var reference;
|
||||||
|
|
||||||
|
reference = this.selectedCardReference();
|
||||||
|
result = MochiKit.Iter.some(someCards, function (aCardInfo) {
|
||||||
|
return aCardInfo['_reference'] == reference;
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
updateSelectedCards: function (shouldIncludeArchivedCards, aFilter) {
|
||||||
|
var deferredResult;
|
||||||
|
var sortCriteria;
|
||||||
|
|
||||||
|
sortCriteria = Clipperz.Base.caseInsensitiveKeyComparator('label');
|
||||||
|
|
||||||
|
deferredResult = new Clipperz.Async.Deferred('MainController.setFilter', {trace:false});
|
||||||
|
deferredResult.addMethod(this.user(), 'getRecordsInfo', Clipperz.PM.DataModel.Record.defaultCardInfo, shouldIncludeArchivedCards);
|
||||||
|
|
||||||
|
if (aFilter['type'] == 'ALL') {
|
||||||
|
deferredResult.addMethodcaller('sort', sortCriteria);
|
||||||
|
} else if (aFilter['type'] == 'RECENT') {
|
||||||
|
deferredResult.addMethodcaller('sort', Clipperz.Base.reverseComparator(MochiKit.Base.keyComparator('accessDate')));
|
||||||
|
deferredResult.addCallback(function (someCards) { return someCards.slice(0, 9)});
|
||||||
|
} else if (aFilter['type'] == 'SEARCH') {
|
||||||
|
deferredResult.addCallback(MochiKit.Base.filter, this.regExpFilterGenerator(Clipperz.PM.DataModel.Record.regExpForSearch(aFilter['value'])));
|
||||||
|
deferredResult.addMethodcaller('sort', sortCriteria);
|
||||||
|
} else if (aFilter['type'] == 'TAG') {
|
||||||
|
deferredResult.addCallback(MochiKit.Base.filter, this.regExpFilterGenerator(Clipperz.PM.DataModel.Record.regExpForTag(aFilter['value'])));
|
||||||
|
deferredResult.addMethodcaller('sort', sortCriteria);
|
||||||
|
}
|
||||||
|
|
||||||
|
deferredResult.addMethod(this, 'setPageProperties', 'mainPage', 'cards');
|
||||||
|
deferredResult.addCallback(MochiKit.Base.bind(function (someCards) {
|
||||||
|
if (!this.isSelectedCardStillVisible(someCards)) {
|
||||||
|
this.updateSelectedCard(null);
|
||||||
|
};
|
||||||
|
}, this));
|
||||||
|
deferredResult.addMethod(this, 'setPageProperties', 'mainPage', 'filter', this.filter());
|
||||||
|
|
||||||
|
deferredResult.callback();
|
||||||
|
|
||||||
|
return deferredResult;
|
||||||
|
},
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
setPageProperties: function (aPageName, aKey, aValue) {
|
||||||
|
var props = {};
|
||||||
|
props[aKey] = aValue;
|
||||||
|
this.pages()[aPageName].setProps(props);
|
||||||
|
|
||||||
|
return aValue;
|
||||||
|
},
|
||||||
|
|
||||||
|
renderAccountData: function () {
|
||||||
|
var deferredResult;
|
||||||
|
|
||||||
|
deferredResult = new Clipperz.Async.Deferred('MainController.renderAccountData', {trace:false});
|
||||||
|
deferredResult.addMethod(this, 'setFilter', 'ALL');
|
||||||
|
deferredResult.addMethod(this, 'updateSelectedCards', false);
|
||||||
|
|
||||||
|
deferredResult.addMethod(this.user(), 'getTags');
|
||||||
|
deferredResult.addMethodcaller('sort', Clipperz.Base.caseInsensitiveCompare);
|
||||||
|
deferredResult.addMethod(this, 'setPageProperties', 'mainPage', 'tags');
|
||||||
|
deferredResult.callback();
|
||||||
|
|
||||||
|
return deferredResult;
|
||||||
|
},
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
|
||||||
|
runApplication: function (anUser) {
|
||||||
|
this.moveInPage(this.currentPage(), 'mainPage');
|
||||||
|
return this.renderAccountData();
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
runDirectLogin_handler: function (someParameters) {
|
||||||
//console.log("RUN DIRECT LOGIN", someParameters);
|
//console.log("RUN DIRECT LOGIN", someParameters);
|
||||||
var deferredResult;
|
var deferredResult;
|
||||||
|
|
||||||
@ -427,10 +583,18 @@ console.log("THE BROWSER IS OFFLINE");
|
|||||||
anEvent.preventDefault();
|
anEvent.preventDefault();
|
||||||
anEvent.stopPropagation();
|
anEvent.stopPropagation();
|
||||||
},
|
},
|
||||||
|
*/
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
/*
|
||||||
showPreferences: function (anEvent) {
|
searchCards_handler: function (someParameters) {
|
||||||
|
//console.log("SEARCH CARDS", someParameters);
|
||||||
|
this.setFilter(someParameters);
|
||||||
|
this.renderAccountData();
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
//=========================================================================
|
||||||
|
/*
|
||||||
|
showPreferences_handler: function (anEvent) {
|
||||||
var deferredResult;
|
var deferredResult;
|
||||||
|
|
||||||
this.pages()['preferencePage'].setProps({});
|
this.pages()['preferencePage'].setProps({});
|
||||||
@ -440,7 +604,7 @@ console.log("THE BROWSER IS OFFLINE");
|
|||||||
|
|
||||||
return deferredResult;
|
return deferredResult;
|
||||||
},
|
},
|
||||||
|
*/
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
||||||
genericErrorHandler: function (anEvent, anError) {
|
genericErrorHandler: function (anEvent, anError) {
|
||||||
@ -471,39 +635,35 @@ console.log("THE BROWSER IS OFFLINE");
|
|||||||
|
|
||||||
slidePage: function (fromPage, toPage, direction) {
|
slidePage: function (fromPage, toPage, direction) {
|
||||||
var fromPosition;
|
var fromPosition;
|
||||||
var toPosition;
|
var toPosition;
|
||||||
|
var itemToTransition;
|
||||||
|
|
||||||
if (direction == "LEFT") {
|
if (direction == "LEFT") {
|
||||||
fromPosition = 'right';
|
fromPosition = 'right';
|
||||||
toPosition = 'left'
|
toPosition = 'left';
|
||||||
|
itemToTransition = toPage;
|
||||||
} else {
|
} else {
|
||||||
fromPosition = 'left';
|
fromPosition = 'left';
|
||||||
toPosition = 'right'
|
toPosition = 'right';
|
||||||
|
itemToTransition = fromPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
MochiKit.DOM.addElementClass(fromPage, toPosition + ' transition');
|
MochiKit.DOM.addElementClass(itemToTransition, 'transition');
|
||||||
|
|
||||||
MochiKit.DOM.addElementClass(toPage, fromPosition);
|
MochiKit.Async.callLater(0, function () {
|
||||||
MochiKit.DOM.removeElementClass(toPage, toPosition);
|
MochiKit.DOM.addElementClass(fromPage, toPosition);
|
||||||
MochiKit.DOM.addElementClass(toPage, 'transition');
|
|
||||||
MochiKit.Async.callLater(0.1, function () {
|
|
||||||
MochiKit.DOM.removeElementClass(toPage, fromPosition);
|
MochiKit.DOM.removeElementClass(toPage, fromPosition);
|
||||||
})
|
})
|
||||||
|
|
||||||
MochiKit.Async.callLater(0.5, function () {
|
MochiKit.Async.callLater(0.5, function () {
|
||||||
MochiKit.DOM.removeElementClass(fromPage, 'transition');
|
MochiKit.DOM.removeElementClass(itemToTransition, 'transition');
|
||||||
MochiKit.DOM.removeElementClass(toPage, 'transition');
|
|
||||||
})
|
})
|
||||||
},
|
|
||||||
|
|
||||||
rotateInPage: function (fromPage, toPage) {
|
|
||||||
// Broken! :(
|
|
||||||
MochiKit.DOM.addElementClass(MochiKit.DOM.getElement('mainDiv'), 'show-right');
|
|
||||||
},
|
},
|
||||||
|
|
||||||
//.........................................................................
|
//.........................................................................
|
||||||
|
|
||||||
goBack: function () {
|
goBack_handler: function () {
|
||||||
var fromPage;
|
var fromPage;
|
||||||
var toPage;
|
var toPage;
|
||||||
|
|
||||||
@ -525,6 +685,7 @@ console.log("THE BROWSER IS OFFLINE");
|
|||||||
|
|
||||||
setCurrentPage: function (aPage) {
|
setCurrentPage: function (aPage) {
|
||||||
this.pageStack().unshift(aPage);
|
this.pageStack().unshift(aPage);
|
||||||
|
this.refreshCurrentPage();
|
||||||
},
|
},
|
||||||
|
|
||||||
moveInPage: function (fromPage, toPage, addToHistory) {
|
moveInPage: function (fromPage, toPage, addToHistory) {
|
||||||
@ -552,12 +713,108 @@ console.log("THE BROWSER IS OFFLINE");
|
|||||||
this.setCurrentPage(toPage);
|
this.setCurrentPage(toPage);
|
||||||
},
|
},
|
||||||
|
|
||||||
//=========================================================================
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
synchronizeLocalData: function (anEvent) {
|
messageBoxContent: function () {
|
||||||
|
var message;
|
||||||
|
var level;
|
||||||
|
|
||||||
|
message = "";
|
||||||
|
level = 'HIDE';
|
||||||
|
|
||||||
|
//console.log("messageBox - this.user()", this.user());
|
||||||
|
if (this.user() != null && this.user().accountInfo() != null && this.user().accountInfo().featureSet() == 'EXPIRED') {
|
||||||
|
message = "Exprired subscription";
|
||||||
|
level = 'ERROR';
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
'message': message,
|
||||||
|
'level': level
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
userAccountInfo: function () {
|
||||||
|
var result;
|
||||||
|
|
||||||
|
result = {};
|
||||||
|
|
||||||
|
if (this.user() != null) {
|
||||||
|
var usefulFields = [
|
||||||
|
'currentSubscriptionType',
|
||||||
|
'expirationDate',
|
||||||
|
'featureSet',
|
||||||
|
'isExpired',
|
||||||
|
'isExpiring',
|
||||||
|
'paymentVerificationPending'
|
||||||
|
];
|
||||||
|
|
||||||
|
var attributes = this.user().accountInfo()._attributes;
|
||||||
|
MochiKit.Iter.forEach(usefulFields, function (aFieldName) {
|
||||||
|
result[aFieldName] = attributes[aFieldName];
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
genericPageProperties: function () {
|
||||||
|
return {
|
||||||
|
'style': this.mediaQueryStyle(),
|
||||||
|
'isTouchDevice': this.isTouchDevice(),
|
||||||
|
'isDesktop': this.isDesktop(),
|
||||||
|
'hasKeyboard': this.hasKeyboard()
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
pageProperties: function (aPageName) {
|
||||||
|
var result;
|
||||||
|
var extraProperties = null;
|
||||||
|
|
||||||
|
result = this.genericPageProperties();
|
||||||
|
|
||||||
|
if (aPageName == 'loginPage') {
|
||||||
|
extraProperties = {
|
||||||
|
'mode': 'CREDENTIALS',
|
||||||
|
'isNewUserRegistrationAvailable': true,
|
||||||
|
'disabled': false,
|
||||||
|
};
|
||||||
|
} else if (aPageName == 'registrationPage') {
|
||||||
|
} else if (aPageName == 'mainPage') {
|
||||||
|
extraProperties = {
|
||||||
|
'messageBox': this.messageBoxContent(),
|
||||||
|
'accountStatus': this.userAccountInfo(),
|
||||||
|
'selectionPanelStatus': this.isSelectionPanelOpen() ? 'OPEN' : 'CLOSED',
|
||||||
|
'settingsPanelStatus': this.isSettingsPanelOpen() ? 'OPEN' : 'CLOSED',
|
||||||
|
// 'cards': …,
|
||||||
|
// 'tags': …,
|
||||||
|
// 'selectedCard': …,
|
||||||
|
};
|
||||||
|
} else if (aPageName == 'errorPage') {
|
||||||
|
extraProperties = {
|
||||||
|
'message': ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extraProperties != null) {
|
||||||
|
result = MochiKit.Base.update(result, extraProperties);
|
||||||
|
}
|
||||||
|
//console.log("MainController.pageProperties", result);
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
refreshCurrentPage: function () {
|
||||||
|
if (this.pages()[this.currentPage()] != null) {
|
||||||
|
this.pages()[this.currentPage()].setProps(this.pageProperties(this.currentPage()));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
/*
|
||||||
|
synchronizeLocalData_handler: function (anEvent) {
|
||||||
var deferredResult;
|
var deferredResult;
|
||||||
|
|
||||||
deferredResult = new Clipperz.Async.Deferred('MainController.synchronizeLocalData', {trace:true});
|
deferredResult = new Clipperz.Async.Deferred('MainController.synchronizeLocalData', {trace:false});
|
||||||
// deferredResult.addMethod(this.proxy(), 'message', 'downloadAccountData', {});
|
// deferredResult.addMethod(this.proxy(), 'message', 'downloadAccountData', {});
|
||||||
deferredResult.addMethod(this.user().connection(), 'message', 'downloadAccountData', {});
|
deferredResult.addMethod(this.user().connection(), 'message', 'downloadAccountData', {});
|
||||||
deferredResult.addCallback(function (aResult) {
|
deferredResult.addCallback(function (aResult) {
|
||||||
@ -570,8 +827,126 @@ console.log("THE BROWSER IS OFFLINE");
|
|||||||
|
|
||||||
return deferredResult;
|
return deferredResult;
|
||||||
},
|
},
|
||||||
|
*/
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
||||||
|
resetPanels: function () {
|
||||||
|
this._isSelectionPanelOpen = false;
|
||||||
|
this._isSettingsPanelOpen = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
isSelectionPanelOpen: function () {
|
||||||
|
return this._isSelectionPanelOpen;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
toggleSelectionPanel_handler: function (anEvent) {
|
||||||
|
this._isSelectionPanelOpen = !this._isSelectionPanelOpen;
|
||||||
|
this.setCloseMaskAction(MochiKit.Base.method(this, 'toggleSelectionPanel_handler'));
|
||||||
|
this.refreshCurrentPage();
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
isSettingsPanelOpen: function () {
|
||||||
|
return this._isSettingsPanelOpen;
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleSettingsPanel_handler: function (anEvent) {
|
||||||
|
this._isSettingsPanelOpen = !this._isSettingsPanelOpen;
|
||||||
|
this.setCloseMaskAction(MochiKit.Base.method(this, 'toggleSettingsPanel_handler'));
|
||||||
|
this.refreshCurrentPage();
|
||||||
|
},
|
||||||
|
|
||||||
|
cardSelected_handler: function (aReference) {
|
||||||
|
this.updateSelectedCard(aReference);
|
||||||
|
},
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
addCardClick_handler: function () {
|
||||||
|
console.log("ADD CARD CLICK");
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteCard_handler: function (anEvent) {
|
||||||
|
console.log("DELETE CARD", anEvent['reference']);
|
||||||
|
},
|
||||||
|
|
||||||
|
archiveCard_handler: function (anEvent) {
|
||||||
|
console.log("ARCHIVE CARD", anEvent['reference']);
|
||||||
|
},
|
||||||
|
|
||||||
|
editCard_handler: function (anEvent) {
|
||||||
|
console.log("EDIT CARD", anEvent['reference']);
|
||||||
|
},
|
||||||
|
|
||||||
|
goBackToMainPage_handler: function (anEvent) {
|
||||||
|
this.updateSelectedCard();
|
||||||
|
this.moveOutPage(this.currentPage(), 'mainPage');
|
||||||
|
},
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
selectAllCards_handler: function () {
|
||||||
|
this.setFilter('ALL');
|
||||||
|
this.updateSelectedCards(false, this.filter());
|
||||||
|
},
|
||||||
|
|
||||||
|
selectRecentCards_handler: function () {
|
||||||
|
this.setFilter('RECENT');
|
||||||
|
this.updateSelectedCards(false, this.filter());
|
||||||
|
},
|
||||||
|
|
||||||
|
tagSelected_handler: function (aTag) {
|
||||||
|
this.setFilter('TAG', aTag);
|
||||||
|
this.updateSelectedCards(false, this.filter());
|
||||||
|
},
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
setCloseMaskAction: function (aFunction) {
|
||||||
|
this._closeMaskAction = aFunction;
|
||||||
|
},
|
||||||
|
|
||||||
|
maskClick_handler: function () {
|
||||||
|
this._closeMaskAction.apply(this);
|
||||||
|
this._closeMaskAction = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
matchMediaQuery_handler: function (newQueryStyle) {
|
||||||
|
this._mediaQueryStyle = newQueryStyle;
|
||||||
|
|
||||||
|
if (this.currentPage() == 'cardDetailPage') {
|
||||||
|
this.moveOutPage(this.currentPage(), 'mainPage');
|
||||||
|
}
|
||||||
|
this.resetPanels();
|
||||||
|
this.refreshCurrentPage();
|
||||||
|
},
|
||||||
|
|
||||||
|
unmatchMediaQuery_handler: function (queryStyle) {
|
||||||
|
},
|
||||||
|
|
||||||
|
mediaQueryStyle: function () {
|
||||||
|
return this._mediaQueryStyle;
|
||||||
|
},
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
isTouchDevice: function () {
|
||||||
|
return this._isTouchDevice;
|
||||||
|
},
|
||||||
|
|
||||||
|
isDesktop: function () {
|
||||||
|
return this._isDesktop;
|
||||||
|
},
|
||||||
|
|
||||||
|
hasKeyboard: function () {
|
||||||
|
return this._hasKeyboard;
|
||||||
|
},
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
/*
|
/*
|
||||||
wrongAppVersion: function (anError) {
|
wrongAppVersion: function (anError) {
|
||||||
// this.pages()['errorPage'].setProps({message:anError.message});
|
// this.pages()['errorPage'].setProps({message:anError.message});
|
||||||
|
261
frontend/delta/js/OnMediaQuery/onmediaquery-0.2.0.js
Normal file
261
frontend/delta/js/OnMediaQuery/onmediaquery-0.2.0.js
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* onMediaQuery
|
||||||
|
* http://springload.co.nz/love-the-web/
|
||||||
|
*
|
||||||
|
* Copyright 2012, Springload
|
||||||
|
* Released under the MIT license.
|
||||||
|
* http://www.opensource.org/licenses/mit-license.php
|
||||||
|
*
|
||||||
|
* Date: Fri 24 October, 2012
|
||||||
|
*/
|
||||||
|
|
||||||
|
;(function (root, factory) {
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
// AMD. Register as an anonymous module.
|
||||||
|
define(function () {
|
||||||
|
// Also create a global in case some scripts
|
||||||
|
// that are loaded still are looking for
|
||||||
|
// a global even when an AMD loader is in use.
|
||||||
|
return (root.MQ = factory(root, root.MQ || {}));
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Browser globals
|
||||||
|
root.MQ = factory(root, root.MQ || {});
|
||||||
|
}
|
||||||
|
}(this, function(mq) {
|
||||||
|
/**
|
||||||
|
* Initialises the MQ object and sets the initial media query callbacks
|
||||||
|
* @returns Void(0)
|
||||||
|
*/
|
||||||
|
mq.init = function(query_array) {
|
||||||
|
|
||||||
|
// Container for all callbacks registered with the plugin
|
||||||
|
this.callbacks = [];
|
||||||
|
this.context = ''; //current active query
|
||||||
|
this.new_context = ''; //current active query to be read inside callbacks, as this.context won't be set when they're called!
|
||||||
|
|
||||||
|
if (typeof(query_array) !== 'undefined' ) {
|
||||||
|
for (i = 0; i < query_array.length; i++) {
|
||||||
|
var r = this.addQuery(query_array[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a listener to the window.resize event, pass mq/self as the scope.
|
||||||
|
this.addEvent(window, 'resize', mq.listenForChange, mq);
|
||||||
|
|
||||||
|
// Figure out which query is active on load.
|
||||||
|
this.listenForChange();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds to the window.onResize and checks for media query changes
|
||||||
|
* @returns Void(0)
|
||||||
|
*/
|
||||||
|
mq.listenForChange = function() {
|
||||||
|
var query_string;
|
||||||
|
|
||||||
|
// Get the value of html { font-family } from the element style.
|
||||||
|
if (document.documentElement.currentStyle) {
|
||||||
|
query_string = document.documentElement.currentStyle["fontFamily"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.getComputedStyle) {
|
||||||
|
query_string = window.getComputedStyle(document.documentElement,null).getPropertyValue('font-family');
|
||||||
|
}
|
||||||
|
|
||||||
|
// No support for CSS enumeration? Return and avoid errors.
|
||||||
|
if (query_string === null) return;
|
||||||
|
|
||||||
|
// Android browsers place a "," after an item in the font family list.
|
||||||
|
// Most browsers either single or double quote the string.
|
||||||
|
query_string = query_string.replace(/['",]/g, '');
|
||||||
|
|
||||||
|
if (query_string !== this.context) {
|
||||||
|
this.new_context = query_string;
|
||||||
|
this.triggerCallbacks(this.context, 'unmatch');
|
||||||
|
this.triggerCallbacks(this.new_context, 'match');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.context = this.new_context;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attach a new query to test.
|
||||||
|
* @param query_object {
|
||||||
|
* context: ['some_media_query','some_other_media_query'],
|
||||||
|
* call_for_each_context: true,
|
||||||
|
* callback: function() {
|
||||||
|
* //something awesome
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* @returns A reference to the query_object that was added
|
||||||
|
*/
|
||||||
|
mq.addQuery = function(query_object) {
|
||||||
|
if (query_object === null || query_object === undefined) return;
|
||||||
|
|
||||||
|
this.callbacks.push(query_object);
|
||||||
|
|
||||||
|
// If the context is passed as a string, turn it into an array (for unified approach elsewhere in the code)
|
||||||
|
if (typeof(query_object.context) == "string") {
|
||||||
|
query_object.context = [query_object.context];
|
||||||
|
}
|
||||||
|
|
||||||
|
// See if "call_for_each_context" is set, if not, set a default (for unified approach elsewhere in the code)
|
||||||
|
if (typeof(query_object.call_for_each_context) !== "boolean") {
|
||||||
|
query_object.call_for_each_context = true; // Default
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fire the added callback if it matches the current context
|
||||||
|
if (this.context !== '' && this._inArray(this.context, query_object.context)) {
|
||||||
|
query_object.match();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.callbacks[ this.callbacks.length - 1];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a query_object by reference.
|
||||||
|
* @returns Void(0)
|
||||||
|
*/
|
||||||
|
mq.removeQuery = function(query_object) {
|
||||||
|
if (query_object === null || query_object === undefined) return;
|
||||||
|
|
||||||
|
var match = -1;
|
||||||
|
|
||||||
|
while ((match = mq._indexOf(query_object,this.callbacks)) > -1) {
|
||||||
|
this.callbacks.splice(match, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loop through the stored callbacks and execute
|
||||||
|
* the ones that are bound to the current context.
|
||||||
|
* @returns Void(0)
|
||||||
|
*/
|
||||||
|
mq.triggerCallbacks = function(size, key) {
|
||||||
|
var i, callback_function, call_for_each_context;
|
||||||
|
|
||||||
|
for (i = 0; i < this.callbacks.length; i++) {
|
||||||
|
|
||||||
|
// Don't call for each context?
|
||||||
|
if(this.callbacks[i].call_for_each_context === false) {
|
||||||
|
if ((key === 'match' && this._inArray(this.context, this.callbacks[i].context)) ||
|
||||||
|
(key === 'unmatch' && this._inArray(this.new_context, this.callbacks[i].context))) {
|
||||||
|
// Was previously called, and we don't want to call it for each context
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
callback_function = this.callbacks[i][key];
|
||||||
|
if (this._inArray(size, this.callbacks[i].context) && callback_function !== undefined) {
|
||||||
|
callback_function();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Swiss Army Knife event binding, in lieu of jQuery.
|
||||||
|
* @returns Void(0)
|
||||||
|
*/
|
||||||
|
mq.addEvent = function(elem, type, eventHandle, eventContext) {
|
||||||
|
if (elem === null || elem === undefined) return;
|
||||||
|
// If the browser supports event listeners, use them.
|
||||||
|
if (elem.addEventListener) {
|
||||||
|
elem.addEventListener(type, function() { eventHandle.call(eventContext); }, false);
|
||||||
|
} else if (elem.attachEvent ) {
|
||||||
|
elem.attachEvent("on" + type, function() { eventHandle.call(eventContext); });
|
||||||
|
|
||||||
|
// Otherwise, replace the current thing bound to on[whatever]! Consider refactoring.
|
||||||
|
} else {
|
||||||
|
elem["on" + type] = function() { eventHandle.call(eventContext); };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to return the mediaquery's previous context
|
||||||
|
* @returns String returns the current mediaquery's context
|
||||||
|
*/
|
||||||
|
mq.getPreviousContext = function()
|
||||||
|
{
|
||||||
|
return this.context;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to return the mediaquery's current context
|
||||||
|
* @returns String returns the current mediaquery's context
|
||||||
|
*/
|
||||||
|
mq.getContext = function()
|
||||||
|
{
|
||||||
|
return this.new_context;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal helper function that checks wether "needle" occurs in "haystack"
|
||||||
|
* @param needle Mixed Value to look for in haystack array
|
||||||
|
* @param haystack Array Haystack array to search in
|
||||||
|
* @returns Boolan True if the needle occurs, false otherwise
|
||||||
|
*/
|
||||||
|
mq._inArray = function(needle, haystack)
|
||||||
|
{
|
||||||
|
var length = haystack.length;
|
||||||
|
for(var i = 0; i < length; i++) {
|
||||||
|
if(haystack[i] == needle) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IE8 do not supports Array.properties.indexOf
|
||||||
|
* copy from jQuery.
|
||||||
|
* in lieu of jQuery.
|
||||||
|
* @returns int
|
||||||
|
*/
|
||||||
|
mq._indexOf = function( elem, arr, i )
|
||||||
|
{
|
||||||
|
var len;
|
||||||
|
if ( arr ) {
|
||||||
|
if ( arr.indexOf ) {
|
||||||
|
return arr.indexOf( elem, i );
|
||||||
|
}
|
||||||
|
|
||||||
|
len = arr.length;
|
||||||
|
i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
|
||||||
|
|
||||||
|
for ( ; i < len; i++ ) {
|
||||||
|
// Skip accessing in sparse arrays
|
||||||
|
if ( i in arr && arr[ i ] === elem ) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expose the functions.
|
||||||
|
return mq;
|
||||||
|
}));
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
20258
frontend/delta/js/React/react-with-addons-0.11.0.js
Executable file
20258
frontend/delta/js/React/react-with-addons-0.11.0.js
Executable file
File diff suppressed because it is too large
Load Diff
948
frontend/delta/js/TestData/User.data.js
Normal file
948
frontend/delta/js/TestData/User.data.js
Normal file
File diff suppressed because one or more lines are too long
@ -44,12 +44,27 @@ MochiKit.Logging.logError("## MainController - GENERIC ERROR" + "\n" + "==>> " +
|
|||||||
React.initializeTouchEvents(true);
|
React.initializeTouchEvents(true);
|
||||||
|
|
||||||
Clipperz.PM.RunTime = {};
|
Clipperz.PM.RunTime = {};
|
||||||
function run() {
|
|
||||||
|
function initOnMediaQuery () {
|
||||||
|
MQ.init(MochiKit.Base.map(function (queryStyle) {
|
||||||
|
return {
|
||||||
|
context: queryStyle,
|
||||||
|
match: function () {
|
||||||
|
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'matchMediaQuery', queryStyle);
|
||||||
|
},
|
||||||
|
unmatch: function () {
|
||||||
|
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'unmatchMediaQuery', queryStyle);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
// }, ['extra-short', 'narrow', 'wide', 'extra-wide']));
|
||||||
|
}, Clipperz_PM_UI_availableStyles));
|
||||||
|
}
|
||||||
|
|
||||||
|
function run () {
|
||||||
var parameters = {};
|
var parameters = {};
|
||||||
|
|
||||||
Clipperz.PM.Strings.Languages.initSetup();
|
Clipperz.PM.Strings.Languages.initSetup();
|
||||||
|
|
||||||
|
|
||||||
if ((window.location.search.indexOf('registration') != -1) || (window.location.hash.indexOf('registration') != -1)) {
|
if ((window.location.search.indexOf('registration') != -1) || (window.location.hash.indexOf('registration') != -1)) {
|
||||||
parameters['shouldShowRegistrationForm'] = true;
|
parameters['shouldShowRegistrationForm'] = true;
|
||||||
} else {
|
} else {
|
||||||
@ -59,7 +74,29 @@ function run() {
|
|||||||
Clipperz.PM.DataModel.devicePreferences = new Clipperz.PM.DataModel.DevicePreferences({});
|
Clipperz.PM.DataModel.devicePreferences = new Clipperz.PM.DataModel.DevicePreferences({});
|
||||||
|
|
||||||
Clipperz.PM.RunTime.mainController = new Clipperz.PM.UI.MainController();
|
Clipperz.PM.RunTime.mainController = new Clipperz.PM.UI.MainController();
|
||||||
|
initOnMediaQuery();
|
||||||
Clipperz.PM.RunTime.mainController.run(parameters);
|
Clipperz.PM.RunTime.mainController.run(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
MochiKit.DOM.addLoadEvent(run);
|
MochiKit.DOM.addLoadEvent(run);
|
||||||
|
|
||||||
|
/* * /
|
||||||
|
MochiKit.DOM.addLoadEvent(simulateLogin);
|
||||||
|
function simulateLogin () {
|
||||||
|
var getURLParameter = function (name) {
|
||||||
|
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search)||[,""])[1].replace(/\+/g, '%20'))||null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
|
||||||
|
|
||||||
|
// MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'doLogin', {username:'joe', passphrase:'clipperz'}); // FULL
|
||||||
|
// http://localhost:8888/delta/index.html?username=joe&passphrase=clipperz
|
||||||
|
|
||||||
|
// MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'doLogin', {username:';', passphrase:';'}); // EXPIRED
|
||||||
|
// http://localhost:8888/delta/index.html?username=%3B&passphrase=%3B
|
||||||
|
|
||||||
|
if ((getURLParameter('u') != null) && (getURLParameter('p'))) {
|
||||||
|
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'doLogin', {username:getURLParameter('u'), passphrase:getURLParameter('p')});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/ * */
|
@ -7,7 +7,7 @@
|
|||||||
# MochiKit (http://www.mochikit.com)
|
# MochiKit (http://www.mochikit.com)
|
||||||
- repository: @mochikit.repository@ (version: @mochikit.version@ - commit: @mochikit.commit@)
|
- repository: @mochikit.repository@ (version: @mochikit.version@ - commit: @mochikit.commit@)
|
||||||
|
|
||||||
* Software licence: https://github.com/mochi/mochikit/blob/master/LICENSE.txt
|
* Software license: https://github.com/mochi/mochikit/blob/master/LICENSE.txt
|
||||||
|
|
||||||
| MochiKit is dual-licensed software. It is available under the terms of the
|
| MochiKit is dual-licensed software. It is available under the terms of the
|
||||||
| MIT License, or the Academic Free License version 2.1. The full text of
|
| MIT License, or the Academic Free License version 2.1. The full text of
|
||||||
@ -207,7 +207,7 @@
|
|||||||
# React.js (http://facebook.github.io/react/)
|
# React.js (http://facebook.github.io/react/)
|
||||||
- repository: @reactjs.repository@ (version: @reactjs.version@ - commit: @reactjs.commit@)
|
- repository: @reactjs.repository@ (version: @reactjs.version@ - commit: @reactjs.commit@)
|
||||||
|
|
||||||
* Software licence: https://github.com/facebook/react/blob/master/LICENSE
|
* Software license: https://github.com/facebook/react/blob/master/LICENSE
|
||||||
|
|
||||||
| Apache License
|
| Apache License
|
||||||
| Version 2.0, January 2004
|
| Version 2.0, January 2004
|
||||||
@ -413,10 +413,61 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Modernizr (http://modernizr.com)
|
||||||
|
- repository: @modernizr.repository@ (version: @modernizr.version@ - commit: @modernizr.commit@)
|
||||||
|
|
||||||
|
* Software license: http://modernizr.com/license/
|
||||||
|
|
||||||
|
| Copyright (c) 2009–2013
|
||||||
|
| Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
| of this software and associated documentation files (the "Software"), to deal
|
||||||
|
| in the Software without restriction, including without limitation the rights
|
||||||
|
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
| copies of the Software, and to permit persons to whom the Software is
|
||||||
|
| furnished to do so, subject to the following conditions:
|
||||||
|
| The above copyright notice and this permission notice shall be included in
|
||||||
|
| all copies or substantial portions of the Software.
|
||||||
|
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
| THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
# OnMediaQuery (https://github.com/JoshBarr/on-media-query)
|
||||||
|
- repository: @onmediaquery.repository@ (version: @onmediaquery.version@ - commit: @onmediaquery.commit@)
|
||||||
|
|
||||||
|
* Software license: http://opensource.org/licenses/mit-license.php
|
||||||
|
|
||||||
|
| The MIT License (MIT)
|
||||||
|
|
|
||||||
|
| Copyright (c) <year> <copyright holders>
|
||||||
|
|
|
||||||
|
| Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
| of this software and associated documentation files (the "Software"), to deal
|
||||||
|
| in the Software without restriction, including without limitation the rights
|
||||||
|
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
| copies of the Software, and to permit persons to whom the Software is
|
||||||
|
| furnished to do so, subject to the following conditions:
|
||||||
|
|
|
||||||
|
| The above copyright notice and this permission notice shall be included in
|
||||||
|
| all copies or substantial portions of the Software.
|
||||||
|
|
|
||||||
|
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
| THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
# Add to Home Screen (http://cubiq.org/add-to-home-screen)
|
# Add to Home Screen (http://cubiq.org/add-to-home-screen)
|
||||||
- repository: @addtohomescreen.repository@ (version: @addtohomescreen.version@ - commit: @addtohomescreen.commit@)
|
- repository: @addtohomescreen.repository@ (version: @addtohomescreen.version@ - commit: @addtohomescreen.commit@)
|
||||||
|
|
||||||
* Software licence: https://github.com/facebook/react/blob/master/LICENSE
|
* Software license: https://github.com/facebook/react/blob/master/LICENSE
|
||||||
|
|
||||||
| This software is released under the MIT License.
|
| This software is released under the MIT License.
|
||||||
|
|
|
|
||||||
@ -447,7 +498,7 @@
|
|||||||
|
|
||||||
Copyright © 2005-2006 Yahoo! Inc. All rights reserved
|
Copyright © 2005-2006 Yahoo! Inc. All rights reserved
|
||||||
* Copyright notes: http://docs.yahoo.com/info/copyright/copyright.html
|
* Copyright notes: http://docs.yahoo.com/info/copyright/copyright.html
|
||||||
* Software licence: http://developer.yahoo.com/yui/license.txt
|
* Software license: http://developer.yahoo.com/yui/license.txt
|
||||||
|
|
||||||
| Software License Agreement (BSD License)
|
| Software License Agreement (BSD License)
|
||||||
|
|
|
|
||||||
@ -485,7 +536,7 @@
|
|||||||
# YUI-ext (http://www.yui-ext.com)
|
# YUI-ext (http://www.yui-ext.com)
|
||||||
- repository: http://yui-ext.googlecode.com/svn/trunk/ (revision: 120)
|
- repository: http://yui-ext.googlecode.com/svn/trunk/ (revision: 120)
|
||||||
|
|
||||||
* Software licence: http://yui-ext.googlecode.com/svn/trunk/src/licence.txt
|
* Software license: http://yui-ext.googlecode.com/svn/trunk/src/licence.txt
|
||||||
|
|
||||||
| yui-ext
|
| yui-ext
|
||||||
| Copyright (c) 2006, Jack Slocum
|
| Copyright (c) 2006, Jack Slocum
|
||||||
|
@ -5,8 +5,16 @@
|
|||||||
"mochikit.commit": "6f26f745d5d915540aa0fc6c34fda24952891a9d",
|
"mochikit.commit": "6f26f745d5d915540aa0fc6c34fda24952891a9d",
|
||||||
|
|
||||||
"reactjs.repository": "https://github.com/facebook/react.git",
|
"reactjs.repository": "https://github.com/facebook/react.git",
|
||||||
"reactjs.version": "0.4.1",
|
"reactjs.version": "0.11.0",
|
||||||
"reactjs.commit": "0cac12d375264a8a232a426d6d6cc8074a94000a",
|
"reactjs.commit": "95d82cacd6e9cc6a2fe6366d79510cc9133886cb",
|
||||||
|
|
||||||
|
"modernizr.repository": "https://github.com/Modernizr/Modernizr",
|
||||||
|
"modernizr.version": "2.8.2",
|
||||||
|
"modernizr.commit": "99c09fa23a83f160a021c98b3644628aaec5e37a",
|
||||||
|
|
||||||
|
"onmediaquery.repository": "https://github.com/JoshBarr/on-media-query",
|
||||||
|
"onmediaquery.version": "0.2.0",
|
||||||
|
"onmediaquery.commit": "5080914636d392781ac858fb8eca9c0d99e5d35c",
|
||||||
|
|
||||||
"addtohomescreen.repository": "https://github.com/cubiq/add-to-homescreen.git",
|
"addtohomescreen.repository": "https://github.com/cubiq/add-to-homescreen.git",
|
||||||
"addtohomescreen.version": "2.0.8",
|
"addtohomescreen.version": "2.0.8",
|
||||||
@ -31,13 +39,14 @@
|
|||||||
"MochiKit/Selector.js",
|
"MochiKit/Selector.js",
|
||||||
"-- MochiKit/Visual.js",
|
"-- MochiKit/Visual.js",
|
||||||
|
|
||||||
"-- React/react-0.4.1.js",
|
"React/react-with-addons-0.11.0.js",
|
||||||
"React/react-0.5.0-alpha.js",
|
|
||||||
|
|
||||||
"-- Hammer/hammer-1.0.5.js",
|
"-- Hammer/hammer-1.0.5.js",
|
||||||
|
"-- Cubiq/add2home.js",
|
||||||
|
"-- Modernizr/modernizr-2.8.2.js",
|
||||||
|
"OnMediaQuery/onmediaquery-0.2.0.js",
|
||||||
|
|
||||||
"Cubiq/add2home.js",
|
"-- IT WOULD BE NICE TO BE ABLE TO GET RID OF THESE IMPORTS",
|
||||||
|
|
||||||
"Clipperz/YUI/Utils.js",
|
"Clipperz/YUI/Utils.js",
|
||||||
"Clipperz/YUI/DomHelper.js",
|
"Clipperz/YUI/DomHelper.js",
|
||||||
|
|
||||||
@ -45,14 +54,14 @@
|
|||||||
"Clipperz/Base.js",
|
"Clipperz/Base.js",
|
||||||
"Clipperz/Async.js",
|
"Clipperz/Async.js",
|
||||||
"Clipperz/CSVProcessor.js",
|
"Clipperz/CSVProcessor.js",
|
||||||
"Clipperz/KeePassExportProcessor.js",
|
"-- Clipperz/KeePassExportProcessor.js",
|
||||||
"Clipperz/Date.js",
|
"Clipperz/Date.js",
|
||||||
"Clipperz/DOM.js",
|
"-- Clipperz/DOM.js",
|
||||||
"Clipperz/Logging.js",
|
"Clipperz/Logging.js",
|
||||||
"Clipperz/Signal.js",
|
"Clipperz/Signal.js",
|
||||||
"-- Clipperz/Style.js",
|
"-- Clipperz/Style.js",
|
||||||
"-- Clipperz/Visual.js",
|
"-- Clipperz/Visual.js",
|
||||||
"Clipperz/Set.js",
|
"-- Clipperz/Set.js",
|
||||||
"-- Clipperz/Profile.js",
|
"-- Clipperz/Profile.js",
|
||||||
"Clipperz/KeyValueObjectStore.js",
|
"Clipperz/KeyValueObjectStore.js",
|
||||||
|
|
||||||
@ -104,7 +113,7 @@
|
|||||||
"Clipperz/PM/DataModel/User.Header.RecordIndex.js",
|
"Clipperz/PM/DataModel/User.Header.RecordIndex.js",
|
||||||
"Clipperz/PM/DataModel/User.Header.Preferences.js",
|
"Clipperz/PM/DataModel/User.Header.Preferences.js",
|
||||||
"Clipperz/PM/DataModel/User.Header.OneTimePasswords.js",
|
"Clipperz/PM/DataModel/User.Header.OneTimePasswords.js",
|
||||||
"Clipperz/PM/DataModel/User.Subscription.js",
|
"Clipperz/PM/DataModel/User.AccountInfo.js",
|
||||||
"Clipperz/PM/DataModel/Record.js",
|
"Clipperz/PM/DataModel/Record.js",
|
||||||
"Clipperz/PM/DataModel/Record.Version.js",
|
"Clipperz/PM/DataModel/Record.Version.js",
|
||||||
"Clipperz/PM/DataModel/Record.Version.Field.js",
|
"Clipperz/PM/DataModel/Record.Version.Field.js",
|
||||||
@ -124,21 +133,42 @@
|
|||||||
"-- Clipperz/PM/UI/Web/Controllers/MainController.js",
|
"-- Clipperz/PM/UI/Web/Controllers/MainController.js",
|
||||||
|
|
||||||
"Clipperz/PM/UI/Components/Overlay.js",
|
"Clipperz/PM/UI/Components/Overlay.js",
|
||||||
|
"Clipperz/PM/UI/Components/Button.js",
|
||||||
"Clipperz/PM/UI/Components/Checkbox.js",
|
"Clipperz/PM/UI/Components/Checkbox.js",
|
||||||
"Clipperz/PM/UI/Components/PageTemplate.js",
|
"Clipperz/PM/UI/Components/CardToolbar.js",
|
||||||
"Clipperz/PM/UI/Components/LoginForm.js",
|
"Clipperz/PM/UI/Components/MessageBox.js",
|
||||||
"Clipperz/PM/UI/Components/RegistrationWizard.js",
|
"Clipperz/PM/UI/Components/Selections.js",
|
||||||
"Clipperz/PM/UI/Components/CardList.js",
|
"Clipperz/PM/UI/Components/TagIndexItem.js",
|
||||||
"Clipperz/PM/UI/Components/CardDetail.js",
|
|
||||||
"Clipperz/PM/UI/Components/PreferencePage.js",
|
"Clipperz/PM/UI/Components/ExpiredPanel.js",
|
||||||
"Clipperz/PM/UI/Components/ErrorPage.js",
|
|
||||||
|
"Clipperz/PM/UI/Components/Pages/LoginPage.js",
|
||||||
|
"Clipperz/PM/UI/Components/Pages/RegistrationPage.js",
|
||||||
|
"Clipperz/PM/UI/Components/Pages/MainPage.js",
|
||||||
|
"Clipperz/PM/UI/Components/Pages/CardDetailPage.js",
|
||||||
|
"Clipperz/PM/UI/Components/Pages/ErrorPage.js",
|
||||||
|
|
||||||
|
"Clipperz/PM/UI/Components/Panels/SelectionPanel.js",
|
||||||
|
"Clipperz/PM/UI/Components/Panels/MainPanel.js",
|
||||||
|
"Clipperz/PM/UI/Components/Panels/ExtraFeaturesPanel.js",
|
||||||
|
|
||||||
|
"Clipperz/PM/UI/Components/Cards/List.js",
|
||||||
|
"Clipperz/PM/UI/Components/Cards/View.js",
|
||||||
|
"Clipperz/PM/UI/Components/Cards/Toolbar.js",
|
||||||
|
|
||||||
|
"Clipperz/PM/UI/Components/AccountStatus.js",
|
||||||
|
|
||||||
"Clipperz/PM/UI/MainController.js",
|
"Clipperz/PM/UI/MainController.js",
|
||||||
|
"-- Clipperz/PM/UI/MainDesktopController.js",
|
||||||
"Clipperz/PM/UI/DirectLoginController.js",
|
"Clipperz/PM/UI/DirectLoginController.js",
|
||||||
"main.js"
|
"main.js"
|
||||||
],
|
],
|
||||||
|
|
||||||
"css": [
|
"css": [
|
||||||
"web.css"
|
"clipperz.css"
|
||||||
|
],
|
||||||
|
|
||||||
|
"scss": [
|
||||||
|
"clipperz.scss"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
CACHE MANIFEST
|
CACHE MANIFEST
|
||||||
# 2013-10-01:v0.0.1
|
# @application.version@
|
||||||
|
|
||||||
CACHE:
|
CACHE:
|
||||||
# - Explicitly cached 'master entries'.
|
# - Explicitly cached 'master entries'.
|
||||||
index.html
|
#index.html
|
||||||
|
|
||||||
NETWORK:
|
NETWORK:
|
||||||
# - Resources that require the user to be online.
|
# - Resources that require the user to be online.
|
||||||
|
35
frontend/delta/scss/clipperz.scss
Normal file
35
frontend/delta/scss/clipperz.scss
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
@import "core/reset";
|
||||||
|
@import "core/palette";
|
||||||
|
@import "core/parameters";
|
||||||
|
@import "core/fonts";
|
||||||
|
@import "core/flex";
|
||||||
|
@import "core/overlay";
|
||||||
|
@import "core/behavior";
|
||||||
|
@import "core/layout";
|
||||||
|
|
||||||
|
@import "style/loadingPage";
|
||||||
|
@import "style/loginPage";
|
||||||
|
@import "style/registrationPage";
|
||||||
|
@import "style/selectionPanel";
|
||||||
|
@import "style/settingsPanel";
|
||||||
|
@import "style/accountStatus";
|
||||||
|
@import "style/card";
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: "clipperz-font";
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body:after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@import "core/sizes";
|
||||||
|
|
||||||
|
//@import "sizes/narrow";
|
||||||
|
//@import "sizes/wide";
|
||||||
|
//@import "sizes/extra-wide";
|
||||||
|
//@import "sizes/extra-short";
|
205
frontend/delta/scss/core/behavior.scss
Normal file
205
frontend/delta/scss/core/behavior.scss
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
// https://github.com/h5bp/Effeckt.css
|
||||||
|
// http://coenraets.org/blog/2013/03/hardware-accelerated-page-transitions-for-mobile-web-apps-phonegap-apps/
|
||||||
|
|
||||||
|
$transition-duration: 0.5s;
|
||||||
|
|
||||||
|
@mixin pageElement () {
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
@include transform3d(0, 0, 0);
|
||||||
|
@include transition-duration($transition-duration);
|
||||||
|
|
||||||
|
&.left {
|
||||||
|
@include transform3d(-100%, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.right {
|
||||||
|
@include transform3d(100%, 0, 0);
|
||||||
|
visibility: hidden;
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
&.transition {
|
||||||
|
visibility: visible;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
@mixin sliding-panel-left ($size) {
|
||||||
|
// background-color: yellow;
|
||||||
|
|
||||||
|
width: $size;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
top: 0;
|
||||||
|
left: -$size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin sliding-panel-right ($size) {
|
||||||
|
// background-color: green;
|
||||||
|
|
||||||
|
width: $size;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
top: 0;
|
||||||
|
right: -$size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin sliding-panel ($side, $size) {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 20;
|
||||||
|
overflow: scroll;
|
||||||
|
|
||||||
|
@if $side == left {
|
||||||
|
@include sliding-panel-left($size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $side == right {
|
||||||
|
@include sliding-panel-right($size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//.............................................................................
|
||||||
|
|
||||||
|
@mixin sliding-panel-open ($side, $size) {
|
||||||
|
@if $side == left {
|
||||||
|
left: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $side == right {
|
||||||
|
right: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//.............................................................................
|
||||||
|
|
||||||
|
@mixin sliding-panel-wrapper-open-left ($size) {
|
||||||
|
top: 0;
|
||||||
|
left: $size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin sliding-panel-wrapper-open-right ($size) {
|
||||||
|
top: 0;
|
||||||
|
right: $size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin sliding-panel-wrapper-open ($side, $size) {
|
||||||
|
@include sliding-panel-wrapper();
|
||||||
|
|
||||||
|
@if $side == left {
|
||||||
|
@include sliding-panel-wrapper-open-left($size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $side == right {
|
||||||
|
@include sliding-panel-wrapper-open-right($size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//.............................................................................
|
||||||
|
|
||||||
|
@mixin sliding-panel-wrapper () {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
position: relative;
|
||||||
|
z-index: 10;
|
||||||
|
// top: 0;
|
||||||
|
// left: 0;
|
||||||
|
// @include transition(all, $transition_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin sliding-panel-container () {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
.registrationForm {
|
||||||
|
.steps {
|
||||||
|
.step {
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
// top: 0;
|
||||||
|
// left: 0;
|
||||||
|
// width: 100%;
|
||||||
|
// height: 100%;
|
||||||
|
|
||||||
|
.slide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// tentative 3D transformations
|
||||||
|
/*
|
||||||
|
.page {
|
||||||
|
transform: rotateY( 0deg) translateZ( 100px);
|
||||||
|
|
||||||
|
&.left {
|
||||||
|
transform: rotateY( -90deg) translateZ( 100px);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.center {
|
||||||
|
transform: rotateY( 0deg) translateZ( 100px);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.right {
|
||||||
|
transform: rotateY( 90deg) translateZ( 100px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#mainDiv {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
transform-style: preserve-3d;
|
||||||
|
|
||||||
|
transition: transform 3s;
|
||||||
|
|
||||||
|
&.show-front { transform: translateZ( -100px ) rotateY( 0deg ); }
|
||||||
|
&.show-back { transform: translateZ( -100px ) rotateX( -180deg ); }
|
||||||
|
&.show-right { transform: translateZ( -100px ) rotateY( -90deg ); }
|
||||||
|
&.show-left { transform: translateZ( -100px ) rotateY( 90deg ); }
|
||||||
|
&.show-top { transform: translateZ( -100px ) rotateX( -90deg ); }
|
||||||
|
&.show-bottom { transform: translateZ( -100px ) rotateX( 90deg ); }
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
//=======================================================================
|
||||||
|
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
|
||||||
|
|
||||||
|
//=======================================================================
|
395
frontend/delta/scss/core/flex.scss
Normal file
395
frontend/delta/scss/core/flex.scss
Normal file
@ -0,0 +1,395 @@
|
|||||||
|
// Downloaded on June 8, 2014 from https://raw.githubusercontent.com/mastastealth/sass-flex-mixin/master/flex.scss
|
||||||
|
|
||||||
|
// Flexbox Mixins
|
||||||
|
// http://philipwalton.github.io/solved-by-flexbox/
|
||||||
|
// https://github.com/philipwalton/solved-by-flexbox
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013 Brian Franco
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the
|
||||||
|
// "Software"), to deal in the Software without restriction, including
|
||||||
|
// without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
// permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
// the following conditions:
|
||||||
|
// The above copyright notice and this permission notice shall be included
|
||||||
|
// in all copies or substantial portions of the Software.
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// This is a set of mixins for those who want to mess around with flexbox
|
||||||
|
// using the native support of current browsers. For full support table
|
||||||
|
// check: http://caniuse.com/flexbox
|
||||||
|
//
|
||||||
|
// Basically this will use:
|
||||||
|
//
|
||||||
|
// * Fallback, old syntax (IE10, Safari, mobile webkit browsers)
|
||||||
|
// * Prefixed standard syntax (Chrome)
|
||||||
|
// * Final standards syntax (FF, IE11, Opera 12.1)
|
||||||
|
//
|
||||||
|
// This was inspired by:
|
||||||
|
//
|
||||||
|
// * http://dev.opera.com/articles/view/advanced-cross-browser-flexbox/
|
||||||
|
//
|
||||||
|
// With help from:
|
||||||
|
//
|
||||||
|
// * http://w3.org/tr/css3-flexbox/
|
||||||
|
// * http://the-echoplex.net/flexyboxes/
|
||||||
|
// * http://msdn.microsoft.com/en-us/library/ie/hh772069(v=vs.85).aspx
|
||||||
|
// * http://css-tricks.com/using-flexbox/
|
||||||
|
// * http://dev.opera.com/articles/view/advanced-cross-browser-flexbox/
|
||||||
|
// * https://developer.mozilla.org/en-us/docs/web/guide/css/flexible_boxes
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Flexbox Containers
|
||||||
|
//
|
||||||
|
// The 'flex' value causes an element to generate a block-level flex
|
||||||
|
// container box.
|
||||||
|
//
|
||||||
|
// The 'inline-flex' value causes an element to generate a inline-level
|
||||||
|
// flex container box.
|
||||||
|
//
|
||||||
|
// display: flex | inline-flex
|
||||||
|
//
|
||||||
|
// http://w3.org/tr/css3-flexbox/#flex-containers
|
||||||
|
//
|
||||||
|
// (Placeholder selectors for each type, for those who rather @extend)
|
||||||
|
|
||||||
|
@mixin flexbox {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: -moz-flex;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
%flexbox { @include flexbox; }
|
||||||
|
|
||||||
|
//----------------------------------
|
||||||
|
|
||||||
|
@mixin inline-flex {
|
||||||
|
display: -webkit-inline-box;
|
||||||
|
display: -webkit-inline-flex;
|
||||||
|
display: -moz-inline-flex;
|
||||||
|
display: -ms-inline-flexbox;
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
%inline-flex { @include inline-flex; }
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Flexbox Direction
|
||||||
|
//
|
||||||
|
// The 'flex-direction' property specifies how flex items are placed in
|
||||||
|
// the flex container, by setting the direction of the flex container's
|
||||||
|
// main axis. This determines the direction that flex items are laid out in.
|
||||||
|
//
|
||||||
|
// Values: row | row-reverse | column | column-reverse
|
||||||
|
// Default: row
|
||||||
|
//
|
||||||
|
// http://w3.org/tr/css3-flexbox/#flex-direction-property
|
||||||
|
|
||||||
|
@mixin flex-direction($value: row) {
|
||||||
|
@if $value == row-reverse {
|
||||||
|
-webkit-box-direction: reverse;
|
||||||
|
-webkit-box-orient: horizontal;
|
||||||
|
} @else if $value == column {
|
||||||
|
-webkit-box-direction: normal;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
} @else if $value == column-reverse {
|
||||||
|
-webkit-box-direction: reverse;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
} @else {
|
||||||
|
-webkit-box-direction: normal;
|
||||||
|
-webkit-box-orient: horizontal;
|
||||||
|
}
|
||||||
|
-webkit-flex-direction: $value;
|
||||||
|
-moz-flex-direction: $value;
|
||||||
|
-ms-flex-direction: $value;
|
||||||
|
flex-direction: $value;
|
||||||
|
}
|
||||||
|
// Shorter version:
|
||||||
|
@mixin flex-dir($value: false) { @include flex-direction($value); }
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Flexbox Wrap
|
||||||
|
//
|
||||||
|
// The 'flex-wrap' property controls whether the flex container is single-line
|
||||||
|
// or multi-line, and the direction of the cross-axis, which determines
|
||||||
|
// the direction new lines are stacked in.
|
||||||
|
//
|
||||||
|
// Values: nowrap | wrap | wrap-reverse
|
||||||
|
// Default: nowrap
|
||||||
|
//
|
||||||
|
// http://w3.org/tr/css3-flexbox/#flex-wrap-property
|
||||||
|
|
||||||
|
@mixin flex-wrap($value: nowrap) {
|
||||||
|
// No Webkit Box fallback.
|
||||||
|
-webkit-flex-wrap: $value;
|
||||||
|
-moz-flex-wrap: $value;
|
||||||
|
@if $value == nowrap {
|
||||||
|
-ms-flex-wrap: none;
|
||||||
|
} @else {
|
||||||
|
-ms-flex-wrap: $value;
|
||||||
|
}
|
||||||
|
flex-wrap: $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Flexbox Flow (shorthand)
|
||||||
|
//
|
||||||
|
// The 'flex-flow' property is a shorthand for setting the 'flex-direction'
|
||||||
|
// and 'flex-wrap' properties, which together define the flex container's
|
||||||
|
// main and cross axes.
|
||||||
|
//
|
||||||
|
// Values: <flex-direction> | <flex-wrap>
|
||||||
|
// Default: row nowrap
|
||||||
|
//
|
||||||
|
// http://w3.org/tr/css3-flexbox/#flex-flow-property
|
||||||
|
|
||||||
|
@mixin flex-flow($values: (row nowrap)) {
|
||||||
|
// No Webkit Box fallback.
|
||||||
|
-webkit-flex-flow: $values;
|
||||||
|
-moz-flex-flow: $values;
|
||||||
|
-ms-flex-flow: $values;
|
||||||
|
flex-flow: $values;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Flexbox Order
|
||||||
|
//
|
||||||
|
// The 'order' property controls the order in which flex items appear within
|
||||||
|
// their flex container, by assigning them to ordinal groups.
|
||||||
|
//
|
||||||
|
// Default: 0
|
||||||
|
//
|
||||||
|
// http://w3.org/tr/css3-flexbox/#order-property
|
||||||
|
|
||||||
|
@mixin order($int: 0) {
|
||||||
|
-webkit-box-ordinal-group: $int + 1;
|
||||||
|
-webkit-order: $int;
|
||||||
|
-moz-order: $int;
|
||||||
|
-ms-flex-order: $int;
|
||||||
|
order: $int;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Flexbox Grow
|
||||||
|
//
|
||||||
|
// The 'flex-grow' property sets the flex grow factor. Negative numbers
|
||||||
|
// are invalid.
|
||||||
|
//
|
||||||
|
// Default: 0
|
||||||
|
//
|
||||||
|
// http://w3.org/tr/css3-flexbox/#flex-grow-property
|
||||||
|
|
||||||
|
@mixin flex-grow($int: 0) {
|
||||||
|
-webkit-box-flex: $int;
|
||||||
|
-webkit-flex-grow: $int;
|
||||||
|
-moz-flex-grow: $int;
|
||||||
|
-ms-flex-positive: $int;
|
||||||
|
flex-grow: $int;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Flexbox Shrink
|
||||||
|
//
|
||||||
|
// The 'flex-shrink' property sets the flex shrink factor. Negative numbers
|
||||||
|
// are invalid.
|
||||||
|
//
|
||||||
|
// Default: 1
|
||||||
|
//
|
||||||
|
// http://w3.org/tr/css3-flexbox/#flex-shrink-property
|
||||||
|
|
||||||
|
@mixin flex-shrink($int: 1) {
|
||||||
|
-webkit-flex-shrink: $int;
|
||||||
|
-moz-flex-shrink: $int;
|
||||||
|
-ms-flex-negative: $int;
|
||||||
|
flex-shrink: $int;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Flexbox Basis
|
||||||
|
//
|
||||||
|
// The 'flex-basis' property sets the flex basis. Negative lengths are invalid.
|
||||||
|
//
|
||||||
|
// Values: Like "width"
|
||||||
|
// Default: auto
|
||||||
|
//
|
||||||
|
// http://www.w3.org/TR/css3-flexbox/#flex-basis-property
|
||||||
|
|
||||||
|
@mixin flex-basis($value: auto) {
|
||||||
|
-webkit-flex-basis: $value;
|
||||||
|
-moz-flex-basis: $value;
|
||||||
|
-ms-flex-preferred-size: $value;
|
||||||
|
flex-basis: $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Flexbox "Flex" (shorthand)
|
||||||
|
//
|
||||||
|
// The 'flex' property specifies the components of a flexible length: the
|
||||||
|
// flex grow factor and flex shrink factor, and the flex basis. When an
|
||||||
|
// element is a flex item, 'flex' is consulted instead of the main size
|
||||||
|
// property to determine the main size of the element. If an element is
|
||||||
|
// not a flex item, 'flex' has no effect.
|
||||||
|
//
|
||||||
|
// Values: none | <flex-grow> <flex-shrink> || <flex-basis>
|
||||||
|
// Default: See individual properties (1 1 0).
|
||||||
|
//
|
||||||
|
// http://w3.org/tr/css3-flexbox/#flex-property
|
||||||
|
|
||||||
|
@mixin flex($fg: 1, $fs: null, $fb: null) {
|
||||||
|
|
||||||
|
// Set a variable to be used by box-flex properties
|
||||||
|
$fg-boxflex: $fg;
|
||||||
|
|
||||||
|
// Box-Flex only supports a flex-grow value so let's grab the
|
||||||
|
// first item in the list and just return that.
|
||||||
|
@if type-of($fg) == 'list' {
|
||||||
|
$fg-boxflex: nth($fg, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
-webkit-box-flex: $fg-boxflex;
|
||||||
|
-webkit-flex: $fg $fs $fb;
|
||||||
|
-moz-box-flex: $fg-boxflex;
|
||||||
|
-moz-flex: $fg $fs $fb;
|
||||||
|
-ms-flex: $fg $fs $fb;
|
||||||
|
flex: $fg $fs $fb;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Flexbox Justify Content
|
||||||
|
//
|
||||||
|
// The 'justify-content' property aligns flex items along the main axis
|
||||||
|
// of the current line of the flex container. This is done after any flexible
|
||||||
|
// lengths and any auto margins have been resolved. Typically it helps distribute
|
||||||
|
// extra free space leftover when either all the flex items on a line are
|
||||||
|
// inflexible, or are flexible but have reached their maximum size. It also
|
||||||
|
// exerts some control over the alignment of items when they overflow the line.
|
||||||
|
//
|
||||||
|
// Note: 'space-*' values not supported in older syntaxes.
|
||||||
|
//
|
||||||
|
// Values: flex-start | flex-end | center | space-between | space-around
|
||||||
|
// Default: flex-start
|
||||||
|
//
|
||||||
|
// http://w3.org/tr/css3-flexbox/#justify-content-property
|
||||||
|
|
||||||
|
@mixin justify-content($value: flex-start) {
|
||||||
|
@if $value == flex-start {
|
||||||
|
-webkit-box-pack: start;
|
||||||
|
-ms-flex-pack: start;
|
||||||
|
} @else if $value == flex-end {
|
||||||
|
-webkit-box-pack: end;
|
||||||
|
-ms-flex-pack: end;
|
||||||
|
} @else if $value == space-between {
|
||||||
|
-webkit-box-pack: justify;
|
||||||
|
-ms-flex-pack: justify;
|
||||||
|
} @else {
|
||||||
|
-webkit-box-pack: $value;
|
||||||
|
-ms-flex-pack: $value;
|
||||||
|
}
|
||||||
|
-webkit-justify-content: $value;
|
||||||
|
-moz-justify-content: $value;
|
||||||
|
justify-content: $value;
|
||||||
|
}
|
||||||
|
// Shorter version:
|
||||||
|
@mixin flex-just($value: flex-start) { @include justify-content($value); }
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Flexbox Align Items
|
||||||
|
//
|
||||||
|
// Flex items can be aligned in the cross axis of the current line of the
|
||||||
|
// flex container, similar to 'justify-content' but in the perpendicular
|
||||||
|
// direction. 'align-items' sets the default alignment for all of the flex
|
||||||
|
// container's items, including anonymous flex items. 'align-self' allows
|
||||||
|
// this default alignment to be overridden for individual flex items. (For
|
||||||
|
// anonymous flex items, 'align-self' always matches the value of 'align-items'
|
||||||
|
// on their associated flex container.)
|
||||||
|
//
|
||||||
|
// Values: flex-start | flex-end | center | baseline | stretch
|
||||||
|
// Default: stretch
|
||||||
|
//
|
||||||
|
// http://w3.org/tr/css3-flexbox/#align-items-property
|
||||||
|
|
||||||
|
@mixin align-items($value: stretch) {
|
||||||
|
@if $value == flex-start {
|
||||||
|
-webkit-box-align: start;
|
||||||
|
-ms-flex-align: start;
|
||||||
|
} @else if $value == flex-end {
|
||||||
|
-webkit-box-align: end;
|
||||||
|
-ms-flex-align: end;
|
||||||
|
} @else {
|
||||||
|
-webkit-box-align: $value;
|
||||||
|
-ms-flex-align: $value;
|
||||||
|
}
|
||||||
|
-webkit-align-items: $value;
|
||||||
|
-moz-align-items: $value;
|
||||||
|
align-items: $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------
|
||||||
|
|
||||||
|
// Flexbox Align Self
|
||||||
|
//
|
||||||
|
// Values: auto | flex-start | flex-end | center | baseline | stretch
|
||||||
|
// Default: auto
|
||||||
|
|
||||||
|
@mixin align-self($value: auto) {
|
||||||
|
// No Webkit Box Fallback.
|
||||||
|
-webkit-align-self: $value;
|
||||||
|
-moz-align-self: $value;
|
||||||
|
@if $value == flex-start {
|
||||||
|
-ms-flex-item-align: start;
|
||||||
|
} @else if $value == flex-end {
|
||||||
|
-ms-flex-item-align: end;
|
||||||
|
} @else {
|
||||||
|
-ms-flex-item-align: $value;
|
||||||
|
}
|
||||||
|
align-self: $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Flexbox Align Content
|
||||||
|
//
|
||||||
|
// The 'align-content' property aligns a flex container's lines within the
|
||||||
|
// flex container when there is extra space in the cross-axis, similar to
|
||||||
|
// how 'justify-content' aligns individual items within the main-axis. Note,
|
||||||
|
// this property has no effect when the flexbox has only a single line.
|
||||||
|
//
|
||||||
|
// Values: flex-start | flex-end | center | space-between | space-around | stretch
|
||||||
|
// Default: stretch
|
||||||
|
//
|
||||||
|
// http://w3.org/tr/css3-flexbox/#align-content-property
|
||||||
|
|
||||||
|
@mixin align-content($value: stretch) {
|
||||||
|
// No Webkit Box Fallback.
|
||||||
|
-webkit-align-content: $value;
|
||||||
|
-moz-align-content: $value;
|
||||||
|
@if $value == flex-start {
|
||||||
|
-ms-flex-line-pack: start;
|
||||||
|
} @else if $value == flex-end {
|
||||||
|
-ms-flex-line-pack: end;
|
||||||
|
} @else {
|
||||||
|
-ms-flex-line-pack: $value;
|
||||||
|
}
|
||||||
|
align-content: $value;
|
||||||
|
}
|
103
frontend/delta/scss/core/fonts.scss
Normal file
103
frontend/delta/scss/core/fonts.scss
Normal file
File diff suppressed because one or more lines are too long
289
frontend/delta/scss/core/layout.scss
Normal file
289
frontend/delta/scss/core/layout.scss
Normal file
@ -0,0 +1,289 @@
|
|||||||
|
@import "parameters";
|
||||||
|
|
||||||
|
.page {
|
||||||
|
@include pageElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
.mainPage {
|
||||||
|
// background-color: yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mainPage > #selectionPanel {
|
||||||
|
@include sliding-panel(left, $selectionPanelWidth);
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
@include sliding-panel-open(left, $selectionPanelWidth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#mainPanel {
|
||||||
|
// background-color: $yellow;
|
||||||
|
|
||||||
|
&.extra-wide {
|
||||||
|
@include sliding-panel-container();
|
||||||
|
|
||||||
|
.container {
|
||||||
|
@include flexbox;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subpanel {
|
||||||
|
|
||||||
|
&.selection {
|
||||||
|
@include flex($selectionPanelWidth, 0);
|
||||||
|
// height: 100%;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.cardContent {
|
||||||
|
@include flex($cardContentPanelWidth);
|
||||||
|
@include flexbox;
|
||||||
|
@include flex-direction(column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.selectionToggle {
|
||||||
|
.button {
|
||||||
|
display: none;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
&.wide, &.narrow {
|
||||||
|
.container {
|
||||||
|
@include sliding-panel-container();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.narrow {
|
||||||
|
.column {
|
||||||
|
@include pageElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.open.left {
|
||||||
|
@include sliding-panel-wrapper-open (left, $selectionPanelWidth);
|
||||||
|
@include mask();
|
||||||
|
}
|
||||||
|
|
||||||
|
&.open.right {
|
||||||
|
// @include sliding-panel-wrapper-open (right, $settingsPanelWidth);
|
||||||
|
@include mask();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#extraFeaturesPanel {
|
||||||
|
@include sliding-panel(right, $settingsPanelWidth);
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
@include sliding-panel-open(right, $settingsPanelWidth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardToolbarFrame {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
@include flexbox;
|
||||||
|
@include flex-direction(column);
|
||||||
|
|
||||||
|
.cardToolbar {
|
||||||
|
@include flex(none);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardContent {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
div.cardToolbar {
|
||||||
|
// background-color: $orange;
|
||||||
|
|
||||||
|
header {
|
||||||
|
@include flexbox;
|
||||||
|
height: $mainCardToolbarHeight;
|
||||||
|
line-height: $mainCardToolbarHeight;
|
||||||
|
|
||||||
|
background-color: $clipperz-orange;
|
||||||
|
color: white;
|
||||||
|
font-size: 24pt;
|
||||||
|
|
||||||
|
div {
|
||||||
|
|
||||||
|
&.clipperz {
|
||||||
|
|
||||||
|
span.logo {
|
||||||
|
@include icon-font();
|
||||||
|
|
||||||
|
@include align-self(center);
|
||||||
|
@include flex(4);
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&.tag, &.search {
|
||||||
|
font-size: 14pt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
span.value {
|
||||||
|
display: inline-block;
|
||||||
|
padding-left: 5px;
|
||||||
|
font-size: 18pt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selectionToggle {
|
||||||
|
@include flex(1);
|
||||||
|
|
||||||
|
.button {
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
.label {
|
||||||
|
padding-left: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// &.logo {
|
||||||
|
// @include align-self(center);
|
||||||
|
// @include flex(4);
|
||||||
|
// text-align: center;
|
||||||
|
// }
|
||||||
|
|
||||||
|
&.settingsToggle {
|
||||||
|
@include flex(1);
|
||||||
|
|
||||||
|
.button {
|
||||||
|
text-align: right;
|
||||||
|
|
||||||
|
.label {
|
||||||
|
padding-right: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: 24pt;
|
||||||
|
@include icon-font();
|
||||||
|
vertical-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
div.cardContent {
|
||||||
|
// @include flex(flex-grow); // ???
|
||||||
|
|
||||||
|
@include flexbox();
|
||||||
|
@include flex-direction(row);
|
||||||
|
|
||||||
|
div.cardListColumn.column {
|
||||||
|
@include flex($cardListWidth, 0);
|
||||||
|
overflow-y: scroll;
|
||||||
|
|
||||||
|
div.cardToolbar.narrow {
|
||||||
|
}
|
||||||
|
|
||||||
|
div.cardList {
|
||||||
|
overflow-y: scroll;
|
||||||
|
padding-bottom: 120px;
|
||||||
|
|
||||||
|
ul {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
div.addCardButton {
|
||||||
|
@include icon-font();
|
||||||
|
@include border-radius(50px);
|
||||||
|
@include radial-gradient (white, rgba(0, 0, 0, 0));
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
bottom: 0px;
|
||||||
|
font-size: 75pt;
|
||||||
|
color: blue;
|
||||||
|
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
|
||||||
|
float: right;
|
||||||
|
position: absolute;
|
||||||
|
margin-left: 100px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
div.cardDetail.column {
|
||||||
|
@include flex($cardDetailWidth);
|
||||||
|
|
||||||
|
@include flexbox();
|
||||||
|
|
||||||
|
div.view {
|
||||||
|
@include flex(auto);
|
||||||
|
|
||||||
|
@include flexbox;
|
||||||
|
@include flex-direction(column);
|
||||||
|
|
||||||
|
.cardDetailToolbar {
|
||||||
|
@include flex(none);
|
||||||
|
height: $mainCardToolbarHeight;
|
||||||
|
line-height: $mainCardToolbarHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
@include flex(auto);
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#cardDetailPage {
|
||||||
|
.view {
|
||||||
|
@include flexbox();
|
||||||
|
@include flex-direction(column);
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.cardDetailToolbar {
|
||||||
|
@include flex(none);
|
||||||
|
height: $mainCardToolbarHeight;
|
||||||
|
line-height: $mainCardToolbarHeight;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
@include flexbox();
|
||||||
|
@include flex-direction(row);
|
||||||
|
font-size: 24pt;
|
||||||
|
|
||||||
|
.back {
|
||||||
|
@include flex(auto);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardMenuOptions {
|
||||||
|
@include flex(auto);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
@include flex(auto);
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,19 @@
|
|||||||
@mixin border-radius ($radius) {
|
@mixin border-radius ($radius) {
|
||||||
border-radius: $radius;
|
|
||||||
-moz-border-radius: $radius;
|
|
||||||
-webkit-border-radius: $radius;
|
-webkit-border-radius: $radius;
|
||||||
|
-moz-border-radius: $radius;
|
||||||
|
border-radius: $radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin font-feature-settings($foo, $bar) {
|
@mixin radial-gradient ($inner-color, $outer-color) {
|
||||||
|
background-image: -ms-radial-gradient(center, circle farthest-corner, $inner-color 0%, $outer-color 100%); /* IE10 */
|
||||||
|
background-image: -moz-radial-gradient(center, circle farthest-corner, $inner-color 0%, $outer-color 100%); /* Mozilla Firefox */
|
||||||
|
background-image: -o-radial-gradient(center, circle farthest-corner, $inner-color 0%, $outer-color 100%); /* Opera */
|
||||||
|
background-image: -webkit-radial-gradient(center, circle farthest-corner, $inner-color 0%, $outer-color 100%); /* Webkit (Chrome 11+) */
|
||||||
|
background-image: radial-gradient(center, circle farthest-corner, $inner-color 0%, $outer-color 100%); /* Proposed W3C Markup */
|
||||||
|
background-image: -webkit-gradient(radial, center center, 0, center center, 495, color-stop(0, $inner-color), color-stop(1, $outer-color)); /* Webkit (Safari/Chrome 10) */
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin font-feature-settings ($foo, $bar) {
|
||||||
-webkit-font-feature-settings:"$foo","$bar";
|
-webkit-font-feature-settings:"$foo","$bar";
|
||||||
-moz-font-feature-settings:"$foo=1, $bar=1";
|
-moz-font-feature-settings:"$foo=1, $bar=1";
|
||||||
-moz-font-feature-settings:"$foo","$bar";
|
-moz-font-feature-settings:"$foo","$bar";
|
||||||
@ -13,14 +22,14 @@
|
|||||||
font-feature-settings:"$foo","$bar";
|
font-feature-settings:"$foo","$bar";
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin icon-font() {
|
@mixin icon-font () {
|
||||||
font-family: 'clipperz-icons';
|
font-family: 'clipperz-icons';
|
||||||
@include font-feature-settings("liga", "dlig");
|
@include font-feature-settings("liga", "dlig");
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
text-rendering:optimizeLegibility;
|
text-rendering:optimizeLegibility;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin password-font() {
|
@mixin password-font () {
|
||||||
font-family: 'clipperz-password';
|
font-family: 'clipperz-password';
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
text-rendering:optimizeLegibility;
|
text-rendering:optimizeLegibility;
|
||||||
@ -60,10 +69,10 @@
|
|||||||
|
|
||||||
@mixin transition ($item, $time, $function) {
|
@mixin transition ($item, $time, $function) {
|
||||||
-webkit-transition: $item $time $function;
|
-webkit-transition: $item $time $function;
|
||||||
-moz-transition: $item $time $function;
|
-moz-transition: $item $time $function;
|
||||||
-o-transition: $item $time $function;
|
-o-transition: $item $time $function;
|
||||||
-ms-transition: $item $time $function;
|
-ms-transition: $item $time $function;
|
||||||
transition: $item $time $function;
|
transition: $item $time $function;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin transform ($rotateAngle, $translateX, $translateY) {
|
@mixin transform ($rotateAngle, $translateX, $translateY) {
|
||||||
@ -74,6 +83,16 @@
|
|||||||
transform: rotate( $rotateAngle) translate($translateX, $translateY);
|
transform: rotate( $rotateAngle) translate($translateX, $translateY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin transform3d ($tx, $ty, $tz) {
|
||||||
|
-webkit-transform: translate3d($tx, $ty, $tz);
|
||||||
|
transform: translate3d($tx, $ty, $tz);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin transition-duration ($duration) {
|
||||||
|
-webkit-transition-duration: $duration;
|
||||||
|
transition-duration: $duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@mixin animation-delay ($delay) {
|
@mixin animation-delay ($delay) {
|
||||||
-webkit-animation-delay: $delay;
|
-webkit-animation-delay: $delay;
|
||||||
@ -91,7 +110,7 @@
|
|||||||
box-shadow: $xOffset $yOffset $size $color;
|
box-shadow: $xOffset $yOffset $size $color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin keyframes($name) {
|
@mixin keyframes ($name) {
|
||||||
@-webkit-keyframes #{$name} {
|
@-webkit-keyframes #{$name} {
|
||||||
@content;
|
@content;
|
||||||
}
|
}
|
||||||
@ -105,3 +124,20 @@
|
|||||||
@content;
|
@content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin mask () {
|
||||||
|
.mask {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 10;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include keyframes(spin) {
|
||||||
|
0% { @include transform(0deg, 0, 0); }
|
||||||
|
100% { @include transform(359deg, 0, 0); }
|
||||||
|
}
|
@ -14,7 +14,7 @@ div.overlay {
|
|||||||
|
|
||||||
.title {
|
.title {
|
||||||
color: #FFF;
|
color: #FFF;
|
||||||
font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
|
// font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
display: block;
|
display: block;
|
44
frontend/delta/scss/core/palette.scss
Normal file
44
frontend/delta/scss/core/palette.scss
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
//
|
||||||
|
// SOLARIZED palette
|
||||||
|
// http://ethanschoonover.com/solarized
|
||||||
|
//
|
||||||
|
$solarize-Background-15: #002b36;
|
||||||
|
$solarize-Background-20: #073642;
|
||||||
|
|
||||||
|
$solarize-Content-45: #586375;
|
||||||
|
$solarize-Content-50: #657b83;
|
||||||
|
$solarize-Content-60: #839496;
|
||||||
|
$solarize-Content-65: #93a1a1;
|
||||||
|
|
||||||
|
$solarize-Background-92: #eee8d5;
|
||||||
|
$solarize-Background-97: #fdf6e3;
|
||||||
|
|
||||||
|
$solarize-Accent-Yellow: #b58900;
|
||||||
|
$solarize-Accent-Orange: #cb4b16;
|
||||||
|
$solarize-Accent-Red: #dc322f;
|
||||||
|
$solarize-Accent-Magenta: #d33682;
|
||||||
|
$solarize-Accent-Violet: #6c71c4;
|
||||||
|
$solarize-Accent-Blue: #268bd2;
|
||||||
|
$solarize-Accent-Cyan: #2aa198;
|
||||||
|
$solarize-Accent-Green: #859900;
|
||||||
|
|
||||||
|
// $yellow: $solarize-Accent-Yellow;
|
||||||
|
// $orange: $solarize-Accent-Orange;
|
||||||
|
// $red: $solarize-Accent-Red;
|
||||||
|
// $magenta: $solarize-Accent-Magenta;
|
||||||
|
// $violete: $solarize-Accent-Violet;
|
||||||
|
// $blue: $solarize-Accent-Blue;
|
||||||
|
// $cyan: $solarize-Accent-Cyan;
|
||||||
|
// $green: $solarize-Accent-Green;
|
||||||
|
|
||||||
|
$clipperz-orange: #ff9900;
|
||||||
|
$clipperz-blue: #1863a1;
|
||||||
|
$terminal-green: #23ff18;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$main-color: $clipperz-orange;
|
||||||
|
$main-text-color: black;
|
||||||
|
|
||||||
|
$main-alternate-color: black;
|
||||||
|
$main-alternate-text-color: white;
|
15
frontend/delta/scss/core/parameters.scss
Normal file
15
frontend/delta/scss/core/parameters.scss
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//$selectionPanelWidth: 200px;
|
||||||
|
//$cardListWidth: 200px;
|
||||||
|
|
||||||
|
$selectionPanelWidth: 1;
|
||||||
|
$cardContentPanelWidth: 4;
|
||||||
|
|
||||||
|
$mainCardToolbarHeight: 48px;
|
||||||
|
|
||||||
|
$cardListWidth: 1;
|
||||||
|
$cardDetailWidth: 2;
|
||||||
|
|
||||||
|
$selectionPanelWidth: 300px;
|
||||||
|
$settingsPanelWidth: 300px;
|
||||||
|
|
||||||
|
|
43
frontend/delta/scss/core/reset.scss
Normal file
43
frontend/delta/scss/core/reset.scss
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Downloaded on June 11, 2014 from: https://gist.github.com/hcatlin/1027867
|
||||||
|
|
||||||
|
/* http://meyerweb.com/eric/tools/css/reset/
|
||||||
|
v2.0 | 20110126
|
||||||
|
License: none (public domain)
|
||||||
|
*/
|
||||||
|
|
||||||
|
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
font-size: 100%;
|
||||||
|
font: inherit;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* HTML5 display-role reset for older browsers */
|
||||||
|
|
||||||
|
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol, ul {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote, q {
|
||||||
|
quotes: none;
|
||||||
|
|
||||||
|
&:before, &:after, {
|
||||||
|
content: '';
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
52
frontend/delta/scss/core/sizes.scss
Normal file
52
frontend/delta/scss/core/sizes.scss
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Bootstrap CSS suggests these size breakpoints:
|
||||||
|
|
||||||
|
- Extra small devices Phones (<768px)
|
||||||
|
- Small devices Tablets (≥768px)
|
||||||
|
- Medium devices Desktops (≥992px)
|
||||||
|
- Large devices Desktops (≥1200px)
|
||||||
|
|
||||||
|
|
||||||
|
# ATTENTION
|
||||||
|
When adding a new 'size', remember to update also MQ.init invocation in main.js.
|
||||||
|
This configuration is now located in the first script included in the index_template.html file.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
@media only screen and (min-width: 100px) {
|
||||||
|
html {
|
||||||
|
font-family: "narrow";
|
||||||
|
}
|
||||||
|
body:after {
|
||||||
|
content: "narrow";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media only screen and (min-width: 700px) {
|
||||||
|
html {
|
||||||
|
font-family: "wide";
|
||||||
|
}
|
||||||
|
body:after {
|
||||||
|
content: "wide";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: 1100px) {
|
||||||
|
html {
|
||||||
|
font-family: "extra-wide";
|
||||||
|
}
|
||||||
|
body:after {
|
||||||
|
content: "extra-wide";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: 100px) and (max-height: 450px) {
|
||||||
|
html {
|
||||||
|
font-family: "extra-short";
|
||||||
|
}
|
||||||
|
body:after {
|
||||||
|
content: "extra-short";
|
||||||
|
}
|
||||||
|
}
|
27
frontend/delta/scss/style/accountStatus.scss
Normal file
27
frontend/delta/scss/style/accountStatus.scss
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
.accountStatus {
|
||||||
|
background-color: green;
|
||||||
|
|
||||||
|
&.FULL {
|
||||||
|
display: none;
|
||||||
|
visibility: hidden;
|
||||||
|
|
||||||
|
&.isExpiring {
|
||||||
|
display: block;
|
||||||
|
visibility: visible;
|
||||||
|
|
||||||
|
background-color: yellow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.TRIAL {
|
||||||
|
background-color: orange;
|
||||||
|
|
||||||
|
&.isExpiring {
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.EXPIRED {
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
|
}
|
270
frontend/delta/scss/style/card.scss
Normal file
270
frontend/delta/scss/style/card.scss
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
$cardListHeight: 48px;
|
||||||
|
$faviconSize: 32px;
|
||||||
|
$padding: ($cardListHeight - $faviconSize) / 2;
|
||||||
|
|
||||||
|
$cardToolbarBackgroundColor: brown;
|
||||||
|
|
||||||
|
div.cardList {
|
||||||
|
// background-color: $yellow;
|
||||||
|
|
||||||
|
&.loadingCard {
|
||||||
|
li.selected {
|
||||||
|
background-color: gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
li.selected {
|
||||||
|
background-color: yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
|
||||||
|
@include flexbox();
|
||||||
|
@include flex-direction(row);
|
||||||
|
|
||||||
|
.favicon {
|
||||||
|
width: $cardListHeight;
|
||||||
|
@include flex(none);
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: $faviconSize;
|
||||||
|
height: $faviconSize;
|
||||||
|
padding: $padding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
@include flex(auto);
|
||||||
|
|
||||||
|
font-size: 18pt;
|
||||||
|
|
||||||
|
padding-top: 0.5em;
|
||||||
|
padding-bottom: 0.5em;
|
||||||
|
padding-left: $padding;
|
||||||
|
padding-right: $padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
div.cardList.narrow {
|
||||||
|
&.loadingCard {
|
||||||
|
li.selected {
|
||||||
|
// background-color: gray;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
color: white;
|
||||||
|
margin-right: 10px;
|
||||||
|
content: "loading";
|
||||||
|
@include animation(spin, 1s, linear, infinite);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
li {
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: "show detail";
|
||||||
|
@include flex(none);
|
||||||
|
@include icon-font();
|
||||||
|
height: 48px;
|
||||||
|
font-size: 24pt;
|
||||||
|
line-height: 48px;
|
||||||
|
margin-right: 25px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$cardViewBasePadding: 10px;
|
||||||
|
|
||||||
|
#cardDetailPage, .cardDetail {
|
||||||
|
.loading {
|
||||||
|
// height: 100%;
|
||||||
|
// width: 100%;
|
||||||
|
// background-color: rgba(0,0,0,0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.view {
|
||||||
|
|
||||||
|
.cardDetailToolbar {
|
||||||
|
|
||||||
|
ul {
|
||||||
|
@include flexbox();
|
||||||
|
@include flex-direction(row);
|
||||||
|
|
||||||
|
li {
|
||||||
|
@include flex(auto);
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
span {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.narrow {
|
||||||
|
.back {
|
||||||
|
@include icon-font();
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardMenuOptions {
|
||||||
|
@include icon-font();
|
||||||
|
text-align: right;
|
||||||
|
font-size: 18pt;
|
||||||
|
padding-right: 10px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.commandMenu {
|
||||||
|
// display: none;
|
||||||
|
.commandMenuMask {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.commandMenu {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.show {
|
||||||
|
|
||||||
|
.commandMenuMask {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.commandMenu {
|
||||||
|
display: block;
|
||||||
|
float: right;
|
||||||
|
position: absolute;
|
||||||
|
min-width: 200px;
|
||||||
|
top: 48px;
|
||||||
|
right: 5px;
|
||||||
|
color: black;
|
||||||
|
background-color: white;
|
||||||
|
@include box-shadow(0px, 2px, 5px, rgba(50, 50, 50, 0.75));
|
||||||
|
|
||||||
|
ul {
|
||||||
|
@include flex-direction(column);
|
||||||
|
|
||||||
|
li {
|
||||||
|
text-align: left;
|
||||||
|
font-size: 18pt;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-bottom: 1px solid black;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.cardDetailToolbar {
|
||||||
|
background-color: $cardToolbarBackgroundColor;
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
&.narrow {
|
||||||
|
|
||||||
|
.cardMenuOptions {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
.cardLabel {
|
||||||
|
font-size: 24pt;
|
||||||
|
padding: $cardViewBasePadding;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardTags {
|
||||||
|
@include flexbox();
|
||||||
|
@include flex-direction(row);
|
||||||
|
@include align-items(flex-start);
|
||||||
|
|
||||||
|
padding: $cardViewBasePadding;
|
||||||
|
|
||||||
|
.cardTag {
|
||||||
|
@include flex(none);
|
||||||
|
font-size: 14pt;
|
||||||
|
padding-right: 10px;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: 'tag';
|
||||||
|
@include icon-font();
|
||||||
|
font-size: 10pt;
|
||||||
|
padding-right: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardNotes {
|
||||||
|
padding: $cardViewBasePadding;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardField {
|
||||||
|
@include flexbox;
|
||||||
|
@include flex-direction(row);
|
||||||
|
|
||||||
|
.fieldValues {
|
||||||
|
@include flex(1);
|
||||||
|
padding: $cardViewBasePadding;
|
||||||
|
|
||||||
|
.fieldLabel {
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fieldValue {
|
||||||
|
font-size: 18pt;
|
||||||
|
|
||||||
|
&.hidden {
|
||||||
|
font-family: clipperz-password;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.fieldAction {
|
||||||
|
@include flex(none);
|
||||||
|
@include align-self(center);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
@include icon-font();
|
||||||
|
font-size: 20pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardDirectLogin {
|
||||||
|
font-size: 18pt;
|
||||||
|
padding: $cardViewBasePadding;
|
||||||
|
background-color: pink;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
32
frontend/delta/scss/style/loadingPage.scss
Normal file
32
frontend/delta/scss/style/loadingPage.scss
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// $Loading_outer_color: $main-color;
|
||||||
|
// $Loading_inner-color: lighten($Loading_outer-color, 30%);
|
||||||
|
//
|
||||||
|
// $Loading_h1-color: lighten($Loading_inner-color, 70%);
|
||||||
|
// $Loading_h3-color: darken($Loading_outer-color, 20%);
|
||||||
|
|
||||||
|
#loadingPage {
|
||||||
|
// @include radial-gradient($Loading_inner-color, $Loading_outer-color);
|
||||||
|
background-color: $main-color;
|
||||||
|
|
||||||
|
div {
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 40pt;
|
||||||
|
font-weight: bold;
|
||||||
|
// color: $Loading_h1-color;
|
||||||
|
color: $main-alternate-text-color;
|
||||||
|
margin-top: 10%;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 18pt;
|
||||||
|
// color: $Loading_h3-color;
|
||||||
|
color: $main-text-color;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
151
frontend/delta/scss/style/loginPage.scss
Normal file
151
frontend/delta/scss/style/loginPage.scss
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
#loginPage {
|
||||||
|
overflow: scroll;
|
||||||
|
|
||||||
|
div.loginForm {
|
||||||
|
@include flexbox;
|
||||||
|
@include flex-direction(column);
|
||||||
|
@include align-items(stretch);
|
||||||
|
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
background-color: $main-color;
|
||||||
|
|
||||||
|
header {
|
||||||
|
@include flex(1);
|
||||||
|
@include icon-font();
|
||||||
|
|
||||||
|
font-size: 48pt;
|
||||||
|
color: $main-alternate-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.form {
|
||||||
|
@include flex(4);
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
|
||||||
|
form {
|
||||||
|
position: relative;
|
||||||
|
background: $main-alternate-text-color;
|
||||||
|
|
||||||
|
// @include border-radius(10px);
|
||||||
|
padding: 20px;
|
||||||
|
margin-bottom: 50px;
|
||||||
|
/*
|
||||||
|
&:after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: -15px;
|
||||||
|
margin-left: 50%;
|
||||||
|
left: -15px;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 15px 15px;
|
||||||
|
border-color: $main-alternate-text-color transparent;
|
||||||
|
display: block;
|
||||||
|
width: 0;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
label {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
font-family: "clipperz-font";
|
||||||
|
display: block;
|
||||||
|
// @include border-radius(4px);
|
||||||
|
padding: 5px;
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size: 100%;
|
||||||
|
// box-shadow:inset 0 0 0;
|
||||||
|
font-size: 24pt;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
font-family: "clipperz-font";
|
||||||
|
min-height: 48px;
|
||||||
|
min-width: 48px;
|
||||||
|
|
||||||
|
color: white;
|
||||||
|
font-size: 24pt;
|
||||||
|
font-weight: 500;
|
||||||
|
border: 0px;
|
||||||
|
|
||||||
|
padding: 10px 25px;
|
||||||
|
|
||||||
|
border: 1px solid white;
|
||||||
|
background-color: $main-color;
|
||||||
|
@include transition(background-color font-weight, 0.2s, linear);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
};
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
font-weight: 100;
|
||||||
|
background-color: #c0c0c0;
|
||||||
|
cursor: default;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
div.registrationLink {
|
||||||
|
@include flex(1);
|
||||||
|
|
||||||
|
color: $main-alternate-text-color;
|
||||||
|
background-color: $main-alternate-color;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 24pt;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: "> ";
|
||||||
|
};
|
||||||
|
|
||||||
|
a {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
div.loginForm.extra-short {
|
||||||
|
header {
|
||||||
|
// @include flex(1);
|
||||||
|
font-size: 18pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.form {
|
||||||
|
// @include flex(6);
|
||||||
|
form {
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
input {
|
||||||
|
padding: 3px;
|
||||||
|
margin-top: 3px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
font-size: 16pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
min-height: 20px;
|
||||||
|
|
||||||
|
font-size: 12pt;
|
||||||
|
padding: 3px 10px;
|
||||||
|
border: 1px solid white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
div.registrationLink {
|
||||||
|
// @include flex(2);
|
||||||
|
font-size: 14pt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
111
frontend/delta/scss/style/registrationPage.scss
Normal file
111
frontend/delta/scss/style/registrationPage.scss
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
#registrationPage {
|
||||||
|
background-color: $main-alternate-color;
|
||||||
|
color: $main-alternate-text-color;
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
display: block;
|
||||||
|
border: 1px solid $solarize-Background-92;
|
||||||
|
@include border-radius(6px);
|
||||||
|
padding: 5px;
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size: 100%;
|
||||||
|
box-shadow:inset 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.steps {
|
||||||
|
.step {
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
&.center {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
color: $solarize-Accent-Blue;
|
||||||
|
font-size: 24pt;
|
||||||
|
font-weight: 700;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
color: $solarize-Content-50;
|
||||||
|
font-size: 14pt;
|
||||||
|
font-weight: 100;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.TERMS_OF_SERVICE {
|
||||||
|
.checkboxBlock {
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
clear: both;
|
||||||
|
|
||||||
|
input {
|
||||||
|
display: block;
|
||||||
|
float: left;
|
||||||
|
margin: 5px;
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 12pt;
|
||||||
|
font-weight: 500;
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $solarize-Accent-Red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.stepIndex {
|
||||||
|
text-align: center;
|
||||||
|
.stepIndexItem {
|
||||||
|
font-weight: 900;
|
||||||
|
font-size: 28pt;
|
||||||
|
display: inline;
|
||||||
|
color: lightgrey;
|
||||||
|
|
||||||
|
&.center {
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.buttons {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 10px;
|
||||||
|
|
||||||
|
.button {
|
||||||
|
margin: 10px;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
display: inline-block;
|
||||||
|
width: 80px;
|
||||||
|
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 45px;
|
||||||
|
font-size: 24px;
|
||||||
|
|
||||||
|
&.back {
|
||||||
|
|
||||||
|
background-color: lightgrey;
|
||||||
|
|
||||||
|
// &.step_-1 {
|
||||||
|
// visibility: hidden;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
background-color: #c0c0c0;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
69
frontend/delta/scss/style/selectionPanel.scss
Normal file
69
frontend/delta/scss/style/selectionPanel.scss
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#selections {
|
||||||
|
background-color: $main-alternate-color;
|
||||||
|
color: $main-alternate-text-color;
|
||||||
|
font-size: 18pt;
|
||||||
|
overflow: scroll;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
$iconColumnWidth: 40px;
|
||||||
|
|
||||||
|
ul.defaultSet {
|
||||||
|
font-weight: bold;
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
&.allCards:before {
|
||||||
|
content: "clipperz";
|
||||||
|
}
|
||||||
|
|
||||||
|
&.recentCards:before {
|
||||||
|
content: "recent";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.search {
|
||||||
|
label {
|
||||||
|
@include icon-font();
|
||||||
|
font-size: 18pt;
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right:5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
font-family: "clipperz-font";
|
||||||
|
color: #999;
|
||||||
|
font-size: 18pt;
|
||||||
|
width: $selectionPanelWidth - $iconColumnWidth - 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.tagList {
|
||||||
|
padding-top: 10px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
&:before {
|
||||||
|
content: "tag";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
padding-left: 35px;
|
||||||
|
text-indent: -35px;
|
||||||
|
|
||||||
|
padding-top: 7px;
|
||||||
|
padding-bottom: 7px;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
@include icon-font();
|
||||||
|
font-weight: normal;
|
||||||
|
padding-left: 8px;
|
||||||
|
padding-right: 8px;
|
||||||
|
font-size: 14pt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
frontend/delta/scss/style/settingsPanel.scss
Normal file
19
frontend/delta/scss/style/settingsPanel.scss
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#extraFeaturesPanel {
|
||||||
|
background-color: $main-alternate-color;
|
||||||
|
color: $main-alternate-text-color;
|
||||||
|
|
||||||
|
header {
|
||||||
|
text-align: right;
|
||||||
|
height: 48px;
|
||||||
|
font-size: 24pt;
|
||||||
|
|
||||||
|
.button {
|
||||||
|
@include icon-font();
|
||||||
|
|
||||||
|
.label {
|
||||||
|
padding-top: 8px;
|
||||||
|
padding-right: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +0,0 @@
|
|||||||
@import "web/fonts";
|
|
||||||
@import "web/overlay";
|
|
||||||
@import "web/behavior";
|
|
||||||
@import "web/style";
|
|
||||||
@import "web/checkbox";
|
|
||||||
@import "web/480";
|
|
||||||
@import "web/768";
|
|
||||||
@import "web/992";
|
|
||||||
|
|
||||||
@import "web/add2home";
|
|
@ -1,11 +0,0 @@
|
|||||||
@media only screen and (min-width: 480px) {
|
|
||||||
.loginForm {
|
|
||||||
font-size: 1.2em;
|
|
||||||
|
|
||||||
input {
|
|
||||||
}
|
|
||||||
button {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
|||||||
@media only screen and (min-width: 768px) {
|
|
||||||
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
@media only screen and (min-width: 992px) {
|
|
||||||
}
|
|
@ -1,160 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* Main container
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#addToHomeScreen {
|
|
||||||
z-index:9999;
|
|
||||||
-webkit-user-select:none;
|
|
||||||
user-select:none;
|
|
||||||
-webkit-box-sizing:border-box;
|
|
||||||
box-sizing:border-box;
|
|
||||||
-webkit-touch-callout:none;
|
|
||||||
touch-callout:none;
|
|
||||||
width:240px;
|
|
||||||
font-size:15px;
|
|
||||||
padding:12px 14px;
|
|
||||||
text-align:left;
|
|
||||||
font-family:helvetica;
|
|
||||||
background-image:-webkit-gradient(linear,0 0,0 100%,color-stop(0,#fff),color-stop(0.02,#eee),color-stop(0.98,#ccc),color-stop(1,#a3a3a3));
|
|
||||||
border:1px solid #505050;
|
|
||||||
-webkit-border-radius:8px;
|
|
||||||
-webkit-background-clip:padding-box;
|
|
||||||
color:#333;
|
|
||||||
text-shadow:0 1px 0 rgba(255,255,255,0.75);
|
|
||||||
line-height:130%;
|
|
||||||
-webkit-box-shadow:0 0 4px rgba(0,0,0,0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
#addToHomeScreen.addToHomeIpad {
|
|
||||||
width:268px;
|
|
||||||
font-size:18px;
|
|
||||||
padding:14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* The 'wide' class is added when the popup contains the touch icon
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#addToHomeScreen.addToHomeWide {
|
|
||||||
width:296px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#addToHomeScreen.addToHomeIpad.addToHomeWide {
|
|
||||||
width:320px;
|
|
||||||
font-size:18px;
|
|
||||||
padding:14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* The balloon arrow
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#addToHomeScreen .addToHomeArrow {
|
|
||||||
position:absolute;
|
|
||||||
background-image:-webkit-gradient(linear,0 0,100% 100%,color-stop(0,rgba(204,204,204,0)),color-stop(0.4,rgba(204,204,204,0)),color-stop(0.4,#ccc));
|
|
||||||
border-width:0 1px 1px 0;
|
|
||||||
border-style:solid;
|
|
||||||
border-color:#505050;
|
|
||||||
width:16px; height:16px;
|
|
||||||
-webkit-transform:rotateZ(45deg);
|
|
||||||
bottom:-9px; left:50%;
|
|
||||||
margin-left:-8px;
|
|
||||||
-webkit-box-shadow:inset -1px -1px 0 #a9a9a9;
|
|
||||||
-webkit-border-bottom-right-radius:2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* The balloon arrow for iPad
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#addToHomeScreen.addToHomeIpad .addToHomeArrow {
|
|
||||||
-webkit-transform:rotateZ(-135deg);
|
|
||||||
background-image:-webkit-gradient(linear,0 0,100% 100%,color-stop(0,rgba(238,238,238,0)),color-stop(0.4,rgba(238,238,238,0)),color-stop(0.4,#eee));
|
|
||||||
-webkit-box-shadow:inset -1px -1px 0 #fff;
|
|
||||||
top:-9px; bottom:auto; left:50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Close button
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#addToHomeScreen .addToHomeClose {
|
|
||||||
-webkit-box-sizing:border-box;
|
|
||||||
position:absolute;
|
|
||||||
right:4px;
|
|
||||||
top:4px;
|
|
||||||
width:18px;
|
|
||||||
height:18px; line-height:14px;
|
|
||||||
text-align:center;
|
|
||||||
text-indent:1px;
|
|
||||||
-webkit-border-radius:9px;
|
|
||||||
background:rgba(0,0,0,0.12);
|
|
||||||
color:#707070;
|
|
||||||
-webkit-box-shadow:0 1px 0 #fff;
|
|
||||||
font-size:16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* The '+' icon, displayed only on iOS < 4.2
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#addToHomeScreen .addToHomePlus {
|
|
||||||
font-weight:bold;
|
|
||||||
font-size:1.3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* The 'share' icon, displayed only on iOS >= 4.2
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#addToHomeScreen .addToHomeShare {
|
|
||||||
display:inline-block;
|
|
||||||
width:18px;
|
|
||||||
height:15px;
|
|
||||||
background-repeat:no-repeat;
|
|
||||||
background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAeCAQAAADu6HTYAAADPElEQVR4Xq3TX2gcRRzA8e/M7mVv2+TSNpc/TZtrY6jUGqgaSAmEChKLrYK0YH0RFC2CSCkEfCghiKU04J8qNigq6os+iQV98MHWFwVBrQQRWs21lBw5cw3NNb1/udu72RGG5Y77IzXW77D7sAwf5scyYoL6BGXSDKFZwaGpLvIUaeoCkvX1MmsM0Ny6oRSQYOLuIS+YZOpfQdqslpUxcZrzTVAz4qPwW2O3CeIwC/RSzeY6Ow1QhUrkr+YOWfEKDkEP8Rij7CHKJmrFSDHBdwGEE5wiGChPN+PnT8VdRtEIl1d4gRj/1EVe5ZSBKGh8iqQpo/Fo5+3C/gz0MYg4zgwbqday1/Q4B8BGQ45d/Hi54lakCrU5obOcidJpu1+Lg9whjabyaOYLnrIBFFaRD+xe2ybMDWY66GmP/WA9cGfGp0CWhy0wkMN8inepFiH2rV1j0NQSNQbFLRQnS8/8YSDBBpadfv4CYDub2fmeHDNAsL1MBWUel0iA+Xik6eHcyvD3vAMSU1TGuA/YRS+dD7ovCQN43GKRFCU20Kd3V/avDVVyAZ5niTEuLA5/zBGWg9EEEhfJKN200Tat8CmRAQb9+wv7soPlHt2tQorsz1uPbr0HTY4sJwrH47zJZwABBAKLMBoQXepwgTwdHCo+fXMkQ4lrxEmQ5AaXipPqDY9V2vn09tgvTPI71EEGYxM+/uMJLJ4svpgaWGKOi/xKgmqLSUGSUd5f2vIVJ/CgBaTIUsZ7ZBsn0+NzfMOXLFCXQyTcybN6ep5ZZgUOHn7jpfUpsZshdugPGf+E5zjbyHTSRyQ8xfRPPM/s63RHeuknSoT22mjmmnAOIMkUZ6D1xSfPPAfd1WFKM3sO2CMaHx8M1NjnXKHaAGGkOW0C02WeYHUz4qMtx+w5gUDS8NckYe5lHsMYwCZEPyEEmjLDZFmAS7CDviMdxyTkMNVBKEmYLvbiQQBIBBbCQG04bGQvFWz6CfsCQLWCigILFwcfkGYBiOpbYuOizTAyYyDdCtrGaRG1LCkIgMYEFhI0WqQZoSlbGRyHKe4qOx7iv2bVQW9dp4dlM/x6kmwnWQcd/Q3FCqwTEiT5s+6D5v/pb0SSHyg7uhMWAAAAAElFTkSuQmCC);
|
|
||||||
background-size:18px 15px;
|
|
||||||
text-indent:-9999em;
|
|
||||||
overflow:hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
#addToHomeScreen .addToHomeShare.addToHomeShareOS7 {
|
|
||||||
width:11px;
|
|
||||||
background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACoAAAA8CAYAAAAQTCjdAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAASCQAAEgkB80sG3AAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAKjSURBVGiB7dpPiFVVHMDxz7m9NCtMyI2bEJEC25WrEkzHUXCRraIwdNE8ZxfYIlcis1ZEbGEzT1QCF4XgH1CyWhUoJKIWNRGEiCNKmkSiYTzfcfGuOokx77x3ZlS8382959zfn+/invvn3RdijHIRBrwkOINCYXEcdjpb7VyiYdBsLScwt5y6IloYdzqXo36Ro0gY9IKWo+5JwmzBt2HQnBw9ehYNazyn5TBee8Dh+Vq+CWu92GufnkTDR6ab7gDeBNHouMM/l9tXTXM0fGBmL726Fg1Dam74EsvKqR8VNowL2Yzj5f7rnnE4DHq2235diYYhhTGfC94up35T0y+6di/ITU0rKVd+sEi0P7xr2pSJOu8zvF+OzqEv7vDH/WFxt7/cshy/ticsN8sXYUht0kXDOlsF9XJ4UaEvNoz9X3zc5bKaZThbyr5jzJ4wlNY7KTgM+ES0vhz+KeiPw36fKC/ucAF9uFBOrTZm26SJCtaV27+xIo7cXdkTEhvOoh+XyxprU1qnim7CQdGK2HAyKRexYVShT3RItDElN+mkjiP2Ym+S3f01hv2EVal5WW6hU0ElmptaqJuBpXg6MbeFH2LDpU6CQ93zWIKnEvs0cayGU3glMfkOo1jQYewZzOuyz7FC95Jwo5OgUFfgeg993hh/eTqCTxOSm/iuk8DY0Ap1b2GhtHXxsfZN4j/X0fOx4auEIknEhqv4OiUn1L13Z/+xWfWVaG4q0dxUormpRHNTieamEs1NJZqbJ1Q0jHvdiJo5S2cVjSNOCHZhn3/SnuYnIvl3yomIIz7MXZMn9hydRCrR3FSiualEc1OJ5qYSzU0lmptKNDePjWgwcPePT7/g+4cp8wCW4GXaryK3tL+mLdD5x62ppllgu7bso8q/2HIbzGWdNmWnSJwAAAAASUVORK5CYII=);
|
|
||||||
background-size:11px 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* The touch icon (if available)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#addToHomeScreen .addToHomeTouchIcon {
|
|
||||||
display:block;
|
|
||||||
float:left;
|
|
||||||
-webkit-border-radius:6px;
|
|
||||||
border-radius:6px;
|
|
||||||
-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.5),
|
|
||||||
inset 0 0 2px rgba(255,255,255,0.9);
|
|
||||||
box-shadow:0 1px 3px rgba(0,0,0,0.5),
|
|
||||||
inset 0 0 2px rgba(255,255,255,0.9);
|
|
||||||
background-repeat:no-repeat;
|
|
||||||
width:57px; height:57px;
|
|
||||||
-webkit-background-size:57px 57px;
|
|
||||||
background-size:57px 57px;
|
|
||||||
margin:0 12px 0 0;
|
|
||||||
border:1px solid #333;
|
|
||||||
-webkit-background-clip:padding-box;
|
|
||||||
background-clip:padding-box;
|
|
||||||
}
|
|
@ -1,111 +0,0 @@
|
|||||||
// https://github.com/h5bp/Effeckt.css
|
|
||||||
|
|
||||||
|
|
||||||
@mixin slide () {
|
|
||||||
-webkit-transform: translate3d(0, 0, 0);
|
|
||||||
transform: translate3d(0, 0, 0);
|
|
||||||
|
|
||||||
&.left {
|
|
||||||
-webkit-transform: translate3d(-100%, 0, 0);
|
|
||||||
transform: translate3d(-100%, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.center {
|
|
||||||
-webkit-transform: translate3d(0, 0, 0);
|
|
||||||
transform: translate3d(0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.right {
|
|
||||||
-webkit-transform: translate3d(100%, 0, 0);
|
|
||||||
transform: translate3d(100%, 0, 0);
|
|
||||||
visibility: hidden;
|
|
||||||
display: none;
|
|
||||||
|
|
||||||
&.transition {
|
|
||||||
visibility: visible;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.transition {
|
|
||||||
-webkit-transition-duration: .25s;
|
|
||||||
transition-duration: .25s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// http://coenraets.org/blog/2013/03/hardware-accelerated-page-transitions-for-mobile-web-apps-phonegap-apps/
|
|
||||||
.page {
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
@include slide();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
.registrationForm {
|
|
||||||
.steps {
|
|
||||||
.step {
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
// top: 0;
|
|
||||||
// left: 0;
|
|
||||||
// width: 100%;
|
|
||||||
// height: 100%;
|
|
||||||
|
|
||||||
.slide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
// tentative 3D transformations
|
|
||||||
/*
|
|
||||||
.page {
|
|
||||||
transform: rotateY( 0deg) translateZ( 100px);
|
|
||||||
|
|
||||||
&.left {
|
|
||||||
transform: rotateY( -90deg) translateZ( 100px);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.center {
|
|
||||||
transform: rotateY( 0deg) translateZ( 100px);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.right {
|
|
||||||
transform: rotateY( 90deg) translateZ( 100px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#mainDiv {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
position: absolute;
|
|
||||||
transform-style: preserve-3d;
|
|
||||||
|
|
||||||
transition: transform 3s;
|
|
||||||
|
|
||||||
&.show-front { transform: translateZ( -100px ) rotateY( 0deg ); }
|
|
||||||
&.show-back { transform: translateZ( -100px ) rotateX( -180deg ); }
|
|
||||||
&.show-right { transform: translateZ( -100px ) rotateY( -90deg ); }
|
|
||||||
&.show-left { transform: translateZ( -100px ) rotateY( 90deg ); }
|
|
||||||
&.show-top { transform: translateZ( -100px ) rotateX( -90deg ); }
|
|
||||||
&.show-bottom { transform: translateZ( -100px ) rotateX( 90deg ); }
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
//=======================================================================
|
|
||||||
|
|
||||||
|
|
||||||
//=======================================================================
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//========================================================
|
|
@ -1,96 +0,0 @@
|
|||||||
div.checkbox {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
@include border-radius(4px);
|
|
||||||
border: 2px solid white;
|
|
||||||
background-color: white;
|
|
||||||
width: 80px;
|
|
||||||
position: relative;
|
|
||||||
height: 32px;
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
content: "ON";
|
|
||||||
padding-left: 9px;
|
|
||||||
line-height: 32px;
|
|
||||||
color: $solarize-Accent-Cyan;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 600;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
content: "OFF";
|
|
||||||
// padding-left: 12px;
|
|
||||||
padding-left: 25px;
|
|
||||||
line-height: 32px;
|
|
||||||
color: $solarize-Accent-Cyan;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
label.check {
|
|
||||||
display: block;
|
|
||||||
width: 40px;
|
|
||||||
height: 30px;
|
|
||||||
@include border-radius(3px);
|
|
||||||
background-color: $solarize-Accent-Magenta;
|
|
||||||
border: 1px solid $solarize-Accent-Magenta;
|
|
||||||
position: absolute;
|
|
||||||
top: 0px;
|
|
||||||
left: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
input[type=checkbox] {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=checkbox]:checked + label.check {
|
|
||||||
top: 0px;
|
|
||||||
left: 38px;
|
|
||||||
@include animation(labelON, .2s, ease-in, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=checkbox] + label.check {
|
|
||||||
top: 0px;
|
|
||||||
left: 0px;
|
|
||||||
@include animation(labelOFF, .2s, ease-in, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
label.info {
|
|
||||||
position: absolute;
|
|
||||||
color: white;
|
|
||||||
top: 0px;
|
|
||||||
left: 100px;
|
|
||||||
line-height: 32px;
|
|
||||||
width: 200px;
|
|
||||||
font-size: 16pt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include keyframes(labelON) {
|
|
||||||
0% {
|
|
||||||
top: 0px;
|
|
||||||
left: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
top: 0px;
|
|
||||||
left: 38px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include keyframes(labelOFF) {
|
|
||||||
0% {
|
|
||||||
top: 0px;
|
|
||||||
left: 38px;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
top: 0px;
|
|
||||||
left: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,138 +0,0 @@
|
|||||||
// --------------------------------------------------
|
|
||||||
// Flexbox LESS mixins
|
|
||||||
// The spec: http://www.w3.org/TR/css3-flexbox
|
|
||||||
//
|
|
||||||
// Other info:
|
|
||||||
// - http://philipwalton.github.io/solved-by-flexbox/
|
|
||||||
// --------------------------------------------------
|
|
||||||
|
|
||||||
// Flexbox display
|
|
||||||
// flex or inline-flex
|
|
||||||
.flex-display(@display: flex) {
|
|
||||||
display: ~"-webkit-@{display}";
|
|
||||||
display: ~"-moz-@{display}";
|
|
||||||
display: ~"-ms-@{display}box"; // IE10 uses -ms-flexbox
|
|
||||||
display: ~"-ms-@{display}"; // IE11
|
|
||||||
display: @display;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The 'flex' shorthand
|
|
||||||
// - applies to: flex items
|
|
||||||
// <positive-number>, initial, auto, or none
|
|
||||||
.flex(@columns: initial) {
|
|
||||||
-webkit-flex: @columns;
|
|
||||||
-moz-flex: @columns;
|
|
||||||
-ms-flex: @columns;
|
|
||||||
flex: @columns;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flex Flow Direction
|
|
||||||
// - applies to: flex containers
|
|
||||||
// row | row-reverse | column | column-reverse
|
|
||||||
.flex-direction(@direction: row) {
|
|
||||||
-webkit-flex-direction: @direction;
|
|
||||||
-moz-flex-direction: @direction;
|
|
||||||
-ms-flex-direction: @direction;
|
|
||||||
flex-direction: @direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flex Line Wrapping
|
|
||||||
// - applies to: flex containers
|
|
||||||
// nowrap | wrap | wrap-reverse
|
|
||||||
.flex-wrap(@wrap: nowrap) {
|
|
||||||
-webkit-flex-wrap: @wrap;
|
|
||||||
-moz-flex-wrap: @wrap;
|
|
||||||
-ms-flex-wrap: @wrap;
|
|
||||||
flex-wrap: @wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flex Direction and Wrap
|
|
||||||
// - applies to: flex containers
|
|
||||||
// <flex-direction> || <flex-wrap>
|
|
||||||
.flex-flow(@flow) {
|
|
||||||
-webkit-flex-flow: @flow;
|
|
||||||
-moz-flex-flow: @flow;
|
|
||||||
-ms-flex-flow: @flow;
|
|
||||||
flex-flow: @flow;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display Order
|
|
||||||
// - applies to: flex items
|
|
||||||
// <integer>
|
|
||||||
.flex-order(@order: 0) {
|
|
||||||
-webkit-order: @order;
|
|
||||||
-moz-order: @order;
|
|
||||||
-ms-order: @order;
|
|
||||||
order: @order;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flex grow factor
|
|
||||||
// - applies to: flex items
|
|
||||||
// <number>
|
|
||||||
.flex-grow(@grow: 0) {
|
|
||||||
-webkit-flex-grow: @grow;
|
|
||||||
-moz-flex-grow: @grow;
|
|
||||||
-ms-flex-grow: @grow;
|
|
||||||
flex-grow: @grow;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flex shr
|
|
||||||
// - applies to: flex itemsink factor
|
|
||||||
// <number>
|
|
||||||
.flex-shrink(@shrink: 1) {
|
|
||||||
-webkit-flex-shrink: @shrink;
|
|
||||||
-moz-flex-shrink: @shrink;
|
|
||||||
-ms-flex-shrink: @shrink;
|
|
||||||
flex-shrink: @shrink;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flex basis
|
|
||||||
// - the initial main size of the flex item
|
|
||||||
// - applies to: flex itemsnitial main size of the flex item
|
|
||||||
// <width>
|
|
||||||
.flex-basis(@width: auto) {
|
|
||||||
-webkit-flex-basis: @width;
|
|
||||||
-moz-flex-basis: @width;
|
|
||||||
-ms-flex-basis: @width;
|
|
||||||
flex-basis: @width;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Axis Alignment
|
|
||||||
// - applies to: flex containers
|
|
||||||
// flex-start | flex-end | center | space-between | space-around
|
|
||||||
.justify-content(@justify: flex-start) {
|
|
||||||
-webkit-justify-content: @justify;
|
|
||||||
-moz-justify-content: @justify;
|
|
||||||
-ms-justify-content: @justify;
|
|
||||||
justify-content: @justify;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packing Flex Lines
|
|
||||||
// - applies to: multi-line flex containers
|
|
||||||
// flex-start | flex-end | center | space-between | space-around | stretch
|
|
||||||
.align-content(@align: stretch) {
|
|
||||||
-webkit-align-content: @align;
|
|
||||||
-moz-align-content: @align;
|
|
||||||
-ms-align-content: @align;
|
|
||||||
align-content: @align;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cross-axis Alignment
|
|
||||||
// - applies to: flex containers
|
|
||||||
// flex-start | flex-end | center | baseline | stretch
|
|
||||||
.align-items(@align: stretch) {
|
|
||||||
-webkit-align-items: @align;
|
|
||||||
-moz-align-items: @align;
|
|
||||||
-ms-align-items: @align;
|
|
||||||
align-items: @align;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cross-axis Alignment
|
|
||||||
// - applies to: flex items
|
|
||||||
// auto | flex-start | flex-end | center | baseline | stretch
|
|
||||||
.align-self(@align: auto) {
|
|
||||||
-webkit-align-self: @align;
|
|
||||||
-moz-align-self: @align;
|
|
||||||
-ms-align-self: @align;
|
|
||||||
align-self: @align;
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
164
frontend/delta/tests/SimpleTest/SimpleTest.Async.js
Normal file
164
frontend/delta/tests/SimpleTest/SimpleTest.Async.js
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
MochiKit.Base.update(Clipperz.Async.Deferred.prototype, {
|
||||||
|
/*
|
||||||
|
'_addTest': function(anExpectedValue, aDescription, isDeep, aResult) {
|
||||||
|
if (isDeep) {
|
||||||
|
SimpleTest.isDeeply(aResult, anExpectedValue, aDescription);
|
||||||
|
} else {
|
||||||
|
SimpleTest.is(aResult, anExpectedValue, aDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
return aResult;
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
'addTest': function (anExpectedValue, aDescription, isDeep) {
|
||||||
|
// this.addMethod(this, '_addTest', anExpectedValue, aDescription, isDeep);
|
||||||
|
// this.addCallback(Clipperz.Async.test, anExpectedValue, aDescription, isDeep);
|
||||||
|
|
||||||
|
if (isDeep) {
|
||||||
|
// SimpleTest.isDeeply(aResult, anExpectedValue, aDescription);
|
||||||
|
this.addCallback(Clipperz.Async.Test.isDeeply(anExpectedValue, aDescription));
|
||||||
|
} else {
|
||||||
|
// SimpleTest.is(aResult, anExpectedValue, aDescription);
|
||||||
|
this.addCallback(Clipperz.Async.Test.is(anExpectedValue, aDescription));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
'shouldSucceed': function (aDescription) {
|
||||||
|
this.addCallbackPass(SimpleTest.ok, true, aDescription);
|
||||||
|
this.addErrbackPass (SimpleTest.ok, false, aDescription);
|
||||||
|
this.addBoth(MochiKit.Async.succeed, null);
|
||||||
|
},
|
||||||
|
|
||||||
|
'shouldFail': function (aDescription) {
|
||||||
|
this.addCallbackPass(SimpleTest.ok, false, aDescription);
|
||||||
|
this.addErrbackPass (SimpleTest.ok, true, aDescription);
|
||||||
|
this.addBoth(MochiKit.Async.succeed, null);
|
||||||
|
},
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Clipperz.Async.Test = {};
|
||||||
|
MochiKit.Base.update(Clipperz.Async.Test, {
|
||||||
|
|
||||||
|
'is': function (anExpectedResult, aDescription) {
|
||||||
|
return MochiKit.Base.partial(function (anExpectedResult, aDescription, aResult) {
|
||||||
|
SimpleTest.is(aResult, anExpectedResult, aDescription);
|
||||||
|
|
||||||
|
return aResult;
|
||||||
|
}, anExpectedResult, aDescription);
|
||||||
|
},
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
'ok': function (aDescription) {
|
||||||
|
return MochiKit.Base.partial(function (aDescription, aResult) {
|
||||||
|
SimpleTest.ok(aResult, aDescription);
|
||||||
|
|
||||||
|
return aResult;
|
||||||
|
}, aDescription);
|
||||||
|
},
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
'fail': function(aDescription) {
|
||||||
|
return MochiKit.Base.partial(function (aDescription, aResult) {
|
||||||
|
SimpleTest.ok(!aResult, aDescription);
|
||||||
|
|
||||||
|
return aResult;
|
||||||
|
}, aDescription);
|
||||||
|
},
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
'isDeeply': function (anExpectedResult, aDescription) {
|
||||||
|
return MochiKit.Base.partial(function (anExpectedResult, aDescription, aResult) {
|
||||||
|
SimpleTest.isDeeply(aResult, anExpectedResult, aDescription);
|
||||||
|
|
||||||
|
return aResult;
|
||||||
|
}, anExpectedResult, aDescription);
|
||||||
|
},
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
__syntaxFix__: "syntax fix"
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
SimpleTest.runDeferredTests = function (aName, aTestSet, aTestArguments) {
|
||||||
|
try {
|
||||||
|
var deferredTests;
|
||||||
|
var aTestName;
|
||||||
|
var title;
|
||||||
|
|
||||||
|
deferredTests = new Clipperz.Async.Deferred(aName + " <deferred test set>", aTestArguments);
|
||||||
|
|
||||||
|
title = aName;
|
||||||
|
|
||||||
|
aTestName = window.location.href.match(/#.*/);
|
||||||
|
if (aTestName && (aTestName != '#')) {
|
||||||
|
aTestName = aTestName[0].slice(1);
|
||||||
|
if (aTestName in aTestSet) {
|
||||||
|
//Clipperz.log("single test execution, via fragment identifier", aTestName);
|
||||||
|
title += ' [' + aTestName + ']';
|
||||||
|
deferredTests.addCallback(aTestSet[aTestName], aTestArguments);
|
||||||
|
deferredTests.addErrback(SimpleTest.ok, false, aTestName);
|
||||||
|
} else {
|
||||||
|
title = 'WRONG TEST NAME'
|
||||||
|
deferredTests.addBoth(is, aTestName, null, "Wrong test name selected to run");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (aTestName in aTestSet) {
|
||||||
|
deferredTests.addCallback(aTestSet[aTestName], aTestArguments);
|
||||||
|
deferredTests.addErrback(SimpleTest.ok, false, aTestName);
|
||||||
|
deferredTests.addBoth(MochiKit.Async.wait, 0.5);
|
||||||
|
}
|
||||||
|
deferredTests.addBoth(is, true, true, "FINISH: completed the full stack of tests");
|
||||||
|
}
|
||||||
|
|
||||||
|
MochiKit.DOM.currentDocument().title = title;
|
||||||
|
|
||||||
|
deferredTests.addBoth(SimpleTest.finish);
|
||||||
|
deferredTests.callback();
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
} catch (err) {
|
||||||
|
var s = "test suite failure!\n";
|
||||||
|
var o = {};
|
||||||
|
var k = null;
|
||||||
|
for (k in err) {
|
||||||
|
// ensure unique keys?!
|
||||||
|
if (!o[k]) {
|
||||||
|
s += k + ": " + err[k] + "\n";
|
||||||
|
o[k] = err[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ok ( false, s );
|
||||||
|
}
|
||||||
|
}
|
447
frontend/delta/tests/SimpleTest/SimpleTest.js
Normal file
447
frontend/delta/tests/SimpleTest/SimpleTest.js
Normal file
@ -0,0 +1,447 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SimpleTest, a partial Test.Simple/Test.More API compatible test library.
|
||||||
|
*
|
||||||
|
* Why?
|
||||||
|
*
|
||||||
|
* Test.Simple doesn't work on IE < 6.
|
||||||
|
* TODO:
|
||||||
|
* * Support the Test.Simple API used by MochiKit, to be able to test MochiKit
|
||||||
|
* itself against IE 5.5
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
if (typeof(SimpleTest) == "undefined") {
|
||||||
|
var SimpleTest = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check to see if the TestRunner is present and has logging
|
||||||
|
if (typeof(parent) != "undefined" && parent.TestRunner) {
|
||||||
|
SimpleTest._logEnabled = parent.TestRunner.logEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTest._tests = [];
|
||||||
|
SimpleTest._stopOnLoad = true;
|
||||||
|
SimpleTest._scopeCopy = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a copy of the specified scope variables.
|
||||||
|
*/
|
||||||
|
SimpleTest.saveScope = function (scope) {
|
||||||
|
SimpleTest._scopeCopy = {};
|
||||||
|
for (var k in scope) {
|
||||||
|
SimpleTest._scopeCopy[k] = scope[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies the specified scope against the stored copy and reports
|
||||||
|
* any differences as test failures.
|
||||||
|
*/
|
||||||
|
SimpleTest.verifyScope = function (scope) {
|
||||||
|
var filter = ['test', '_firebug','_FirebugConsole','XMLHttpRequest','Audio',
|
||||||
|
'XSLTProcessor','Option','Image','scrollMaxX','scrollMaxY',
|
||||||
|
'clipboardData'];
|
||||||
|
for (var k in scope) {
|
||||||
|
if (MochiKit.Base.findValue(filter, k) < 0) {
|
||||||
|
var v = scope[k];
|
||||||
|
var old = SimpleTest._scopeCopy[k];
|
||||||
|
if (v !== old && typeof(old) === "undefined") {
|
||||||
|
SimpleTest.ok(false, "scope modified, variable " + k + " was added");
|
||||||
|
} else if (v !== old) {
|
||||||
|
SimpleTest.ok(false, "scope modified, variable " + k + " changed from: " + old + ", to: " + v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var k in SimpleTest._scopeCopy) {
|
||||||
|
if (!(k in scope)) {
|
||||||
|
SimpleTest.ok(false, "scope modified, variable " + k + " has been removed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Something like assert.
|
||||||
|
*/
|
||||||
|
SimpleTest.ok = function (condition, name, diag) {
|
||||||
|
var test = {'result': !!condition, 'name': name, 'diag': diag || ""};
|
||||||
|
if (SimpleTest._logEnabled) {
|
||||||
|
var msg = test.result ? "PASS" : "FAIL";
|
||||||
|
msg += " | " + test.name;
|
||||||
|
if (test.result) {
|
||||||
|
parent.TestRunner.logger.log(msg);
|
||||||
|
} else {
|
||||||
|
msg += " | " + test.diag;
|
||||||
|
parent.TestRunner.logger.error(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SimpleTest._tests.push(test);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Roughly equivalent to ok(a==b, name)
|
||||||
|
*/
|
||||||
|
SimpleTest.is = function (a, b, name) {
|
||||||
|
var repr = MochiKit.Base.repr;
|
||||||
|
SimpleTest.ok(a == b, name, "got " + repr(a) + ", expected " + repr(b));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Roughly equivalent to ok(compare(a,b)==0, name)
|
||||||
|
*/
|
||||||
|
SimpleTest.eq = function (a, b, name) {
|
||||||
|
var base = MochiKit.Base;
|
||||||
|
var repr = base.repr;
|
||||||
|
try {
|
||||||
|
SimpleTest.ok(base.compare(a, b) == 0, name, "got " + repr(a) + ", expected " + repr(b));
|
||||||
|
} catch (e) {
|
||||||
|
SimpleTest.ok(false, name, "exception in compare: " + repr(e));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes a test report, returns it as a DIV element.
|
||||||
|
**/
|
||||||
|
SimpleTest.report = function () {
|
||||||
|
var DIV = MochiKit.DOM.DIV;
|
||||||
|
var passed = 0;
|
||||||
|
var failed = 0;
|
||||||
|
var results = MochiKit.Base.map(
|
||||||
|
function (test) {
|
||||||
|
var cls, msg;
|
||||||
|
if (test.result) {
|
||||||
|
passed++;
|
||||||
|
cls = "test_ok";
|
||||||
|
msg = "ok - " + test.name;
|
||||||
|
} else {
|
||||||
|
failed++;
|
||||||
|
cls = "test_not_ok";
|
||||||
|
msg = "not ok - " + test.name;
|
||||||
|
if (test.diag != null && test.diag != "") {
|
||||||
|
msg += ": " + test.diag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DIV({"class": cls}, msg);
|
||||||
|
},
|
||||||
|
SimpleTest._tests
|
||||||
|
);
|
||||||
|
var summary_class = ((failed == 0) ? 'all_pass' : 'some_fail');
|
||||||
|
return DIV({'class': 'tests_report'},
|
||||||
|
DIV({'class': 'tests_summary ' + summary_class},
|
||||||
|
DIV({'class': 'tests_passed'}, "Passed: " + passed),
|
||||||
|
DIV({'class': 'tests_failed'}, "Failed: " + failed)),
|
||||||
|
results
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle element visibility
|
||||||
|
**/
|
||||||
|
SimpleTest.toggle = function(el) {
|
||||||
|
if (MochiKit.Style.getStyle(el, 'display') == 'block') {
|
||||||
|
el.style.display = 'none';
|
||||||
|
} else {
|
||||||
|
el.style.display = 'block';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle visibility for divs with a specific class.
|
||||||
|
**/
|
||||||
|
SimpleTest.toggleByClass = function (cls) {
|
||||||
|
var elems = MochiKit.DOM.getElementsByTagAndClassName('div', cls);
|
||||||
|
MochiKit.Base.map(SimpleTest.toggle, elems);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the report in the browser
|
||||||
|
**/
|
||||||
|
|
||||||
|
SimpleTest.showReport = function() {
|
||||||
|
var base = MochiKit.Base;
|
||||||
|
var dom = MochiKit.DOM;
|
||||||
|
var togglePassed = dom.A({'href': '#'}, "Toggle passed tests");
|
||||||
|
var toggleFailed = dom.A({'href': '#'}, "Toggle failed tests");
|
||||||
|
togglePassed.onclick = base.partial(SimpleTest.toggleByClass, 'test_ok');
|
||||||
|
toggleFailed.onclick = base.partial(SimpleTest.toggleByClass, 'test_not_ok');
|
||||||
|
var body = document.getElementsByTagName("body")[0];
|
||||||
|
var firstChild = body.childNodes[0];
|
||||||
|
var addNode;
|
||||||
|
if (firstChild) {
|
||||||
|
addNode = function (el) {
|
||||||
|
body.insertBefore(el, firstChild);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
addNode = function (el) {
|
||||||
|
body.appendChild(el)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
addNode(togglePassed);
|
||||||
|
addNode(dom.SPAN(null, " "));
|
||||||
|
addNode(toggleFailed);
|
||||||
|
addNode(SimpleTest.report());
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells SimpleTest to don't finish the test when the document is loaded,
|
||||||
|
* useful for asynchronous tests.
|
||||||
|
*
|
||||||
|
* When SimpleTest.waitForExplicitFinish is called,
|
||||||
|
* explicit SimpleTest.finish() is required.
|
||||||
|
**/
|
||||||
|
SimpleTest.waitForExplicitFinish = function () {
|
||||||
|
SimpleTest._stopOnLoad = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Talks to the TestRunner if being ran on a iframe and the parent has a
|
||||||
|
* TestRunner object.
|
||||||
|
**/
|
||||||
|
SimpleTest.talkToRunner = function () {
|
||||||
|
if (typeof(parent) != "undefined" && parent.TestRunner) {
|
||||||
|
parent.TestRunner.testFinished(document);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finishes the tests. This is automatically called, except when
|
||||||
|
* SimpleTest.waitForExplicitFinish() has been invoked.
|
||||||
|
**/
|
||||||
|
SimpleTest.finish = function () {
|
||||||
|
SimpleTest.showReport();
|
||||||
|
SimpleTest.talkToRunner();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
MochiKit.DOM.addLoadEvent(function() {
|
||||||
|
if (SimpleTest._stopOnLoad) {
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// --------------- Test.Builder/Test.More isDeeply() -----------------
|
||||||
|
|
||||||
|
|
||||||
|
SimpleTest.DNE = {dne: 'Does not exist'};
|
||||||
|
SimpleTest.LF = "\r\n";
|
||||||
|
SimpleTest._isRef = function (object) {
|
||||||
|
var type = typeof(object);
|
||||||
|
return type == 'object' || type == 'function';
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
SimpleTest._deepCheck = function (e1, e2, stack, seen) {
|
||||||
|
var ok = false;
|
||||||
|
// Either they're both references or both not.
|
||||||
|
var sameRef = !(!SimpleTest._isRef(e1) ^ !SimpleTest._isRef(e2));
|
||||||
|
if (e1 == null && e2 == null) {
|
||||||
|
ok = true;
|
||||||
|
} else if (e1 != null ^ e2 != null) {
|
||||||
|
ok = false;
|
||||||
|
} else if (e1 == SimpleTest.DNE ^ e2 == SimpleTest.DNE) {
|
||||||
|
ok = false;
|
||||||
|
} else if (sameRef && e1 == e2) {
|
||||||
|
// Handles primitives and any variables that reference the same
|
||||||
|
// object, including functions.
|
||||||
|
ok = true;
|
||||||
|
} else if (SimpleTest.isa(e1, 'Array') && SimpleTest.isa(e2, 'Array')) {
|
||||||
|
ok = SimpleTest._eqArray(e1, e2, stack, seen);
|
||||||
|
} else if (typeof e1 == "object" && typeof e2 == "object") {
|
||||||
|
ok = SimpleTest._eqAssoc(e1, e2, stack, seen);
|
||||||
|
} else {
|
||||||
|
// If we get here, they're not the same (function references must
|
||||||
|
// always simply rererence the same function).
|
||||||
|
stack.push({ vals: [e1, e2] });
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
};
|
||||||
|
|
||||||
|
SimpleTest._eqArray = function (a1, a2, stack, seen) {
|
||||||
|
// Return if they're the same object.
|
||||||
|
if (a1 == a2) return true;
|
||||||
|
|
||||||
|
// JavaScript objects have no unique identifiers, so we have to store
|
||||||
|
// references to them all in an array, and then compare the references
|
||||||
|
// directly. It's slow, but probably won't be much of an issue in
|
||||||
|
// practice. Start by making a local copy of the array to as to avoid
|
||||||
|
// confusing a reference seen more than once (such as [a, a]) for a
|
||||||
|
// circular reference.
|
||||||
|
for (var j = 0; j < seen.length; j++) {
|
||||||
|
if (seen[j][0] == a1) {
|
||||||
|
return seen[j][1] == a2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we get here, we haven't seen a1 before, so store it with reference
|
||||||
|
// to a2.
|
||||||
|
seen.push([ a1, a2 ]);
|
||||||
|
|
||||||
|
var ok = true;
|
||||||
|
// Only examines enumerable attributes. Only works for numeric arrays!
|
||||||
|
// Associative arrays return 0. So call _eqAssoc() for them, instead.
|
||||||
|
var max = a1.length > a2.length ? a1.length : a2.length;
|
||||||
|
if (max == 0) return SimpleTest._eqAssoc(a1, a2, stack, seen);
|
||||||
|
for (var i = 0; i < max; i++) {
|
||||||
|
var e1 = i > a1.length - 1 ? SimpleTest.DNE : a1[i];
|
||||||
|
var e2 = i > a2.length - 1 ? SimpleTest.DNE : a2[i];
|
||||||
|
stack.push({ type: 'Array', idx: i, vals: [e1, e2] });
|
||||||
|
if (ok = SimpleTest._deepCheck(e1, e2, stack, seen)) {
|
||||||
|
stack.pop();
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
};
|
||||||
|
|
||||||
|
SimpleTest._eqAssoc = function (o1, o2, stack, seen) {
|
||||||
|
// Return if they're the same object.
|
||||||
|
if (o1 == o2) return true;
|
||||||
|
|
||||||
|
// JavaScript objects have no unique identifiers, so we have to store
|
||||||
|
// references to them all in an array, and then compare the references
|
||||||
|
// directly. It's slow, but probably won't be much of an issue in
|
||||||
|
// practice. Start by making a local copy of the array to as to avoid
|
||||||
|
// confusing a reference seen more than once (such as [a, a]) for a
|
||||||
|
// circular reference.
|
||||||
|
seen = seen.slice(0);
|
||||||
|
for (var j = 0; j < seen.length; j++) {
|
||||||
|
if (seen[j][0] == o1) {
|
||||||
|
return seen[j][1] == o2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we get here, we haven't seen o1 before, so store it with reference
|
||||||
|
// to o2.
|
||||||
|
seen.push([ o1, o2 ]);
|
||||||
|
|
||||||
|
// They should be of the same class.
|
||||||
|
|
||||||
|
var ok = true;
|
||||||
|
// Only examines enumerable attributes.
|
||||||
|
var o1Size = 0; for (var i in o1) o1Size++;
|
||||||
|
var o2Size = 0; for (var i in o2) o2Size++;
|
||||||
|
var bigger = o1Size > o2Size ? o1 : o2;
|
||||||
|
for (var i in bigger) {
|
||||||
|
var e1 = o1[i] == undefined ? SimpleTest.DNE : o1[i];
|
||||||
|
var e2 = o2[i] == undefined ? SimpleTest.DNE : o2[i];
|
||||||
|
stack.push({ type: 'Object', idx: i, vals: [e1, e2] });
|
||||||
|
if (ok = SimpleTest._deepCheck(e1, e2, stack, seen)) {
|
||||||
|
stack.pop();
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
};
|
||||||
|
|
||||||
|
SimpleTest._formatStack = function (stack) {
|
||||||
|
var variable = '$Foo';
|
||||||
|
for (var i = 0; i < stack.length; i++) {
|
||||||
|
var entry = stack[i];
|
||||||
|
var type = entry['type'];
|
||||||
|
var idx = entry['idx'];
|
||||||
|
if (idx != null) {
|
||||||
|
if (/^\d+$/.test(idx)) {
|
||||||
|
// Numeric array index.
|
||||||
|
variable += '[' + idx + ']';
|
||||||
|
} else {
|
||||||
|
// Associative array index.
|
||||||
|
idx = idx.replace("'", "\\'");
|
||||||
|
variable += "['" + idx + "']";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var vals = stack[stack.length-1]['vals'].slice(0, 2);
|
||||||
|
var vars = [
|
||||||
|
variable.replace('$Foo', 'got'),
|
||||||
|
variable.replace('$Foo', 'expected')
|
||||||
|
];
|
||||||
|
|
||||||
|
var out = "Structures begin differing at:" + SimpleTest.LF;
|
||||||
|
for (var i = 0; i < vals.length; i++) {
|
||||||
|
var val = vals[i];
|
||||||
|
if (val == null) {
|
||||||
|
val = 'undefined';
|
||||||
|
} else {
|
||||||
|
val == SimpleTest.DNE ? "Does not exist" : "'" + val + "'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out += vars[0] + ' = ' + vals[0] + SimpleTest.LF;
|
||||||
|
out += vars[1] + ' = ' + vals[1] + SimpleTest.LF;
|
||||||
|
|
||||||
|
return ' ' + out;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
SimpleTest.isDeeply = function (it, as, name) {
|
||||||
|
var ok;
|
||||||
|
// ^ is the XOR operator.
|
||||||
|
if (SimpleTest._isRef(it) ^ SimpleTest._isRef(as)) {
|
||||||
|
// One's a reference, one isn't.
|
||||||
|
ok = false;
|
||||||
|
} else if (!SimpleTest._isRef(it) && !SimpleTest._isRef(as)) {
|
||||||
|
// Neither is an object.
|
||||||
|
ok = SimpleTest.is(it, as, name);
|
||||||
|
} else {
|
||||||
|
// We have two objects. Do a deep comparison.
|
||||||
|
var stack = [], seen = [];
|
||||||
|
if ( SimpleTest._deepCheck(it, as, stack, seen)) {
|
||||||
|
ok = SimpleTest.ok(true, name);
|
||||||
|
} else {
|
||||||
|
ok = SimpleTest.ok(false, name, SimpleTest._formatStack(stack));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
};
|
||||||
|
|
||||||
|
SimpleTest.typeOf = function (object) {
|
||||||
|
var c = Object.prototype.toString.apply(object);
|
||||||
|
var name = c.substring(8, c.length - 1);
|
||||||
|
if (name != 'Object') return name;
|
||||||
|
// It may be a non-core class. Try to extract the class name from
|
||||||
|
// the constructor function. This may not work in all implementations.
|
||||||
|
if (/function ([^(\s]+)/.test(Function.toString.call(object.constructor))) {
|
||||||
|
return RegExp.$1;
|
||||||
|
}
|
||||||
|
// No idea. :-(
|
||||||
|
return name;
|
||||||
|
};
|
||||||
|
|
||||||
|
SimpleTest.isa = function (object, clas) {
|
||||||
|
return SimpleTest.typeOf(object) == clas;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Global symbols:
|
||||||
|
var ok = SimpleTest.ok;
|
||||||
|
var is = SimpleTest.is;
|
||||||
|
var isDeeply = SimpleTest.isDeeply;
|
256
frontend/delta/tests/SimpleTest/TestRunner.js
Normal file
256
frontend/delta/tests/SimpleTest/TestRunner.js
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TestRunner: A test runner for SimpleTest
|
||||||
|
* TODO:
|
||||||
|
*
|
||||||
|
* * Avoid moving iframes: That causes reloads on mozilla and opera.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
var TestRunner = {};
|
||||||
|
TestRunner.logEnabled = false;
|
||||||
|
TestRunner._iframes = {};
|
||||||
|
TestRunner._iframeDocuments = {};
|
||||||
|
TestRunner._iframeRows = {};
|
||||||
|
TestRunner._currentTest = 0;
|
||||||
|
TestRunner._urls = [];
|
||||||
|
TestRunner._testsDiv = DIV();
|
||||||
|
TestRunner._progressDiv = DIV();
|
||||||
|
TestRunner._summaryDiv = DIV(null,
|
||||||
|
H1(null, "Tests Summary"),
|
||||||
|
TABLE(null,
|
||||||
|
THEAD(null,
|
||||||
|
TR(null,
|
||||||
|
TH(null, "Test"),
|
||||||
|
TH(null, "Passed"),
|
||||||
|
TH(null, "Failed")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
TFOOT(/*null, TR(null, TH(null, "-"), TH(null, "--"), TH(null, "---"))*/),
|
||||||
|
TBODY()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is called after generating the summary.
|
||||||
|
**/
|
||||||
|
TestRunner.onComplete = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If logEnabled is true, this is the logger that will be used.
|
||||||
|
**/
|
||||||
|
TestRunner.logger = MochiKit.Logging.logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle element visibility
|
||||||
|
**/
|
||||||
|
TestRunner._toggle = function(el) {
|
||||||
|
if (el.className == "noshow") {
|
||||||
|
el.className = "";
|
||||||
|
el.style.cssText = "";
|
||||||
|
} else {
|
||||||
|
el.className = "noshow";
|
||||||
|
el.style.cssText = "width:0px; height:0px; border:0px;";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the iframe that contains a test
|
||||||
|
**/
|
||||||
|
TestRunner._makeIframe = function (url) {
|
||||||
|
var iframe = document.createElement('iframe');
|
||||||
|
iframe.src = url;
|
||||||
|
iframe.name = url;
|
||||||
|
iframe.width = "500";
|
||||||
|
var tbody = TestRunner._summaryDiv.getElementsByTagName("tbody")[0];
|
||||||
|
var tr = TR(null, TD({'colspan': '3'}, iframe));
|
||||||
|
iframe._row = tr;
|
||||||
|
tbody.appendChild(tr);
|
||||||
|
return iframe;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TestRunner entry point.
|
||||||
|
*
|
||||||
|
* The arguments are the URLs of the test to be ran.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
TestRunner.runTests = function (/*url...*/) {
|
||||||
|
if (TestRunner.logEnabled)
|
||||||
|
TestRunner.logger.log("SimpleTest START");
|
||||||
|
|
||||||
|
var body = document.getElementsByTagName("body")[0];
|
||||||
|
appendChildNodes(body,
|
||||||
|
TestRunner._testsDiv,
|
||||||
|
TestRunner._progressDiv,
|
||||||
|
TestRunner._summaryDiv
|
||||||
|
);
|
||||||
|
for (var i = 0; i < arguments.length; i++) {
|
||||||
|
TestRunner._urls.push(arguments[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TestRunner.runNextTest();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the next test. If no test remains, calls makeSummary
|
||||||
|
**/
|
||||||
|
TestRunner.runNextTest = function() {
|
||||||
|
if (TestRunner._currentTest < TestRunner._urls.length) {
|
||||||
|
var url = TestRunner._urls[TestRunner._currentTest];
|
||||||
|
var progress = SPAN(null,
|
||||||
|
"Running ", A({href:url}, url), "..."
|
||||||
|
);
|
||||||
|
|
||||||
|
if (TestRunner.logEnabled)
|
||||||
|
TestRunner.logger.log(scrapeText(progress));
|
||||||
|
|
||||||
|
TestRunner._progressDiv.appendChild(progress);
|
||||||
|
TestRunner._iframes[url] = TestRunner._makeIframe(url);
|
||||||
|
} else {
|
||||||
|
TestRunner.makeSummary();
|
||||||
|
if (TestRunner.onComplete) {
|
||||||
|
TestRunner.onComplete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This stub is called by SimpleTest when a test is finished.
|
||||||
|
**/
|
||||||
|
TestRunner.testFinished = function (doc) {
|
||||||
|
appendChildNodes(TestRunner._progressDiv, SPAN(null, "Done"), BR());
|
||||||
|
var finishedURL = TestRunner._urls[TestRunner._currentTest];
|
||||||
|
|
||||||
|
if (TestRunner.logEnabled)
|
||||||
|
TestRunner.logger.debug("SimpleTest finished " + finishedURL);
|
||||||
|
|
||||||
|
TestRunner._iframeDocuments[finishedURL] = doc;
|
||||||
|
// TestRunner._iframes[finishedURL].style.display = "none";
|
||||||
|
if (finishedURL != null) {
|
||||||
|
TestRunner._toggle(TestRunner._iframes[finishedURL]);
|
||||||
|
TestRunner._currentTest++;
|
||||||
|
TestRunner.runNextTest();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the summary in the browser
|
||||||
|
**/
|
||||||
|
/*
|
||||||
|
TestRunner.makeSummary = function() {
|
||||||
|
if (TestRunner.logEnabled)
|
||||||
|
TestRunner.logger.log("SimpleTest FINISHED");
|
||||||
|
var rows = [];
|
||||||
|
for (var url in TestRunner._iframeDocuments) {
|
||||||
|
var doc = TestRunner._iframeDocuments[url];
|
||||||
|
var nOK = withDocument(doc,
|
||||||
|
partial(getElementsByTagAndClassName, 'div', 'test_ok')
|
||||||
|
).length;
|
||||||
|
var nNotOK = withDocument(doc,
|
||||||
|
partial(getElementsByTagAndClassName, 'div', 'test_not_ok')
|
||||||
|
).length;
|
||||||
|
var toggle = partial(TestRunner._toggle, TestRunner._iframes[url]);
|
||||||
|
var jsurl = "TestRunner._toggle(TestRunner._iframes['" + url + "'])";
|
||||||
|
var row = TR(
|
||||||
|
{'style': {'backgroundColor': nNotOK > 0 ? "#f00":"#0f0"}},
|
||||||
|
TD(null, url),
|
||||||
|
TD(null, nOK),
|
||||||
|
TD(null, nNotOK)
|
||||||
|
);
|
||||||
|
row.onclick = toggle;
|
||||||
|
var tbody = TestRunner._summaryDiv.getElementsByTagName("tbody")[0];
|
||||||
|
tbody.insertBefore(row, TestRunner._iframes[url]._row)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
TestRunner.makeSummary = function() {
|
||||||
|
var base = MochiKit.Base;
|
||||||
|
var dom = MochiKit.DOM;
|
||||||
|
var iter = MochiKit.Iter;
|
||||||
|
var total_Ok, total_not_Ok;
|
||||||
|
|
||||||
|
total_Ok = 0;
|
||||||
|
total_not_Ok = 0;
|
||||||
|
|
||||||
|
if (TestRunner.logEnabled)
|
||||||
|
TestRunner.logger.log("SimpleTest FINISHED");
|
||||||
|
var rows = [];
|
||||||
|
for (var url in TestRunner._iframeDocuments) {
|
||||||
|
var doc = TestRunner._iframeDocuments[url];
|
||||||
|
var nOK = withDocument(doc,
|
||||||
|
partial(getElementsByTagAndClassName, 'div', 'test_ok')
|
||||||
|
).length;
|
||||||
|
var nNotOK = withDocument(doc,
|
||||||
|
partial(getElementsByTagAndClassName, 'div', 'test_not_ok')
|
||||||
|
).length;
|
||||||
|
var toggle = partial(TestRunner._toggle, TestRunner._iframes[url]);
|
||||||
|
var jsurl = "TestRunner._toggle(TestRunner._iframes['" + url + "'])";
|
||||||
|
var row = TR(
|
||||||
|
{'style': {'backgroundColor': nNotOK > 0 ? "#f00":"#0f0"}},
|
||||||
|
TD(null, url),
|
||||||
|
TD(null, nOK),
|
||||||
|
TD(null, nNotOK)
|
||||||
|
);
|
||||||
|
row.onclick = toggle;
|
||||||
|
var tbody = TestRunner._summaryDiv.getElementsByTagName("tbody")[0];
|
||||||
|
tbody.insertBefore(row, TestRunner._iframes[url]._row);
|
||||||
|
|
||||||
|
total_Ok += nOK;
|
||||||
|
total_not_Ok += nNotOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
var tfoot = TestRunner._summaryDiv.getElementsByTagName("tfoot")[0];
|
||||||
|
tfoot.appendChild(TR(null,
|
||||||
|
TH(null, ""),
|
||||||
|
TH({'style':"color:green;"}, total_Ok),
|
||||||
|
TH({'style':"color:" + ((total_not_Ok == 0) ? 'black' : 'red') + ";"}, total_not_Ok)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
var testRunnerResults;
|
||||||
|
var i, c;
|
||||||
|
|
||||||
|
testRunnerResults = dom.DIV({'style': 'display:none; visibility:hidden;'}, null);
|
||||||
|
|
||||||
|
c = total_Ok;
|
||||||
|
for (i=0; i<c; i++) {
|
||||||
|
dom.appendChildNodes(testRunnerResults, dom.DIV({'class': 'test_ok'}, "ok"));
|
||||||
|
}
|
||||||
|
|
||||||
|
c = total_not_Ok;
|
||||||
|
for (i=0; i<c; i++) {
|
||||||
|
dom.appendChildNodes(testRunnerResults, dom.DIV({'class': 'test_not_ok'}, "fail"));
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementsByTagName("body")[0].appendChild(testRunnerResults);
|
||||||
|
|
||||||
|
if (typeof(parent) != "undefined" && parent.TestRunner) {
|
||||||
|
parent.TestRunner.testFinished(document);
|
||||||
|
}
|
||||||
|
};
|
51
frontend/delta/tests/SimpleTest/test.css
Normal file
51
frontend/delta/tests/SimpleTest/test.css
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
.test_ok {
|
||||||
|
color: green;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.test_not_ok {
|
||||||
|
color: red;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.test_ok, .test_not_ok {
|
||||||
|
border-bottom-width: 2px;
|
||||||
|
border-bottom-style: solid;
|
||||||
|
border-bottom-color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.all_pass {
|
||||||
|
background-color: lime;
|
||||||
|
}
|
||||||
|
|
||||||
|
.some_fail {
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tests_report {
|
||||||
|
border-width: 2px;
|
||||||
|
border-style: solid;
|
||||||
|
width: 20em;
|
||||||
|
}
|
@ -0,0 +1,100 @@
|
|||||||
|
<!--
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Clipperz.PM.DataModel.DirectLogin - test</title>
|
||||||
|
<script>Clipperz = {}</script>
|
||||||
|
<script type="text/javascript" src="../../../../../js/MochiKit/MochiKit.js"></script>
|
||||||
|
<script type="text/javascript" src="../../../../../js/React/react-with-addons-0.10.0.js"></script>
|
||||||
|
<script type="text/javascript" src="../../../../SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../../../../SimpleTest/test.css">
|
||||||
|
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/YUI/Utils.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Base.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Date.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/ByteArray.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Logging.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Async.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Signal.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/KeyValueObjectStore.js'></script>
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/Base.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/BigInt.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES_2.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SHA.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/PRNG.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SRP.js'></script>
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Toll.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script>
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Connection.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Crypto.js'></script>
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Date.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.Field.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLogin.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginInput.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginBinding.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Legacy.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.RecordIndex.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Preferences.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/OneTimePassword.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.AccountInfo.js'></script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="../../../../SimpleTest/SimpleTest.Async.js"></script>
|
||||||
|
<script>
|
||||||
|
Clipperz_IEisBroken = false;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--[if IE]><script>
|
||||||
|
Clipperz_IEisBroken = true;
|
||||||
|
Clipperz_normalizedNewLine = '\x0d\x0a';
|
||||||
|
</script><![endif]-->
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<pre id="test">
|
||||||
|
<script>
|
||||||
|
Clipperz.PM.Strings.Languages.setSelectedLanguage('en-us');
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript" src="User.data.js"></script>
|
||||||
|
<script type="text/javascript" src="User.data.old.js"></script>
|
||||||
|
<script type="text/javascript" src="DirectLogin.test.js"></script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,190 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
|
||||||
|
|
||||||
|
var tests = {
|
||||||
|
|
||||||
|
/*
|
||||||
|
user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
|
||||||
|
...
|
||||||
|
deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']);
|
||||||
|
deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
|
||||||
|
|
||||||
|
|
||||||
|
user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
|
||||||
|
...
|
||||||
|
deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
|
||||||
|
deferredResult.addMethod(user, 'getRecord', '5cdac63b317f3942da38f3a3de3b7f0e5d6678200951c6216230295550f63fb4'); // WEB PASSWORD (0)
|
||||||
|
deferredResult.addMethod(user, 'getRecord', '36ec1a41118813ced3553534fa2607d781cba687768db305beed368a8e06e113'); // DIGG (1)
|
||||||
|
deferredResult.addMethod(user, 'getRecord', 'c0ce9130ca365bb02418d4305ea1d29e49c3f0e96d44b9d3cb6b4b6843d25065'); // SAP (2)
|
||||||
|
deferredResult.addMethod(user, 'getRecord', 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'); // YAHOO (4)
|
||||||
|
DirectLogin references
|
||||||
|
- dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496 // Yahoo! Mail
|
||||||
|
- aa18149164302d5dbe7e2d3724565b9550e00887b49978559783b2e38c625584 // (Yahoo! Groups)
|
||||||
|
- 6f7bbc4e42ea462b5246e6f51c3f86056bec50601ce2de6067c8c1d26f21c07f // (Flickr)
|
||||||
|
- a7b32e72502804bf2946a2a8856139cbbb759c5777e6b3e673db1fdf7e3bd06e // (My Yahoo!)
|
||||||
|
*/
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
'editDirectLoginLabel_test': function (someTestArgs) {
|
||||||
|
var deferredResult;
|
||||||
|
var proxy;
|
||||||
|
var user;
|
||||||
|
|
||||||
|
proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
|
||||||
|
user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
|
||||||
|
|
||||||
|
deferredResult = new Clipperz.Async.Deferred("editDirectLoginLabel_test", someTestArgs);
|
||||||
|
deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
|
||||||
|
deferredResult.addMethod(user, 'login');
|
||||||
|
deferredResult.addMethod(user, 'getRecord', 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'); // YAHOO (4)
|
||||||
|
deferredResult.addMethodcaller('directLogins');
|
||||||
|
deferredResult.addCallback(MochiKit.Base.itemgetter('dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496'));
|
||||||
|
deferredResult.addCallback(function (aDirectLogin) {
|
||||||
|
var innerDeferredResult;
|
||||||
|
var updatedLabel;
|
||||||
|
|
||||||
|
updatedLabel = "updated Yahoo! Mail label";
|
||||||
|
|
||||||
|
innerDeferredResult = new Clipperz.Async.Deferred("editDirectLoginLabel_test <inner>", someTestArgs);
|
||||||
|
innerDeferredResult.addMethod(aDirectLogin, 'label');
|
||||||
|
innerDeferredResult.addTest("Yahoo! Mail", "The label of the selected direct login is correct.");
|
||||||
|
innerDeferredResult.addMethod(aDirectLogin, 'setLabel', updatedLabel);
|
||||||
|
|
||||||
|
innerDeferredResult.addMethod(aDirectLogin, 'label');
|
||||||
|
innerDeferredResult.addTest(updatedLabel, "The DirectLogin returns the correct label even before committing data.");
|
||||||
|
|
||||||
|
innerDeferredResult.addMethod(user, 'hasPendingChanges');
|
||||||
|
innerDeferredResult.addTest(true, "When changing the label of a DirectLogin, the user should report pending changes.");
|
||||||
|
|
||||||
|
//innerDeferredResult.addCallback(function () { console.log("+_+_+_+_+_+_+_+_+_+_+_+ >>>")});
|
||||||
|
innerDeferredResult.addMethod(user, 'saveChanges');
|
||||||
|
//innerDeferredResult.addCallback(function () { console.log("+_+_+_+_+_+_+_+_+_+_+_+ <<<")});
|
||||||
|
innerDeferredResult.addMethod(user, 'hasPendingChanges');
|
||||||
|
innerDeferredResult.addTest(false, "After saving changes there should be no pending changes left.");
|
||||||
|
|
||||||
|
innerDeferredResult.addMethod(aDirectLogin, 'label');
|
||||||
|
innerDeferredResult.addTest(updatedLabel, "The DirectLogin returns the correct label even after committing data.");
|
||||||
|
|
||||||
|
innerDeferredResult.callback();
|
||||||
|
|
||||||
|
return innerDeferredResult;
|
||||||
|
})
|
||||||
|
|
||||||
|
deferredResult.callback();
|
||||||
|
|
||||||
|
return deferredResult;
|
||||||
|
},
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
'editDirectLoginLabel_thanResetItToThePreviousValue_test': function (someTestArgs) {
|
||||||
|
var deferredResult;
|
||||||
|
var proxy;
|
||||||
|
var user;
|
||||||
|
|
||||||
|
proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
|
||||||
|
user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
|
||||||
|
|
||||||
|
deferredResult = new Clipperz.Async.Deferred("editDirectLoginLabel_thanResetItToThePreviousValue_test", someTestArgs);
|
||||||
|
deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
|
||||||
|
deferredResult.addMethod(user, 'login');
|
||||||
|
deferredResult.addMethod(user, 'getRecord', 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'); // YAHOO (4)
|
||||||
|
deferredResult.addMethodcaller('directLogins');
|
||||||
|
deferredResult.addCallback(MochiKit.Base.itemgetter('dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496'));
|
||||||
|
deferredResult.addCallback(function (aDirectLogin) {
|
||||||
|
var innerDeferredResult;
|
||||||
|
var originalLabel;
|
||||||
|
var updatedLabel;
|
||||||
|
|
||||||
|
originalLabel = "Yahoo! Mail";
|
||||||
|
updatedLabel = "updated Yahoo! Mail label";
|
||||||
|
|
||||||
|
innerDeferredResult = new Clipperz.Async.Deferred("editDirectLoginLabel_thanResetItToThePreviousValue_test <inner>", someTestArgs);
|
||||||
|
innerDeferredResult.addMethod(aDirectLogin, 'label');
|
||||||
|
innerDeferredResult.addTest(originalLabel, "The label of the selected direct login is correct.");
|
||||||
|
innerDeferredResult.addMethod(aDirectLogin, 'setLabel', updatedLabel);
|
||||||
|
|
||||||
|
innerDeferredResult.addMethod(aDirectLogin, 'label');
|
||||||
|
innerDeferredResult.addTest(updatedLabel, "The DirectLogin returns the correct label even before committing data.");
|
||||||
|
|
||||||
|
innerDeferredResult.addMethod(user, 'hasPendingChanges');
|
||||||
|
innerDeferredResult.addTest(true, "When changing the label of a DirectLogin, the user should report pending changes [2].");
|
||||||
|
|
||||||
|
innerDeferredResult.addMethod(aDirectLogin, 'setLabel', originalLabel);
|
||||||
|
|
||||||
|
innerDeferredResult.addMethod(aDirectLogin, 'hasPendingChanges');
|
||||||
|
innerDeferredResult.addTest(false, "Restoring the original label, the directLogin should report no pending changes.");
|
||||||
|
|
||||||
|
innerDeferredResult.addMethod(aDirectLogin.record(), 'hasPendingChanges');
|
||||||
|
innerDeferredResult.addTest(false, "Restoring the original label, the record should report no pending changes.");
|
||||||
|
|
||||||
|
innerDeferredResult.addMethod(user, 'hasPendingChanges');
|
||||||
|
innerDeferredResult.addTest(false, "Restoring the original label, the user should report no pending changes.");
|
||||||
|
|
||||||
|
innerDeferredResult.callback();
|
||||||
|
|
||||||
|
return innerDeferredResult;
|
||||||
|
})
|
||||||
|
|
||||||
|
deferredResult.callback();
|
||||||
|
|
||||||
|
return deferredResult;
|
||||||
|
},
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
'bindingValues_test': function (someTestArgs) {
|
||||||
|
var deferredResult;
|
||||||
|
var proxy;
|
||||||
|
var user;
|
||||||
|
|
||||||
|
proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
|
||||||
|
user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
|
||||||
|
|
||||||
|
deferredResult = new Clipperz.Async.Deferred("DirectLogin.bindingValues_test", someTestArgs);
|
||||||
|
deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
|
||||||
|
deferredResult.addMethod(user, 'login');
|
||||||
|
deferredResult.addMethod(user, 'getRecord', 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'); // YAHOO (4)
|
||||||
|
deferredResult.addMethodcaller('directLogins');
|
||||||
|
deferredResult.addCallback(MochiKit.Base.itemgetter('dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496'));
|
||||||
|
deferredResult.addMethodcaller('bindingValues');
|
||||||
|
deferredResult.addCallback(function (someBindingValues) {
|
||||||
|
SimpleTest.is(MochiKit.Base.keys(someBindingValues).length, 2, "there should be 2 bindings for this direct login");
|
||||||
|
SimpleTest.is(someBindingValues['login'], 'joe.clipperz', "the login field should be filled with 'joe.clipperz'");
|
||||||
|
SimpleTest.is(someBindingValues['passwd'], 'enfvDG1RxAsl', "the passwd field should be filled with 'enfvDG1RxAsl'");
|
||||||
|
})
|
||||||
|
|
||||||
|
deferredResult.callback();
|
||||||
|
|
||||||
|
return deferredResult;
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
'syntaxFix': MochiKit.Base.noop
|
||||||
|
};
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
SimpleTest.runDeferredTests("Clipperz.PM.DataModel.DirectLogin", tests, {trace:false});
|
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
directLoginConfigurations = {
|
||||||
|
'Yahoo! Mail': '{\n "page": {\n "title": "Yahoo! Mail"\n },\n "form": {\n "attributes": {\n "action": "https://login.yahoo.com/config/login?",\n "method": "post"\n },\n "inputs": [\n {\n "type": "hidden",\n "name": ".tries",\n "value": "1"\n },\n {\n "type": "hidden",\n "name": ".src",\n "value": "ym"\n },\n {\n "type": "hidden",\n "name": ".md5",\n "value": ""\n },\n {\n "type": "hidden",\n "name": ".hash",\n "value": ""\n },\n {\n "type": "hidden",\n "name": ".js",\n "value": ""\n },\n {\n "type": "hidden",\n "name": ".last",\n "value": ""\n },\n {\n "type": "hidden",\n "name": "promo",\n "value": ""\n },\n {\n "type": "hidden",\n "name": ".intl",\n "value": "us"\n },\n {\n "type": "hidden",\n "name": ".bypass",\n "value": ""\n },\n {\n "type": "hidden",\n "name": ".partner",\n "value": ""\n },\n {\n "type": "hidden",\n "name": ".u",\n "value": "5gp62cl2vg3ov"\n },\n {\n "type": "hidden",\n "name": ".v",\n "value": "0"\n },\n {\n "type": "hidden",\n "name": ".challenge",\n "value": "iBEY0IK6k3t9Uals32mrTos8s48p"\n },\n {\n "type": "hidden",\n "name": ".yplus",\n "value": ""\n },\n {\n "type": "hidden",\n "name": ".emailCode",\n "value": ""\n },\n {\n "type": "hidden",\n "name": "pkg",\n "value": ""\n },\n {\n "type": "hidden",\n "name": "stepid",\n "value": ""\n },\n {\n "type": "hidden",\n "name": ".ev",\n "value": ""\n },\n {\n "type": "hidden",\n "name": "hasMsgr",\n "value": "0"\n },\n {\n "type": "hidden",\n "name": ".chkP",\n "value": "Y"\n },\n {\n "type": "hidden",\n "name": ".done",\n "value": "http://mail.yahoo.com"\n },\n {\n "type": "hidden",\n "name": ".pd",\n "value": "ym_ver%3d0%26c="\n },\n {\n "type": "text",\n "name": "login",\n "value": ""\n },\n {\n "type": "password",\n "name": "passwd",\n "value": ""\n },\n {\n "type": "checkbox",\n "name": ".persistent",\n "value": "y"\n },\n {\n "type": "submit",\n "name": ".save",\n "value": "Sign In"\n }\n ]\n },\n "version": "0.2"\n}',
|
||||||
|
'Parallels': '{"page": {"title": "Parallels Account"},\n"form": {"attributes": {"action": "https://www.parallels.com/account/",\n"method": "post"},\n"inputs": [{"type": "text",\n"name": "Email",\n"value": ""},\n{"type": "password",\n"name": "Password",\n"value": ""}]},\n"version": "0.2.3"}',
|
||||||
|
__syntaxFix__: "syntax fix"
|
||||||
|
};
|
@ -0,0 +1,60 @@
|
|||||||
|
<!--
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Clipperz.PM.DataModel.EncryptedRemoteObject - test</title>
|
||||||
|
<script>Clipperz = {}</script>
|
||||||
|
<script type="text/javascript" src="../../../../../js/MochiKit/MochiKit.js"></script>
|
||||||
|
<script type="text/javascript" src="../../../../SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../../../../SimpleTest/test.css">
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/YUI/Utils.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Base.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/ByteArray.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Logging.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Async.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Signal.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/KeyValueObjectStore.js'></script>
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/Base.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/BigInt.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES_2.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SHA.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/PRNG.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SRP.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Connection.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Crypto.js'></script>
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script>
|
||||||
|
<script type="text/javascript" src="../../../../SimpleTest/SimpleTest.Async.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<pre id="test">
|
||||||
|
<script type="text/javascript" src="EncryptedRemoteObject.test.js"></script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,220 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
|
||||||
|
|
||||||
|
var tests = {
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
'simple_tests': function(someTestArgs) {
|
||||||
|
var deferredResult;
|
||||||
|
var encryptedRemoteObject;
|
||||||
|
|
||||||
|
var key;
|
||||||
|
var version;
|
||||||
|
var rawData;
|
||||||
|
|
||||||
|
key = "just a random key";
|
||||||
|
version = Clipperz.PM.Crypto.encryptingFunctions.currentVersion;
|
||||||
|
rawData = "just a random text to encrypt";
|
||||||
|
|
||||||
|
encryptedRemoteObject = new Clipperz.PM.DataModel.EncryptedRemoteObject({
|
||||||
|
'retrieveKeyFunction': MochiKit.Base.noop,
|
||||||
|
'retrieveRemoteDataFunction': function () { return "--"},
|
||||||
|
'encryptedDataKeypath': '--',
|
||||||
|
'encryptedVersionKeypath': '--'
|
||||||
|
});
|
||||||
|
SimpleTest.ok(encryptedRemoteObject != null, "create an encryptedRemoteObject");
|
||||||
|
|
||||||
|
deferredResult = Clipperz.Async.callbacks("EncryptedRemoteObject.test - simple_tests", [
|
||||||
|
MochiKit.Base.method(encryptedRemoteObject, 'getRemoteData'),
|
||||||
|
function(aResult) {
|
||||||
|
SimpleTest.is(aResult, "--", "setting and getting serverData works");
|
||||||
|
}
|
||||||
|
], someTestArgs);
|
||||||
|
|
||||||
|
return deferredResult;
|
||||||
|
},
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
'decrypt_test': function (someTestArgs) {
|
||||||
|
var deferredResult;
|
||||||
|
var encryptedRemoteObject;
|
||||||
|
var key;
|
||||||
|
var version;
|
||||||
|
var rawData;
|
||||||
|
|
||||||
|
key = "just a random key";
|
||||||
|
version = Clipperz.PM.Crypto.encryptingFunctions.currentVersion;
|
||||||
|
rawData = "just a random text to encrypt";
|
||||||
|
|
||||||
|
encryptedRemoteObject = new Clipperz.PM.DataModel.EncryptedRemoteObject({
|
||||||
|
'retrieveKeyFunction': MochiKit.Base.partial(MochiKit.Async.succeed, key),
|
||||||
|
'retrieveRemoteDataFunction': MochiKit.Base.partial(Clipperz.Async.callbacks, "EncryptedRemoteObject.test - decrypt_test <encrypt data>", [
|
||||||
|
MochiKit.Base.partial(Clipperz.PM.Crypto.deferredEncrypt, {key:key, value:rawData, version:version}),
|
||||||
|
function (someEncryptedData) {
|
||||||
|
return {
|
||||||
|
'data': someEncryptedData,
|
||||||
|
'version': version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
], someTestArgs)//,
|
||||||
|
// 'encryptedDataKeypath': 'data',
|
||||||
|
// 'encryptedVersionKeypath': 'version'
|
||||||
|
});
|
||||||
|
|
||||||
|
deferredResult = new Clipperz.Async.Deferred("decrypt_test", someTestArgs);
|
||||||
|
deferredResult.addMethod(encryptedRemoteObject, 'getDecryptedData');
|
||||||
|
deferredResult.addCallback(function (aResult) {
|
||||||
|
SimpleTest.is(aResult, rawData, "encrypt and decrypt works");
|
||||||
|
})
|
||||||
|
deferredResult.callback();
|
||||||
|
|
||||||
|
return deferredResult;
|
||||||
|
},
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
'getValue_test': function (someTestArgs) {
|
||||||
|
var deferredResult;
|
||||||
|
var encryptedRemoteObject;
|
||||||
|
var key;
|
||||||
|
var version;
|
||||||
|
var rawData;
|
||||||
|
|
||||||
|
key = "just a random key";
|
||||||
|
version = Clipperz.PM.Crypto.encryptingFunctions.currentVersion;
|
||||||
|
rawData = {
|
||||||
|
key1: 'value1',
|
||||||
|
key2: 'value2'
|
||||||
|
};
|
||||||
|
|
||||||
|
encryptedRemoteObject = new Clipperz.PM.DataModel.EncryptedRemoteObject({
|
||||||
|
'reference': "testReference",
|
||||||
|
'retrieveKeyFunction': MochiKit.Base.partial(MochiKit.Async.succeed, key),
|
||||||
|
'retrieveRemoteDataFunction': MochiKit.Base.partial(Clipperz.Async.callbacks, "EncryptedRemoteObject.test - decrypt_test <encrypt data>", [
|
||||||
|
MochiKit.Base.partial(Clipperz.PM.Crypto.deferredEncrypt, {key:key, value:rawData, version:version}),
|
||||||
|
function (someEncryptedData) {
|
||||||
|
return {
|
||||||
|
'data': someEncryptedData,
|
||||||
|
'version': version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
], someTestArgs)//,
|
||||||
|
// 'encryptedDataKeypath': 'data',
|
||||||
|
// 'encryptedVersionKeypath': 'version'
|
||||||
|
});
|
||||||
|
|
||||||
|
deferredResult = new Clipperz.Async.Deferred("decrypt_test", someTestArgs);
|
||||||
|
|
||||||
|
deferredResult.addMethod(encryptedRemoteObject, 'getValue', 'key1');
|
||||||
|
deferredResult.addTest('value1', "getting 'key1' works");
|
||||||
|
deferredResult.addMethod(encryptedRemoteObject, 'hasAnyCleanTextData');
|
||||||
|
deferredResult.addTest(true, "After accessing a value, hasAnyCleanTextData returns false");
|
||||||
|
|
||||||
|
deferredResult.addMethod(encryptedRemoteObject, 'hasPendingChanges');
|
||||||
|
deferredResult.addTest(false, "if nothing has changed, the object should return not pending changes");
|
||||||
|
|
||||||
|
deferredResult.addMethod(encryptedRemoteObject, 'deleteAllCleanTextData');
|
||||||
|
deferredResult.addMethod(encryptedRemoteObject, 'hasAnyCleanTextData');
|
||||||
|
deferredResult.addTest(false, "After deleting all cleanTextData, hasAnyCleanTextData returns false");
|
||||||
|
|
||||||
|
deferredResult.addMethod(encryptedRemoteObject, 'getValue', 'key1');
|
||||||
|
deferredResult.addTest('value1', "getting 'key1' (also after a lock) works correctly");
|
||||||
|
|
||||||
|
deferredResult.addMethod(encryptedRemoteObject, 'setValue', 'key1', 'new value1');
|
||||||
|
deferredResult.addMethod(encryptedRemoteObject, 'getValue', 'key1');
|
||||||
|
deferredResult.addTest('new value1', "after setting a new value, it is correctly returned");
|
||||||
|
|
||||||
|
deferredResult.addMethod(encryptedRemoteObject, 'values');
|
||||||
|
deferredResult.addCallback(function (someValues) {
|
||||||
|
SimpleTest.is(someValues['key1'], 'new value1', "the value got straight from the objectStore is correct");
|
||||||
|
});
|
||||||
|
|
||||||
|
deferredResult.addMethod(encryptedRemoteObject, 'hasPendingChanges');
|
||||||
|
deferredResult.addTest(true, "once a value has been changed, the object should return that there're some pending changes");
|
||||||
|
|
||||||
|
deferredResult.addMethod(encryptedRemoteObject, 'revertChanges');
|
||||||
|
deferredResult.addMethod(encryptedRemoteObject, 'hasPendingChanges');
|
||||||
|
deferredResult.addTest(false, "reverting the changes should return the object to its initial state, without any peding changes");
|
||||||
|
|
||||||
|
deferredResult.addMethod(encryptedRemoteObject, 'getValue', 'key1');
|
||||||
|
deferredResult.addTest('value1', "also the value of the changed item has been restored");
|
||||||
|
|
||||||
|
deferredResult.callback();
|
||||||
|
|
||||||
|
return deferredResult;
|
||||||
|
},
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
'encrypt_with_new_object_test': function (someTestArgs) {
|
||||||
|
var deferredResult;
|
||||||
|
var encryptedRemoteObject;
|
||||||
|
var key;
|
||||||
|
// var version;
|
||||||
|
// var rawData;
|
||||||
|
|
||||||
|
key = "just a random key";
|
||||||
|
// version = Clipperz.PM.Crypto.encryptingFunctions.currentVersion;
|
||||||
|
// rawData = "just a random text to encrypt";
|
||||||
|
|
||||||
|
encryptedRemoteObject = new Clipperz.PM.DataModel.EncryptedRemoteObject({
|
||||||
|
'retrieveRemoteDataFunction': MochiKit.Base.noop
|
||||||
|
});
|
||||||
|
|
||||||
|
encryptedRemoteObject.setValue('key1', "value1");
|
||||||
|
encryptedRemoteObject.setValue('key2', "value2");
|
||||||
|
encryptedRemoteObject.setValue('key3', "value3");
|
||||||
|
|
||||||
|
deferredResult = new Clipperz.Async.Deferred("encrypt_with_new_object_test", someTestArgs);
|
||||||
|
deferredResult.addMethod(encryptedRemoteObject, 'prepareRemoteDataWithKey', key);
|
||||||
|
deferredResult.addCallback(MochiKit.Base.itemgetter('data'));
|
||||||
|
deferredResult.collectResults({
|
||||||
|
'key': MochiKit.Base.partial(MochiKit.Async.succeed, key),
|
||||||
|
'value': MochiKit.Async.succeed,
|
||||||
|
'version': MochiKit.Base.partial(MochiKit.Async.succeed, Clipperz.PM.Crypto.encryptingFunctions.currentVersion)
|
||||||
|
});
|
||||||
|
deferredResult.addCallback(Clipperz.PM.Crypto.deferredDecrypt);
|
||||||
|
deferredResult.addCallback(function (aResult) {
|
||||||
|
SimpleTest.is(aResult['key1'], "value1", "encrypt and decrypt works for first element");
|
||||||
|
SimpleTest.is(aResult['key2'], "value2", "encrypt and decrypt works for second element");
|
||||||
|
SimpleTest.is(aResult['key3'], "value3", "encrypt and decrypt works for third element");
|
||||||
|
})
|
||||||
|
deferredResult.callback();
|
||||||
|
|
||||||
|
return deferredResult;
|
||||||
|
},
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
'syntaxFix': MochiKit.Base.noop
|
||||||
|
};
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
SimpleTest.runDeferredTests("Clipperz.PM.DataModel.EncryptedRemoteObject", tests, {trace:false});
|
@ -0,0 +1,99 @@
|
|||||||
|
<!--
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Clipperz.PM.DataModel.User - test</title>
|
||||||
|
<script>Clipperz = {}</script>
|
||||||
|
<script type="text/javascript" src="../../../../../js/MochiKit/MochiKit.js"></script>
|
||||||
|
<script type="text/javascript" src="../../../../SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../../../../SimpleTest/test.css">
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/YUI/Utils.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Base.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Date.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/ByteArray.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Logging.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Async.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Signal.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/KeyValueObjectStore.js'></script>
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/Base.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/BigInt.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SHA.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/PRNG.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SRP.js'></script>
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Toll.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script>
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Connection.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Crypto.js'></script>
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/UI/DirectLoginController.js'></script>
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Date.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.Field.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLogin.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginInput.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginBinding.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginFormValue.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Legacy.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.RecordIndex.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Preferences.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/OneTimePassword.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.AccountInfo.js'></script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="../../../../SimpleTest/SimpleTest.Async.js"></script>
|
||||||
|
<script>
|
||||||
|
Clipperz_IEisBroken = false;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--[if IE]><script>
|
||||||
|
Clipperz_IEisBroken = true;
|
||||||
|
Clipperz_normalizedNewLine = '\x0d\x0a';
|
||||||
|
</script><![endif]-->
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<pre id="test">
|
||||||
|
<script>
|
||||||
|
Clipperz.PM.Strings.Languages.setSelectedLanguage('en-us');
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript" src="User.data.js"></script>
|
||||||
|
<script type="text/javascript" src="OneTimePassword.test.js"></script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,193 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
|
||||||
|
|
||||||
|
var tests = {
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
'isValidOneTimePasswordValue_test': function (someTestArgs) {
|
||||||
|
var otp;
|
||||||
|
var notOTP;
|
||||||
|
|
||||||
|
otp = 'yaxx k7ww - f8y6 tqz5 - 58b6 th44 - 9cwv q0fg';
|
||||||
|
SimpleTest.is(Clipperz.PM.DataModel.OneTimePassword.isValidOneTimePasswordValue(otp), true, "isValidOneTimePasswordValue [expect true] - test 1");
|
||||||
|
|
||||||
|
notOTP = 'trustno1';
|
||||||
|
SimpleTest.is(Clipperz.PM.DataModel.OneTimePassword.isValidOneTimePasswordValue(notOTP), false, "isValidOneTimePasswordValue [expect false] - test 1");
|
||||||
|
|
||||||
|
return MochiKit.Async.succeed('done');
|
||||||
|
},
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
'loginUsingOtp_test': function (someTestArgs) {
|
||||||
|
var deferredResult;
|
||||||
|
var proxy;
|
||||||
|
var user, user2;
|
||||||
|
var username;
|
||||||
|
var passphrase;
|
||||||
|
|
||||||
|
username = "test";
|
||||||
|
passphrase = "yaxx k7ww - f8y6 tqz5 - 58b6 th44 - 9cwv q0fg"; // OTP
|
||||||
|
|
||||||
|
proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
|
||||||
|
user = new Clipperz.PM.DataModel.User({username:username, getPassphraseFunction:function () { return passphrase;}});
|
||||||
|
user2 = new Clipperz.PM.DataModel.User({username:username, getPassphraseFunction:function () { return passphrase;}});
|
||||||
|
|
||||||
|
deferredResult = new Clipperz.Async.Deferred("loginUsingOtp_test", someTestArgs);
|
||||||
|
deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_with_otps']);
|
||||||
|
|
||||||
|
deferredResult.addMethod(user, 'login');
|
||||||
|
deferredResult.addMethod(user, 'getRecords');
|
||||||
|
deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
|
||||||
|
deferredResult.addTest(1, "This account has one single card");
|
||||||
|
|
||||||
|
deferredResult.addMethod(user, 'getOneTimePasswords');
|
||||||
|
deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
|
||||||
|
deferredResult.addTest(1, "This account has one OTP");
|
||||||
|
|
||||||
|
deferredResult.addMethod(user, 'getOneTimePasswords');
|
||||||
|
deferredResult.addCallback(MochiKit.Base.itemgetter(0));
|
||||||
|
deferredResult.addCallback(MochiKit.Base.methodcaller('status'));
|
||||||
|
deferredResult.addTest('USED', "The available OTP has been unsed to login, and should be marked accordingly");
|
||||||
|
|
||||||
|
deferredResult.addMethod(user2, 'login');
|
||||||
|
deferredResult.shouldFail("trying to login using the same OTP twice");
|
||||||
|
|
||||||
|
deferredResult.callback();
|
||||||
|
|
||||||
|
return deferredResult;
|
||||||
|
},
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
'changePassphraseAndLoginUsingOtp_test': function (someTestArgs) {
|
||||||
|
var deferredResult;
|
||||||
|
var proxy;
|
||||||
|
var user;
|
||||||
|
var user2;
|
||||||
|
var user3;
|
||||||
|
var otp;
|
||||||
|
|
||||||
|
otp = "yaxx k7ww - f8y6 tqz5 - 58b6 th44 - 9cwv q0fg"; // OTP
|
||||||
|
|
||||||
|
newPassphrase = 'tset';
|
||||||
|
proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
|
||||||
|
user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
|
||||||
|
user2 = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return otp;}});
|
||||||
|
|
||||||
|
deferredResult = new Clipperz.Async.Deferred("changePassphraseAndLoginUsingOtp_test", someTestArgs);
|
||||||
|
deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_with_otps']);
|
||||||
|
|
||||||
|
deferredResult.addMethod(user, 'login');
|
||||||
|
|
||||||
|
deferredResult.addMethod(user, 'getRecords');
|
||||||
|
deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
|
||||||
|
deferredResult.addTest(1, "This account has only a single card");
|
||||||
|
|
||||||
|
deferredResult.addMethod(user, 'changePassphrase', newPassphrase);
|
||||||
|
deferredResult.addMethod(user, 'logout');
|
||||||
|
|
||||||
|
deferredResult.addMethod(user2, 'login');
|
||||||
|
deferredResult.addMethod(user2, 'getRecords');
|
||||||
|
deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
|
||||||
|
deferredResult.addTest(1, "This account has oly a single card");
|
||||||
|
deferredResult.addMethod(user2, 'logout');
|
||||||
|
|
||||||
|
deferredResult.callback();
|
||||||
|
|
||||||
|
return deferredResult;
|
||||||
|
},
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
'loginUsingOtpAndWrongUsername_test': function (someTestArgs) {
|
||||||
|
var deferredResult;
|
||||||
|
var proxy;
|
||||||
|
var user, user2;
|
||||||
|
var username;
|
||||||
|
var wrongUsername;
|
||||||
|
var passphrase;
|
||||||
|
|
||||||
|
username = "test";
|
||||||
|
wrongUsername = "tset";
|
||||||
|
passphrase = "yaxx k7ww - f8y6 tqz5 - 58b6 th44 - 9cwv q0fg"; // OTP
|
||||||
|
|
||||||
|
proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
|
||||||
|
user = new Clipperz.PM.DataModel.User({username:wrongUsername, getPassphraseFunction:function () { return passphrase;}});
|
||||||
|
user2 = new Clipperz.PM.DataModel.User({username:username, getPassphraseFunction:function () { return passphrase;}});
|
||||||
|
|
||||||
|
deferredResult = new Clipperz.Async.Deferred("loginUsingOtpAndWrongUsername_test", someTestArgs);
|
||||||
|
deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_with_otps']);
|
||||||
|
|
||||||
|
deferredResult.addMethod(user, 'login');
|
||||||
|
deferredResult.shouldFail("login in using the wrong username with the OTP should fail");
|
||||||
|
|
||||||
|
deferredResult.addMethod(user2, 'login');
|
||||||
|
deferredResult.shouldFail("trying to reuse the same OTP should fail, even if now it is used with the correct username");
|
||||||
|
|
||||||
|
deferredResult.callback();
|
||||||
|
|
||||||
|
return deferredResult;
|
||||||
|
},
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
'loginUserWithAPassphraseLookingExactlyLikeAnOTP_test': function (someTestArgs) {
|
||||||
|
var deferredResult;
|
||||||
|
var proxy;
|
||||||
|
var user;
|
||||||
|
var username;
|
||||||
|
var passphrase;
|
||||||
|
|
||||||
|
username = "otp_user";
|
||||||
|
passphrase = "yaxx k7ww - f8y6 tqz5 - 58b6 th44 - 9cwv q0fg"; // passphrase
|
||||||
|
|
||||||
|
proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
|
||||||
|
user = new Clipperz.PM.DataModel.User({username:username, getPassphraseFunction:function () { return passphrase;}});
|
||||||
|
|
||||||
|
deferredResult = new Clipperz.Async.Deferred("loginUserWithAPassphraseLookingExactlyLikeAnOTP_test", someTestArgs);
|
||||||
|
deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['otp_user_test']);
|
||||||
|
|
||||||
|
deferredResult.addMethod(user, 'login');
|
||||||
|
deferredResult.addMethod(user, 'getRecords');
|
||||||
|
deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
|
||||||
|
deferredResult.addTest(1, "This account has one single card");
|
||||||
|
|
||||||
|
deferredResult.callback();
|
||||||
|
|
||||||
|
return deferredResult;
|
||||||
|
},
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
'syntaxFix': MochiKit.Base.noop
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
SimpleTest.runDeferredTests("Clipperz.PM.DataModel.OneTimePassword", tests, {trace:false});
|
94
frontend/delta/tests/tests/Clipperz/PM/DataModel/Record.html
Normal file
94
frontend/delta/tests/tests/Clipperz/PM/DataModel/Record.html
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<!--
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Clipperz.PM.DataModel.Record - test</title>
|
||||||
|
<script>Clipperz = {}</script>
|
||||||
|
<script type="text/javascript" src="../../../../../js/MochiKit/MochiKit.js"></script>
|
||||||
|
<script type="text/javascript" src="../../../../SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../../../../SimpleTest/test.css">
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/YUI/Utils.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Base.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Date.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/ByteArray.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Logging.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Async.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Signal.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Set.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/KeyValueObjectStore.js'></script>
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/Base.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/BigInt.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES_2.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SHA.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/PRNG.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SRP.js'></script>
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Toll.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Date.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script>
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Connection.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Crypto.js'></script>
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Date.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.Field.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLogin.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginInput.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginBinding.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginFormValue.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Legacy.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.RecordIndex.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Preferences.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/OneTimePassword.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.AccountInfo.js'></script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="../../../../SimpleTest/SimpleTest.Async.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<pre id="test">
|
||||||
|
<script>
|
||||||
|
Clipperz.PM.Strings.Languages.setSelectedLanguage('en-us');
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript" src="DirectLoginConfigurations.data.js"></script>
|
||||||
|
<script type="text/javascript" src="User.data.js"></script>
|
||||||
|
<script type="text/javascript" src="Record.test.js"></script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
1513
frontend/delta/tests/tests/Clipperz/PM/DataModel/Record.test.js
Normal file
1513
frontend/delta/tests/tests/Clipperz/PM/DataModel/Record.test.js
Normal file
File diff suppressed because it is too large
Load Diff
2068
frontend/delta/tests/tests/Clipperz/PM/DataModel/User.data.js
Normal file
2068
frontend/delta/tests/tests/Clipperz/PM/DataModel/User.data.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
102
frontend/delta/tests/tests/Clipperz/PM/DataModel/User.html
Normal file
102
frontend/delta/tests/tests/Clipperz/PM/DataModel/User.html
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<!--
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Clipperz.PM.DataModel.User - test</title>
|
||||||
|
<script>Clipperz = {}</script>
|
||||||
|
<script type="text/javascript" src="../../../../../js/MochiKit/MochiKit.js"></script>
|
||||||
|
<script type="text/javascript" src="../../../../SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../../../../SimpleTest/test.css">
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/YUI/Utils.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Base.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Date.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/ByteArray.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Logging.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Async.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Signal.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/KeyValueObjectStore.js'></script>
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/Base.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/BigInt.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES_2.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SHA.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/PRNG.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SRP.js'></script>
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Toll.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script>
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Connection.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Crypto.js'></script>
|
||||||
|
|
||||||
|
<!-- script type='text/javascript' src='../../../../../js/Clipperz/PM/UI/Common/Controllers/DirectLoginRunner.js'></script -->
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/UI/DirectLoginController.js'></script>
|
||||||
|
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/Date.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.Field.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLogin.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginInput.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginBinding.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginFormValue.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Legacy.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.RecordIndex.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Preferences.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/OneTimePassword.js'></script>
|
||||||
|
<script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.AccountInfo.js'></script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="../../../../SimpleTest/SimpleTest.Async.js"></script>
|
||||||
|
<script>
|
||||||
|
Clipperz_IEisBroken = false;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--[if IE]><script>
|
||||||
|
Clipperz_IEisBroken = true;
|
||||||
|
Clipperz_normalizedNewLine = '\x0d\x0a';
|
||||||
|
</script><![endif]-->
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<pre id="test">
|
||||||
|
<script>
|
||||||
|
Clipperz.PM.Strings.Languages.setSelectedLanguage('en-us');
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript" src="User.data.js"></script>
|
||||||
|
<script type="text/javascript" src="User.data.old.js"></script>
|
||||||
|
<script type="text/javascript" src="User.test.js"></script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
2083
frontend/delta/tests/tests/Clipperz/PM/DataModel/User.test.js
Normal file
2083
frontend/delta/tests/tests/Clipperz/PM/DataModel/User.test.js
Normal file
File diff suppressed because it is too large
Load Diff
42
frontend/delta/tests/tests/Clipperz/PM/DataModel/index.html
Normal file
42
frontend/delta/tests/tests/Clipperz/PM/DataModel/index.html
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<!--
|
||||||
|
|
||||||
|
Copyright 2008-2013 Clipperz Srl
|
||||||
|
|
||||||
|
This file is part of Clipperz, the online password manager.
|
||||||
|
For further information about its features and functionalities please
|
||||||
|
refer to http://www.clipperz.com.
|
||||||
|
|
||||||
|
* Clipperz is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
* Clipperz is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Clipperz.PM.DataModel.* - tests</title>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="../../../../../js/MochiKit/MochiKit.js"></script>
|
||||||
|
<script type="text/javascript" src="../../../../SimpleTest/TestRunner.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
TestRunner.runTests(
|
||||||
|
'DirectLogin.html',
|
||||||
|
'EncryptedRemoteObject.html',
|
||||||
|
'OneTimePassword.html',
|
||||||
|
'Record.html',
|
||||||
|
'User.html'
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -92,6 +92,7 @@ class BackendBuilder(object):
|
|||||||
print message + ": " + md5Digest + " (md5)"
|
print message + ": " + md5Digest + " (md5)"
|
||||||
print message + ": " + shaDigest + " (sha1)"
|
print message + ": " + shaDigest + " (sha1)"
|
||||||
print message + ": " + sha256Digest + " (sha256)"
|
print message + ": " + sha256Digest + " (sha256)"
|
||||||
|
print "file size: " + "{:,}".format(len(content))
|
||||||
print "====="
|
print "====="
|
||||||
|
|
||||||
|
|
||||||
@ -112,14 +113,15 @@ class BackendBuilder(object):
|
|||||||
submoduleExtension = '.' + frontend.submodule
|
submoduleExtension = '.' + frontend.submodule
|
||||||
|
|
||||||
main.createFolder(os.path.join(self.frontEndTempFolder(), frontend.module))
|
main.createFolder(os.path.join(self.frontEndTempFolder(), frontend.module))
|
||||||
|
frontend.copyResourcesToFolder(self.frontEndTempFolder())
|
||||||
|
|
||||||
if 'debug' in self.versions:
|
if 'debug' in self.versions:
|
||||||
frontend.copyResourcesToFolder(self.frontEndTempFolder())
|
frontend.copyDebugResourcesToFolder(self.frontEndTempFolder())
|
||||||
|
|
||||||
index = self.configureIndexContent(frontend.assemble(assemblyMode='DEBUG', versionType='DEBUG'))
|
index = self.configureIndexContent(frontend.assemble(assemblyMode='DEBUG', versionType='DEBUG'))
|
||||||
self.writeToFolder(self.frontEndTempFolder(), os.path.join(frontend.module, 'index_debug' + submoduleExtension + '.html'), index)
|
self.writeToFolder(self.frontEndTempFolder(), os.path.join(frontend.module, 'index_debug' + submoduleExtension + '.html'), index)
|
||||||
|
|
||||||
if 'install' in self.versions:
|
if 'install' in self.versions:
|
||||||
|
# frontend.copyResourcesToFolder(self.frontEndTempFolder())
|
||||||
index = self.configureIndexContent(frontend.assemble())
|
index = self.configureIndexContent(frontend.assemble())
|
||||||
self.writeToFolder(self.frontEndTempFolder(), os.path.join(frontend.module, 'index' + submoduleExtension + '.html'), index)
|
self.writeToFolder(self.frontEndTempFolder(), os.path.join(frontend.module, 'index' + submoduleExtension + '.html'), index)
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user