packages feed

notmuch-web 0.1.2 → 0.1.2.1

raw patch · 11 files changed

+757/−5 lines, 11 filesbinary-added

Files

notmuch-web.cabal view
@@ -1,5 +1,5 @@ name:              notmuch-web-version:           0.1.2+version:           0.1.2.1 cabal-version:     >= 1.8 build-type:        Simple synopsis:          A web interface to the notmuch email indexer@@ -21,6 +21,9 @@             config/robots.txt             config/settings.yml             static/css/*.min.css+            static/css/*.css+            static/css/*.png+            static/css/*.gif             static/js/*.min.js             static/js/*.js             static/img/*.png@@ -34,6 +37,9 @@                     templates/*.lucius                     devel.hs                     package.sh+                    -- Workaround for http://hackage.haskell.org/trac/hackage/ticket/792+                    tests/Address.hs+                    tests/HomeTest.hs  source-repository head     type: mercurial
src/Handler/ComposeFields.hs view
@@ -69,7 +69,7 @@         Just e -> return $ Address (Just x) e         Nothing -> return $ Address Nothing x --- | Parse a list of addresses seperated by commas+-- | Parse a list of addresses separated by commas addresses :: Parser [Address] addresses = do as <- address `sepBy1` char ','                endOfInput <?> "Expecting ',' or '>'"
src/NotmuchCmd.hs view
@@ -295,7 +295,11 @@ notmuchVersion :: MonadIO m => m Version notmuchVersion = do     out <- liftIO $ readProcess "notmuch" ["--version"] ""-    let vStr = words out !! 1+    let fixTags :: Char -> Char+        fixTags '+' = '-'+        fixTags '~' = '-'+        fixTags c   = c+    let vStr = map fixTags $ words out !! 1     let vs = filter (\(_,r) -> r == "") $ readP_to_S parseVersion vStr     case vs of         ((v,_):_) -> return v
+ static/css/select2-spinner.gif view

binary file changed (absent → 1849 bytes)

+ static/css/select2.css view
@@ -0,0 +1,680 @@+/*+Version: 3.4.1 Timestamp: Thu Jun 27 18:02:10 PDT 2013+*/+.select2-container {+    margin: 0;+    position: relative;+    display: inline-block;+    /* inline-block for ie7 */+    zoom: 1;+    *display: inline;+    vertical-align: middle;+}++.select2-container,+.select2-drop,+.select2-search,+.select2-search input{+  /*+    Force border-box so that % widths fit the parent+    container without overlap because of margin/padding.++    More Info : http://www.quirksmode.org/css/box.html+  */+  -webkit-box-sizing: border-box; /* webkit */+   -khtml-box-sizing: border-box; /* konqueror */+     -moz-box-sizing: border-box; /* firefox */+      -ms-box-sizing: border-box; /* ie */+          box-sizing: border-box; /* css3 */+}++.select2-container .select2-choice {+    display: block;+    height: 26px;+    padding: 0 0 0 8px;+    overflow: hidden;+    position: relative;++    border: 1px solid #aaa;+    white-space: nowrap;+    line-height: 26px;+    color: #444;+    text-decoration: none;++    -webkit-border-radius: 4px;+       -moz-border-radius: 4px;+            border-radius: 4px;++    -webkit-background-clip: padding-box;+       -moz-background-clip: padding;+            background-clip: padding-box;++    -webkit-touch-callout: none;+      -webkit-user-select: none;+       -khtml-user-select: none;+         -moz-user-select: none;+          -ms-user-select: none;+              user-select: none;++    background-color: #fff;+    background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.5, white));+    background-image: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 50%);+    background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 50%);+    background-image: -o-linear-gradient(bottom, #eeeeee 0%, #ffffff 50%);+    background-image: -ms-linear-gradient(top, #ffffff 0%, #eeeeee 50%);+    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#ffffff', endColorstr = '#eeeeee', GradientType = 0);+    background-image: linear-gradient(top, #ffffff 0%, #eeeeee 50%);+}++.select2-container.select2-drop-above .select2-choice {+    border-bottom-color: #aaa;++    -webkit-border-radius:0 0 4px 4px;+       -moz-border-radius:0 0 4px 4px;+            border-radius:0 0 4px 4px;++    background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.9, white));+    background-image: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 90%);+    background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 90%);+    background-image: -o-linear-gradient(bottom, #eeeeee 0%, white 90%);+    background-image: -ms-linear-gradient(top, #eeeeee 0%,#ffffff 90%);+    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee',GradientType=0 );+    background-image: linear-gradient(top, #eeeeee 0%,#ffffff 90%);+}++.select2-container.select2-allowclear .select2-choice .select2-chosen {+    margin-right: 42px;+}++.select2-container .select2-choice > .select2-chosen {+    margin-right: 26px;+    display: block;+    overflow: hidden;++    white-space: nowrap;++    -ms-text-overflow: ellipsis;+     -o-text-overflow: ellipsis;+        text-overflow: ellipsis;+}++.select2-container .select2-choice abbr {+    display: none;+    width: 12px;+    height: 12px;+    position: absolute;+    right: 24px;+    top: 8px;++    font-size: 1px;+    text-decoration: none;++    border: 0;+    background: url('select2.png') right top no-repeat;+    cursor: pointer;+    outline: 0;+}++.select2-container.select2-allowclear .select2-choice abbr {+    display: inline-block;+}++.select2-container .select2-choice abbr:hover {+    background-position: right -11px;+    cursor: pointer;+}++.select2-drop-undermask {+    border: 0;+    margin: 0;+    padding: 0;+    position: absolute;+    left: 0;+    top: 0;+    z-index: 9998;+    background-color: transparent;+    filter: alpha(opacity=0);+}++.select2-drop-mask {+    border: 0;+    margin: 0;+    padding: 0;+    position: absolute;+    left: 0;+    top: 0;+    z-index: 9998;+    /* styles required for IE to work */+    background-color: #fff;+    opacity: 0;+    filter: alpha(opacity=0);+}++.select2-drop {+    width: 100%;+    margin-top: -1px;+    position: absolute;+    z-index: 9999;+    top: 100%;++    background: #fff;+    color: #000;+    border: 1px solid #aaa;+    border-top: 0;++    -webkit-border-radius: 0 0 4px 4px;+       -moz-border-radius: 0 0 4px 4px;+            border-radius: 0 0 4px 4px;++    -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);+       -moz-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);+            box-shadow: 0 4px 5px rgba(0, 0, 0, .15);+}++.select2-drop-auto-width {+    border-top: 1px solid #aaa;+    width: auto;+}++.select2-drop-auto-width .select2-search {+    padding-top: 4px;+}++.select2-drop.select2-drop-above {+    margin-top: 1px;+    border-top: 1px solid #aaa;+    border-bottom: 0;++    -webkit-border-radius: 4px 4px 0 0;+       -moz-border-radius: 4px 4px 0 0;+            border-radius: 4px 4px 0 0;++    -webkit-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);+       -moz-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);+            box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);+}++.select2-drop-active {+    border: 1px solid #5897fb;+    border-top: none;+}++.select2-drop.select2-drop-above.select2-drop-active {+    border-top: 1px solid #5897fb;+}++.select2-container .select2-choice .select2-arrow {+    display: inline-block;+    width: 18px;+    height: 100%;+    position: absolute;+    right: 0;+    top: 0;++    border-left: 1px solid #aaa;+    -webkit-border-radius: 0 4px 4px 0;+       -moz-border-radius: 0 4px 4px 0;+            border-radius: 0 4px 4px 0;++    -webkit-background-clip: padding-box;+       -moz-background-clip: padding;+            background-clip: padding-box;++    background: #ccc;+    background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee));+    background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%);+    background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%);+    background-image: -o-linear-gradient(bottom, #ccc 0%, #eee 60%);+    background-image: -ms-linear-gradient(top, #cccccc 0%, #eeeeee 60%);+    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#eeeeee', endColorstr = '#cccccc', GradientType = 0);+    background-image: linear-gradient(top, #cccccc 0%, #eeeeee 60%);+}++.select2-container .select2-choice .select2-arrow b {+    display: block;+    width: 100%;+    height: 100%;+    background: url('select2.png') no-repeat 0 1px;+}++.select2-search {+    display: inline-block;+    width: 100%;+    min-height: 26px;+    margin: 0;+    padding-left: 4px;+    padding-right: 4px;++    position: relative;+    z-index: 10000;++    white-space: nowrap;+}++.select2-search input {+    width: 100%;+    height: auto !important;+    min-height: 26px;+    padding: 4px 20px 4px 5px;+    margin: 0;++    outline: 0;+    font-family: sans-serif;+    font-size: 1em;++    border: 1px solid #aaa;+    -webkit-border-radius: 0;+       -moz-border-radius: 0;+            border-radius: 0;++    -webkit-box-shadow: none;+       -moz-box-shadow: none;+            box-shadow: none;++    background: #fff url('select2.png') no-repeat 100% -22px;+    background: url('select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));+    background: url('select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);+    background: url('select2.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);+    background: url('select2.png') no-repeat 100% -22px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);+    background: url('select2.png') no-repeat 100% -22px, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%);+    background: url('select2.png') no-repeat 100% -22px, linear-gradient(top, #ffffff 85%, #eeeeee 99%);+}++.select2-drop.select2-drop-above .select2-search input {+    margin-top: 4px;+}++.select2-search input.select2-active {+    background: #fff url('select2-spinner.gif') no-repeat 100%;+    background: url('select2-spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));+    background: url('select2-spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);+    background: url('select2-spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);+    background: url('select2-spinner.gif') no-repeat 100%, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);+    background: url('select2-spinner.gif') no-repeat 100%, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%);+    background: url('select2-spinner.gif') no-repeat 100%, linear-gradient(top, #ffffff 85%, #eeeeee 99%);+}++.select2-container-active .select2-choice,+.select2-container-active .select2-choices {+    border: 1px solid #5897fb;+    outline: none;++    -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3);+       -moz-box-shadow: 0 0 5px rgba(0,0,0,.3);+            box-shadow: 0 0 5px rgba(0,0,0,.3);+}++.select2-dropdown-open .select2-choice {+    border-bottom-color: transparent;+    -webkit-box-shadow: 0 1px 0 #fff inset;+       -moz-box-shadow: 0 1px 0 #fff inset;+            box-shadow: 0 1px 0 #fff inset;++    -webkit-border-bottom-left-radius: 0;+        -moz-border-radius-bottomleft: 0;+            border-bottom-left-radius: 0;++    -webkit-border-bottom-right-radius: 0;+        -moz-border-radius-bottomright: 0;+            border-bottom-right-radius: 0;++    background-color: #eee;+    background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, white), color-stop(0.5, #eeeeee));+    background-image: -webkit-linear-gradient(center bottom, white 0%, #eeeeee 50%);+    background-image: -moz-linear-gradient(center bottom, white 0%, #eeeeee 50%);+    background-image: -o-linear-gradient(bottom, white 0%, #eeeeee 50%);+    background-image: -ms-linear-gradient(top, #ffffff 0%,#eeeeee 50%);+    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff',GradientType=0 );+    background-image: linear-gradient(top, #ffffff 0%,#eeeeee 50%);+}++.select2-dropdown-open.select2-drop-above .select2-choice,+.select2-dropdown-open.select2-drop-above .select2-choices {+    border: 1px solid #5897fb;+    border-top-color: transparent;++    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, white), color-stop(0.5, #eeeeee));+    background-image: -webkit-linear-gradient(center top, white 0%, #eeeeee 50%);+    background-image: -moz-linear-gradient(center top, white 0%, #eeeeee 50%);+    background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%);+    background-image: -ms-linear-gradient(bottom, #ffffff 0%,#eeeeee 50%);+    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff',GradientType=0 );+    background-image: linear-gradient(bottom, #ffffff 0%,#eeeeee 50%);+}++.select2-dropdown-open .select2-choice .select2-arrow {+    background: transparent;+    border-left: none;+    filter: none;+}+.select2-dropdown-open .select2-choice .select2-arrow b {+    background-position: -18px 1px;+}++/* results */+.select2-results {+    max-height: 200px;+    padding: 0 0 0 4px;+    margin: 4px 4px 4px 0;+    position: relative;+    overflow-x: hidden;+    overflow-y: auto;+    -webkit-tap-highlight-color: rgba(0,0,0,0);+}++.select2-results ul.select2-result-sub {+    margin: 0;+    padding-left: 0;+}++.select2-results ul.select2-result-sub > li .select2-result-label { padding-left: 20px }+.select2-results ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 40px }+.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 60px }+.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 80px }+.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 100px }+.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 110px }+.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 120px }++.select2-results li {+    list-style: none;+    display: list-item;+    background-image: none;+}++.select2-results li.select2-result-with-children > .select2-result-label {+    font-weight: bold;+}++.select2-results .select2-result-label {+    padding: 3px 7px 4px;+    margin: 0;+    cursor: pointer;++    min-height: 1em;++    -webkit-touch-callout: none;+      -webkit-user-select: none;+       -khtml-user-select: none;+         -moz-user-select: none;+          -ms-user-select: none;+              user-select: none;+}++.select2-results .select2-highlighted {+    background: #3875d7;+    color: #fff;+}++.select2-results li em {+    background: #feffde;+    font-style: normal;+}++.select2-results .select2-highlighted em {+    background: transparent;+}++.select2-results .select2-highlighted ul {+    background: white;+    color: #000;+}+++.select2-results .select2-no-results,+.select2-results .select2-searching,+.select2-results .select2-selection-limit {+    background: #f4f4f4;+    display: list-item;+}++/*+disabled look for disabled choices in the results dropdown+*/+.select2-results .select2-disabled.select2-highlighted {+    color: #666;+    background: #f4f4f4;+    display: list-item;+    cursor: default;+}+.select2-results .select2-disabled {+  background: #f4f4f4;+  display: list-item;+  cursor: default;+}++.select2-results .select2-selected {+    display: none;+}++.select2-more-results.select2-active {+    background: #f4f4f4 url('select2-spinner.gif') no-repeat 100%;+}++.select2-more-results {+    background: #f4f4f4;+    display: list-item;+}++/* disabled styles */++.select2-container.select2-container-disabled .select2-choice {+    background-color: #f4f4f4;+    background-image: none;+    border: 1px solid #ddd;+    cursor: default;+}++.select2-container.select2-container-disabled .select2-choice .select2-arrow {+    background-color: #f4f4f4;+    background-image: none;+    border-left: 0;+}++.select2-container.select2-container-disabled .select2-choice abbr {+    display: none;+}+++/* multiselect */++.select2-container-multi .select2-choices {+    height: auto !important;+    height: 1%;+    margin: 0;+    padding: 0;+    position: relative;++    border: 1px solid #aaa;+    cursor: text;+    overflow: hidden;++    background-color: #fff;+    background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));+    background-image: -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%);+    background-image: -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%);+    background-image: -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%);+    background-image: -ms-linear-gradient(top, #eeeeee 1%, #ffffff 15%);+    background-image: linear-gradient(top, #eeeeee 1%, #ffffff 15%);+}++.select2-locked {+  padding: 3px 5px 3px 5px !important;+}++.select2-container-multi .select2-choices {+    min-height: 26px;+}++.select2-container-multi.select2-container-active .select2-choices {+    border: 1px solid #5897fb;+    outline: none;++    -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3);+       -moz-box-shadow: 0 0 5px rgba(0,0,0,.3);+            box-shadow: 0 0 5px rgba(0,0,0,.3);+}+.select2-container-multi .select2-choices li {+    float: left;+    list-style: none;+}+.select2-container-multi .select2-choices .select2-search-field {+    margin: 0;+    padding: 0;+    white-space: nowrap;+}++.select2-container-multi .select2-choices .select2-search-field input {+    padding: 5px;+    margin: 1px 0;++    font-family: sans-serif;+    font-size: 100%;+    color: #666;+    outline: 0;+    border: 0;+    -webkit-box-shadow: none;+       -moz-box-shadow: none;+            box-shadow: none;+    background: transparent !important;+}++.select2-container-multi .select2-choices .select2-search-field input.select2-active {+    background: #fff url('select2-spinner.gif') no-repeat 100% !important;+}++.select2-default {+    color: #999 !important;+}++.select2-container-multi .select2-choices .select2-search-choice {+    padding: 3px 5px 3px 18px;+    margin: 3px 0 3px 5px;+    position: relative;++    line-height: 13px;+    color: #333;+    cursor: default;+    border: 1px solid #aaaaaa;++    -webkit-border-radius: 3px;+       -moz-border-radius: 3px;+            border-radius: 3px;++    -webkit-box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);+       -moz-box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);+            box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);++    -webkit-background-clip: padding-box;+       -moz-background-clip: padding;+            background-clip: padding-box;++    -webkit-touch-callout: none;+      -webkit-user-select: none;+       -khtml-user-select: none;+         -moz-user-select: none;+          -ms-user-select: none;+              user-select: none;++    background-color: #e4e4e4;+    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#f4f4f4', GradientType=0 );+    background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));+    background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);+    background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);+    background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);+    background-image: -ms-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);+    background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);+}+.select2-container-multi .select2-choices .select2-search-choice .select2-chosen {+    cursor: default;+}+.select2-container-multi .select2-choices .select2-search-choice-focus {+    background: #d4d4d4;+}++.select2-search-choice-close {+    display: block;+    width: 12px;+    height: 13px;+    position: absolute;+    right: 3px;+    top: 4px;++    font-size: 1px;+    outline: none;+    background: url('select2.png') right top no-repeat;+}++.select2-container-multi .select2-search-choice-close {+    left: 3px;+}++.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover {+  background-position: right -11px;+}+.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close {+    background-position: right -11px;+}++/* disabled styles */+.select2-container-multi.select2-container-disabled .select2-choices{+    background-color: #f4f4f4;+    background-image: none;+    border: 1px solid #ddd;+    cursor: default;+}++.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice {+    padding: 3px 5px 3px 5px;+    border: 1px solid #ddd;+    background-image: none;+    background-color: #f4f4f4;+}++.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close {    display: none;+    background:none;+}+/* end multiselect */+++.select2-result-selectable .select2-match,+.select2-result-unselectable .select2-match {+    text-decoration: underline;+}++.select2-offscreen, .select2-offscreen:focus {+    clip: rect(0 0 0 0);+    width: 1px;+    height: 1px;+    border: 0;+    margin: 0;+    padding: 0;+    overflow: hidden;+    position: absolute;+    outline: 0;+    left: 0px;+}++.select2-display-none {+    display: none;+}++.select2-measure-scrollbar {+    position: absolute;+    top: -10000px;+    left: -10000px;+    width: 100px;+    height: 100px;+    overflow: scroll;+}+/* Retina-ize icons */++@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 144dpi)  {+  .select2-search input, .select2-search-choice-close, .select2-container .select2-choice abbr, .select2-container .select2-choice .select2-arrow b {+      background-image: url('select2x2.png') !important;+      background-repeat: no-repeat !important;+      background-size: 60px 40px !important;+  }+  .select2-search input {+      background-position: 100% -21px !important;+  }+}
+ static/css/select2.png view

binary file changed (absent → 613 bytes)

+ static/css/select2x2.png view

binary file changed (absent → 845 bytes)

templates/abook.julius view
@@ -24,7 +24,7 @@     };      //Set the address book type based on the dropdown.  The google-    //contacts is set in a seperate change handler which is only+    //contacts is set in a separate change handler which is only     //loaded depending on the settings.     aType.change(function() {         var v = $(this).val();
templates/compose.julius view
@@ -63,7 +63,7 @@         return false;     }); -    //parse a comma seperated list of addresses, supporting commas inside quotes in the name+    //parse a comma separated list of addresses, supporting commas inside quotes in the name     var parseAddrs = function(str) {         var pttrn = /( *"[^"]*"[^,"]*|[^",]+)(,)?/g;         var data = [];
+ tests/Address.hs view
@@ -0,0 +1,46 @@+{-# LANGUAGE OverloadedStrings #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+module Address (addrSpecs) where++import Import hiding (check)++import Handler.ComposeFields+import Network.Mail.Mime (Address(..))+import Test.Hspec+import Test.HUnit+import qualified Data.Text as T++instance Show Address where+    show = T.unpack . showAddress+instance Eq Address where+    (Address x1 y1) == (Address x2 y2) = x1 == x2 && y1 == y2++check :: T.Text -> [(T.Text, T.Text)] -> Assertion+check a expected = parsed @?= map build expected+    where+        mparsed = parseAddresses a+        parsed = case mparsed of+                  Left m -> error $ T.unpack $ renderMessage (undefined :: App) [] m+                  Right ps -> ps+        build ("",y) = Address Nothing y+        build (x,y) = Address (Just x) y++addrSpecs :: Spec+addrSpecs =+    describe "Parsing email addresses" $ do+      it "empty address" $+          check "" []+      it "single address" $+          check "abc@example.com" [("","abc@example.com")]+      it "multiple addresses" $+          check "abc@a.com, def@a.com" [("","abc@a.com"),("","def@a.com")]+      it "name and address" $+          check "John <john@a.com>" [("John", "john@a.com")]+      it "name in quotes" $+          check " \"John\" <a@b.com>" [("John", "a@b.com")]+      it "name in quotes with comma" $+          check "\"Armstrong, Niel\" <ff@ss.com>" [("Niel Armstrong", "ff@ss.com")]+      it "quotes and commas" $+          check "\"Armstrong, Niel, A\" <aa@ss.com>, bare@tt.com, John <john@ss.com> , \"Wow\" <ww@qwe.com>"+                [("Niel A Armstrong", "aa@ss.com"), ("","bare@tt.com"),+                 ("John", "john@ss.com"), ("Wow", "ww@qwe.com")]
+ tests/HomeTest.hs view
@@ -0,0 +1,16 @@+{-# LANGUAGE OverloadedStrings #-}+module HomeTest+    ( homeSpecs+    ) where++import Import hiding (get)+import Yesod.Test++homeSpecs :: YesodSpec App+homeSpecs =+  ydescribe "Basic home page tests" $+    yit "main page redirects to the login page" $ do+      get HomeR+      statusIs 303+      get ("/auth/login" :: String)+      bodyContains "Password"