├── api
├── .htaccess
├── Slim
│ ├── Environment.php
│ ├── Exception
│ │ ├── Pass.php
│ │ ├── RequestSlash.php
│ │ └── Stop.php
│ ├── Http
│ │ ├── Headers.php
│ │ ├── Request.php
│ │ ├── Response.php
│ │ └── Util.php
│ ├── Log.php
│ ├── LogFileWriter.php
│ ├── Middleware.php
│ ├── Middleware
│ │ ├── ContentTypes.php
│ │ ├── Flash.php
│ │ ├── MethodOverride.php
│ │ ├── PrettyExceptions.php
│ │ └── SessionCookie.php
│ ├── Route.php
│ ├── Router.php
│ ├── Slim.php
│ └── View.php
└── index.php
├── directory.sql
├── iphone
├── css
│ ├── images
│ │ ├── activity-indicator.png
│ │ ├── back-button-active.png
│ │ ├── back-button.png
│ │ ├── button-active.png
│ │ ├── button.png
│ │ ├── call.png
│ │ ├── comment-arrow.png
│ │ ├── detail-disclosure-button.png
│ │ ├── disclosure-indicator.png
│ │ ├── mail.png
│ │ ├── manager.png
│ │ ├── message.png
│ │ ├── navbar-bg.png
│ │ ├── navbar-landscape-bg.png
│ │ ├── refresh-icon.png
│ │ ├── reports.png
│ │ └── search-icon.png
│ └── styles.css
├── index.html
├── js
│ └── app.js
├── libs
│ ├── backbone-min.js
│ ├── jquery-1.7.2.min.js
│ └── underscore-min.js
├── pics
│ ├── Andy_Bernard.jpg
│ ├── Angela_Martin.jpg
│ ├── Creed_Bratton.jpg
│ ├── Dwight_Schrute.jpg
│ ├── Jim_Halpert.jpg
│ ├── Kelly_Kapoor.jpg
│ ├── Kevin_Malone.jpg
│ ├── Meredith_Palmer.jpg
│ ├── Michael_Scott.jpg
│ ├── Oscar_Martinez.jpg
│ ├── Pamela_Beesly.jpg
│ ├── Phyllis_Lapin.jpg
│ ├── Ryan_Howard.jpg
│ ├── Stanley_Hudson.jpg
│ └── Toby_Flenderson.jpg
└── tpl
│ ├── employee-list-item.html
│ ├── employee-page.html
│ ├── report-page.html
│ └── search-page.html
├── jquerymobile
├── css
│ ├── images
│ │ ├── ajax-loader.png
│ │ ├── icons-18-black.png
│ │ ├── icons-18-white.png
│ │ ├── icons-36-black.png
│ │ └── icons-36-white.png
│ ├── jquery.mobile-1.0.1.min.css
│ └── styles.css
├── img
│ └── logo.png
├── index.html
├── js
│ ├── jqm-config.js
│ ├── main.js
│ ├── models
│ │ └── employeemodel.js
│ ├── utils.js
│ └── views
│ │ ├── employeedetails.js
│ │ └── employeelist.js
├── lib
│ ├── backbone-min.js
│ ├── iscroll.js
│ ├── jquery-1.7.1.min.js
│ ├── jquery.mobile-1.0.1.min.js
│ └── underscore-min.js
├── pics
│ ├── Amy_Jones.jpg
│ ├── Amy_Jones100.jpg
│ ├── Amy_Jones50.jpg
│ ├── Eugene_Lee.jpg
│ ├── Eugene_Lee100.jpg
│ ├── Eugene_Lee50.jpg
│ ├── Gary_Donovan.jpg
│ ├── Gary_Donovan100.jpg
│ ├── Gary_Donovan50.jpg
│ ├── James_King.jpg
│ ├── James_King100.jpg
│ ├── James_King50.jpg
│ ├── John_Williams.jpg
│ ├── John_Williams100.jpg
│ ├── John_Williams50.jpg
│ ├── Julie_Taylor.jpg
│ ├── Julie_Taylor100.jpg
│ ├── Julie_Taylor50.jpg
│ ├── Kathleen_Byrne.jpg
│ ├── Kathleen_Byrne100.jpg
│ ├── Kathleen_Byrne50.jpg
│ ├── Lisa_Wong.jpg
│ ├── Lisa_Wong100.jpg
│ ├── Lisa_Wong50.jpg
│ ├── Paul_Jones.jpg
│ ├── Paul_Jones100.jpg
│ ├── Paul_Jones50.jpg
│ ├── Paula_Gates.jpg
│ ├── Paula_Gates100.jpg
│ ├── Paula_Gates50.jpg
│ ├── Ray_Moore.jpg
│ ├── Ray_Moore100.jpg
│ ├── Ray_Moore50.jpg
│ ├── Steven_Wells.jpg
│ ├── Steven_Wells100.jpg
│ └── Steven_Wells50.jpg
└── tpl
│ ├── employee-details.html
│ ├── employee-list-item.html
│ ├── report-list.html
│ └── search-page.html
├── localdb
├── css
│ ├── images
│ │ ├── activity-indicator.png
│ │ ├── back-button-active.png
│ │ ├── back-button.png
│ │ ├── button-active.png
│ │ ├── button.png
│ │ ├── call.png
│ │ ├── comment-arrow.png
│ │ ├── detail-disclosure-button.png
│ │ ├── disclosure-indicator.png
│ │ ├── mail.png
│ │ ├── manager.png
│ │ ├── message.png
│ │ ├── navbar-bg.png
│ │ ├── navbar-landscape-bg.png
│ │ ├── refresh-icon.png
│ │ ├── reports.png
│ │ └── search-icon.png
│ └── styles.css
├── index.html
├── js
│ └── app.js
├── libs
│ ├── backbone-min.js
│ ├── jquery-1.7.2.min.js
│ └── underscore-min.js
├── pics
│ ├── Andy_Bernard.jpg
│ ├── Angela_Martin.jpg
│ ├── Creed_Bratton.jpg
│ ├── Dwight_Schrute.jpg
│ ├── Jim_Halpert.jpg
│ ├── Kelly_Kapoor.jpg
│ ├── Kevin_Malone.jpg
│ ├── Meredith_Palmer.jpg
│ ├── Michael_Scott.jpg
│ ├── Oscar_Martinez.jpg
│ ├── Pamela_Beesly.jpg
│ ├── Phyllis_Lapin.jpg
│ ├── Ryan_Howard.jpg
│ ├── Stanley_Hudson.jpg
│ └── Toby_Flenderson.jpg
└── tpl
│ ├── employee-list-item.html
│ ├── employee-page.html
│ ├── report-page.html
│ └── search-page.html
├── readme.md
└── web
├── css
├── bootstrap.css
└── styles.css
├── img
├── glyphicons-halflings-white.png
├── glyphicons-halflings.png
└── logo.png
├── index.html
├── js
├── main.js
├── models
│ └── employeemodel.js
├── utils.js
└── views
│ ├── contact.js
│ ├── employeedetails.js
│ ├── employeelist.js
│ ├── header.js
│ └── home.js
├── lib
├── backbone-min.js
├── jquery-1.7.2.min.js
└── underscore-min.js
├── pics
├── Amy_Jones.jpg
├── Amy_Jones50.jpg
├── Eugene_Lee.jpg
├── Eugene_Lee50.jpg
├── Gary_Donovan.jpg
├── Gary_Donovan50.jpg
├── James_King.jpg
├── James_King50.jpg
├── John_Williams.jpg
├── John_Williams50.jpg
├── Julie_Taylor.jpg
├── Julie_Taylor50.jpg
├── Kathleen_Byrne.jpg
├── Kathleen_Byrne50.jpg
├── Lisa_Wong.jpg
├── Lisa_Wong50.jpg
├── Paul_Jones.jpg
├── Paul_Jones50.jpg
├── Paula_Gates.jpg
├── Paula_Gates50.jpg
├── Ray_Moore.jpg
├── Ray_Moore50.jpg
├── Steven_Wells.jpg
└── Steven_Wells50.jpg
└── tpl
├── ContactView.html
├── EmployeeListItemView.html
├── EmployeeSummaryView.html
├── EmployeeView.html
├── HeaderView.html
└── HomeView.html
/api/.htaccess:
--------------------------------------------------------------------------------
1 | RewriteEngine On
2 |
3 | # Some hosts may require you to use the `RewriteBase` directive.
4 | # If you need to use the `RewriteBase` directive, it should be the
5 | # absolute physical path to the directory that contains this htaccess file.
6 | #
7 | # RewriteBase /
8 |
9 | RewriteCond %{REQUEST_FILENAME} !-f
10 | RewriteRule ^(.*)$ index.php [QSA,L]
--------------------------------------------------------------------------------
/api/Slim/Environment.php:
--------------------------------------------------------------------------------
1 |
6 | * @copyright 2011 Josh Lockhart
7 | * @link http://www.slimframework.com
8 | * @license http://www.slimframework.com/license
9 | * @version 1.6.0
10 | * @package Slim
11 | *
12 | * MIT LICENSE
13 | *
14 | * Permission is hereby granted, free of charge, to any person obtaining
15 | * a copy of this software and associated documentation files (the
16 | * "Software"), to deal in the Software without restriction, including
17 | * without limitation the rights to use, copy, modify, merge, publish,
18 | * distribute, sublicense, and/or sell copies of the Software, and to
19 | * permit persons to whom the Software is furnished to do so, subject to
20 | * the following conditions:
21 | *
22 | * The above copyright notice and this permission notice shall be
23 | * included in all copies or substantial portions of the Software.
24 | *
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 | */
33 |
34 | /**
35 | * Environment
36 | *
37 | * This class creates and returns a key/value array of common
38 | * environment variables for the current HTTP request.
39 | *
40 | * This is a singleton class; derived environment variables will
41 | * be common across multiple Slim applications.
42 | *
43 | * This class matches the Rack (Ruby) specification as closely
44 | * as possible. More information available below.
45 | *
46 | * @package Slim
47 | * @author Josh Lockhart
48 | * @since 1.6.0
49 | */
50 | class Slim_Environment implements ArrayAccess, IteratorAggregate {
51 | /**
52 | * @var array
53 | */
54 | protected $properties;
55 |
56 | /**
57 | * @var Slim_Environment
58 | */
59 | protected static $environment;
60 |
61 | /**
62 | * Get environment instance (singleton)
63 | *
64 | * This creates and/or returns an Environment instance (singleton)
65 | * derived from $_SERVER variables. You may override the global server
66 | * variables by using `Environment::mock()` instead.
67 | *
68 | * @param bool $refresh Refresh properties using global server variables?
69 | * @return Slim_Environment
70 | */
71 | public static function getInstance( $refresh = false ) {
72 | if ( is_null(self::$environment) || $refresh ) {
73 | self::$environment = new self();
74 | }
75 | return self::$environment;
76 | }
77 |
78 | /**
79 | * Get mock environment instance
80 | *
81 | * @param array $userSettings
82 | * @return Environment
83 | */
84 | public static function mock( $userSettings = array() ) {
85 | self::$environment = new self(array_merge(array(
86 | 'REQUEST_METHOD' => 'GET',
87 | 'SCRIPT_NAME' => '',
88 | 'PATH_INFO' => '',
89 | 'QUERY_STRING' => '',
90 | 'SERVER_NAME' => 'localhost',
91 | 'SERVER_PORT' => 80,
92 | 'ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
93 | 'ACCEPT_LANGUAGE' => 'en-US,en;q=0.8',
94 | 'ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
95 | 'USER_AGENT' => 'Slim Framework',
96 | 'REMOTE_ADDR' => '127.0.0.1',
97 | 'slim.url_scheme' => 'http',
98 | 'slim.input' => '',
99 | 'slim.errors' => @fopen('php://stderr', 'w')
100 | ), $userSettings));
101 | return self::$environment;
102 | }
103 |
104 | /**
105 | * Constructor (private access)
106 | *
107 | * @param array|null $settings If present, these are used instead of global server variables
108 | * @return void
109 | */
110 | private function __construct( $settings = null ) {
111 | if ( $settings ) {
112 | $this->properties = $settings;
113 | } else {
114 | $env = array();
115 |
116 | //The HTTP request method
117 | $env['REQUEST_METHOD'] = $_SERVER['REQUEST_METHOD'];
118 |
119 | //The IP
120 | $env['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'];
121 |
122 | /**
123 | * Application paths
124 | *
125 | * This derives two paths: SCRIPT_NAME and PATH_INFO. The SCRIPT_NAME
126 | * is the real, physical path to the application, be it in the root
127 | * directory or a subdirectory of the public document root. The PATH_INFO is the
128 | * virtual path to the requested resource within the application context.
129 | *
130 | * With htaccess, the SCRIPT_NAME will be an absolute path (without file name);
131 | * if not using htaccess, it will also include the file name. If it is "/",
132 | * it is set to an empty string (since it cannot have a trailing slash).
133 | *
134 | * The PATH_INFO will be an absolute path with a leading slash; this will be
135 | * used for application routing.
136 | */
137 | if ( strpos($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME']) === 0 ) {
138 | $env['SCRIPT_NAME'] = $_SERVER['SCRIPT_NAME']; //Without URL rewrite
139 | } else {
140 | $env['SCRIPT_NAME'] = str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME']) ); //With URL rewrite
141 | }
142 | $env['PATH_INFO'] = substr_replace($_SERVER['REQUEST_URI'], '', 0, strlen($env['SCRIPT_NAME']));
143 | if ( strpos($env['PATH_INFO'], '?') !== false ) {
144 | $env['PATH_INFO'] = substr_replace($env['PATH_INFO'], '', strpos($env['PATH_INFO'], '?')); //query string is not removed automatically
145 | }
146 | $env['SCRIPT_NAME'] = rtrim($env['SCRIPT_NAME'], '/');
147 | $env['PATH_INFO'] = '/' . ltrim($env['PATH_INFO'], '/');
148 |
149 | //The portion of the request URI following the '?'
150 | $env['QUERY_STRING'] = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : '';
151 |
152 | //Name of server host that is running the script
153 | $env['SERVER_NAME'] = $_SERVER['SERVER_NAME'];
154 |
155 | //Number of server port that is running the script
156 | $env['SERVER_PORT'] = $_SERVER['SERVER_PORT'];
157 |
158 | //HTTP request headers
159 | $specialHeaders = array('CONTENT_TYPE', 'CONTENT_LENGTH', 'PHP_AUTH_USER', 'PHP_AUTH_PW', 'PHP_AUTH_DIGEST', 'AUTH_TYPE');
160 | foreach ( $_SERVER as $key => $value ) {
161 | $value = is_string($value) ? trim($value) : $value;
162 | if ( strpos($key, 'HTTP_') === 0 ) {
163 | $env[substr($key, 5)] = $value;
164 | } else if ( strpos($key, 'X_') === 0 || in_array($key, $specialHeaders) ) {
165 | $env[$key] = $value;
166 | }
167 | }
168 |
169 | //Is the application running under HTTPS or HTTP protocol?
170 | $env['slim.url_scheme'] = empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] === 'off' ? 'http' : 'https';
171 |
172 | //Input stream (readable one time only; not available for mutipart/form-data requests)
173 | $rawInput = @file_get_contents('php://input');
174 | if ( !$rawInput ) {
175 | $rawInput = '';
176 | }
177 | $env['slim.input'] = $rawInput;
178 |
179 | //Error stream
180 | $env['slim.errors'] = fopen('php://stderr', 'w');
181 |
182 | $this->properties = $env;
183 | }
184 | }
185 |
186 | /**
187 | * Array Access: Offset Exists
188 | */
189 | public function offsetExists( $offset ) {
190 | return isset($this->properties[$offset]);
191 | }
192 |
193 | /**
194 | * Array Access: Offset Get
195 | */
196 | public function offsetGet( $offset ) {
197 | if ( isset($this->properties[$offset]) ) {
198 | return $this->properties[$offset];
199 | } else {
200 | return null;
201 | }
202 | }
203 |
204 | /**
205 | * Array Access: Offset Set
206 | */
207 | public function offsetSet( $offset, $value ) {
208 | $this->properties[$offset] = $value;
209 | }
210 |
211 | /**
212 | * Array Access: Offset Unset
213 | */
214 | public function offsetUnset( $offset ) {
215 | unset($this->properties[$offset]);
216 | }
217 |
218 | /**
219 | * IteratorAggregate
220 | *
221 | * @return ArrayIterator
222 | */
223 | public function getIterator() {
224 | return new ArrayIterator($this->properties);
225 | }
226 | }
227 |
--------------------------------------------------------------------------------
/api/Slim/Exception/Pass.php:
--------------------------------------------------------------------------------
1 |
6 | * @copyright 2011 Josh Lockhart
7 | * @link http://www.slimframework.com
8 | * @license http://www.slimframework.com/license
9 | * @version 1.6.0
10 | * @package Slim
11 | *
12 | * MIT LICENSE
13 | *
14 | * Permission is hereby granted, free of charge, to any person obtaining
15 | * a copy of this software and associated documentation files (the
16 | * "Software"), to deal in the Software without restriction, including
17 | * without limitation the rights to use, copy, modify, merge, publish,
18 | * distribute, sublicense, and/or sell copies of the Software, and to
19 | * permit persons to whom the Software is furnished to do so, subject to
20 | * the following conditions:
21 | *
22 | * The above copyright notice and this permission notice shall be
23 | * included in all copies or substantial portions of the Software.
24 | *
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 | */
33 |
34 | /**
35 | * Pass Exception
36 | *
37 | * This Exception will cause the Router::dispatch method
38 | * to skip the current matching route and continue to the next
39 | * matching route. If no subsequent routes are found, a
40 | * HTTP 404 Not Found response will be sent to the client.
41 | *
42 | * @package Slim
43 | * @author Josh Lockhart
44 | * @since 1.0.0
45 | */
46 | class Slim_Exception_Pass extends Exception {}
--------------------------------------------------------------------------------
/api/Slim/Exception/RequestSlash.php:
--------------------------------------------------------------------------------
1 |
6 | * @copyright 2011 Josh Lockhart
7 | * @link http://www.slimframework.com
8 | * @license http://www.slimframework.com/license
9 | * @version 1.6.0
10 | * @package Slim
11 | *
12 | * MIT LICENSE
13 | *
14 | * Permission is hereby granted, free of charge, to any person obtaining
15 | * a copy of this software and associated documentation files (the
16 | * "Software"), to deal in the Software without restriction, including
17 | * without limitation the rights to use, copy, modify, merge, publish,
18 | * distribute, sublicense, and/or sell copies of the Software, and to
19 | * permit persons to whom the Software is furnished to do so, subject to
20 | * the following conditions:
21 | *
22 | * The above copyright notice and this permission notice shall be
23 | * included in all copies or substantial portions of the Software.
24 | *
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 | */
33 |
34 | /**
35 | * Request Slash Exception
36 | *
37 | * This Exception is thrown when Slim detects a matching route
38 | * (defined with a trailing slash) and the HTTP request
39 | * matches the route but does not have a trailing slash. This
40 | * exception will be caught in `Slim::run` and trigger a 301 redirect
41 | * to the same resource URI with a trailing slash.
42 | *
43 | * @package Slim
44 | * @author Josh Lockhart
45 | * @since 1.0.0
46 | */
47 | class Slim_Exception_RequestSlash extends Exception {}
--------------------------------------------------------------------------------
/api/Slim/Exception/Stop.php:
--------------------------------------------------------------------------------
1 |
6 | * @copyright 2011 Josh Lockhart
7 | * @link http://www.slimframework.com
8 | * @license http://www.slimframework.com/license
9 | * @version 1.6.0
10 | * @package Slim
11 | *
12 | * MIT LICENSE
13 | *
14 | * Permission is hereby granted, free of charge, to any person obtaining
15 | * a copy of this software and associated documentation files (the
16 | * "Software"), to deal in the Software without restriction, including
17 | * without limitation the rights to use, copy, modify, merge, publish,
18 | * distribute, sublicense, and/or sell copies of the Software, and to
19 | * permit persons to whom the Software is furnished to do so, subject to
20 | * the following conditions:
21 | *
22 | * The above copyright notice and this permission notice shall be
23 | * included in all copies or substantial portions of the Software.
24 | *
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 | */
33 |
34 | /**
35 | * Stop Exception
36 | *
37 | * This Exception is thrown when the Slim application needs to abort
38 | * processing and return control flow to the outer PHP script.
39 | *
40 | * @package Slim
41 | * @author Josh Lockhart
42 | * @since 1.0.0
43 | */
44 | class Slim_Exception_Stop extends Exception {}
--------------------------------------------------------------------------------
/api/Slim/Http/Headers.php:
--------------------------------------------------------------------------------
1 |
6 | * @copyright 2011 Josh Lockhart
7 | * @link http://www.slimframework.com
8 | * @license http://www.slimframework.com/license
9 | * @version 1.6.0
10 | * @package Slim
11 | *
12 | * MIT LICENSE
13 | *
14 | * Permission is hereby granted, free of charge, to any person obtaining
15 | * a copy of this software and associated documentation files (the
16 | * "Software"), to deal in the Software without restriction, including
17 | * without limitation the rights to use, copy, modify, merge, publish,
18 | * distribute, sublicense, and/or sell copies of the Software, and to
19 | * permit persons to whom the Software is furnished to do so, subject to
20 | * the following conditions:
21 | *
22 | * The above copyright notice and this permission notice shall be
23 | * included in all copies or substantial portions of the Software.
24 | *
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 | */
33 |
34 | /**
35 | * HTTP Headers
36 | *
37 | * This class is an abstraction of the HTTP response headers and
38 | * provides array access to the header list while automatically
39 | * stores and retrieves headers with lowercase canonical keys regardless
40 | * of the input format.
41 | *
42 | * This class also implements the `Iterator` and `Countable`
43 | * interfaces for even more convenient usage.
44 | *
45 | * @package Slim
46 | * @author Josh Lockhart
47 | * @since 1.6.0
48 | */
49 | class Slim_Http_Headers implements ArrayAccess, Iterator, Countable {
50 | /**
51 | * @var array HTTP headers
52 | */
53 | protected $headers;
54 |
55 | /**
56 | * @var array Map canonical header name to original header name
57 | */
58 | protected $map;
59 |
60 | /**
61 | * Constructor
62 | * @param array $headers
63 | * @return void
64 | */
65 | public function __construct( $headers = array() ) {
66 | $this->merge($headers);
67 | }
68 |
69 | /**
70 | * Merge Headers
71 | * @param array $headers
72 | * @return void
73 | */
74 | public function merge( $headers ) {
75 | foreach ( $headers as $name => $value ) {
76 | $this[$name] = $value;
77 | }
78 | }
79 |
80 | /**
81 | * Transform header name into canonical form
82 | * @param string $name
83 | * @return string
84 | */
85 | protected function canonical( $name ) {
86 | return strtolower(trim($name));
87 | }
88 |
89 | /**
90 | * Array Access: Offset Exists
91 | */
92 | public function offsetExists( $offset ) {
93 | return isset($this->headers[$this->canonical($offset)]);
94 | }
95 |
96 | /**
97 | * Array Access: Offset Get
98 | */
99 | public function offsetGet( $offset ) {
100 | $canonical = $this->canonical($offset);
101 | if ( isset($this->headers[$canonical]) ) {
102 | return $this->headers[$canonical];
103 | } else {
104 | return null;
105 | }
106 | }
107 |
108 | /**
109 | * Array Access: Offset Set
110 | */
111 | public function offsetSet( $offset, $value ) {
112 | $canonical = $this->canonical($offset);
113 | $this->headers[$canonical] = $value;
114 | $this->map[$canonical] = $offset;
115 | }
116 |
117 | /**
118 | * Array Access: Offset Unset
119 | */
120 | public function offsetUnset( $offset ) {
121 | $canonical = $this->canonical($offset);
122 | unset($this->headers[$canonical], $this->map[$canonical]);
123 | }
124 |
125 | /**
126 | * Countable: Count
127 | */
128 | public function count() {
129 | return count($this->headers);
130 | }
131 |
132 | /**
133 | * Iterator: Rewind
134 | */
135 | public function rewind() {
136 | reset($this->headers);
137 | }
138 |
139 | /**
140 | * Iterator: Current
141 | */
142 | public function current() {
143 | return current($this->headers);
144 | }
145 |
146 | /**
147 | * Iterator: Key
148 | */
149 | public function key() {
150 | $key = key($this->headers);
151 | return $this->map[$key];
152 | }
153 |
154 | /**
155 | * Iterator: Next
156 | */
157 | public function next() {
158 | return next($this->headers);
159 | }
160 |
161 | /**
162 | * Iterator: Valid
163 | */
164 | public function valid() {
165 | return current($this->headers) !== false;
166 | }
167 | }
--------------------------------------------------------------------------------
/api/Slim/Log.php:
--------------------------------------------------------------------------------
1 |
6 | * @copyright 2011 Josh Lockhart
7 | * @link http://www.slimframework.com
8 | * @license http://www.slimframework.com/license
9 | * @version 1.6.0
10 | * @package Slim
11 | *
12 | * MIT LICENSE
13 | *
14 | * Permission is hereby granted, free of charge, to any person obtaining
15 | * a copy of this software and associated documentation files (the
16 | * "Software"), to deal in the Software without restriction, including
17 | * without limitation the rights to use, copy, modify, merge, publish,
18 | * distribute, sublicense, and/or sell copies of the Software, and to
19 | * permit persons to whom the Software is furnished to do so, subject to
20 | * the following conditions:
21 | *
22 | * The above copyright notice and this permission notice shall be
23 | * included in all copies or substantial portions of the Software.
24 | *
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 | */
33 |
34 | /**
35 | * Log
36 | *
37 | * This is the primary logger for a Slim application. You may provide
38 | * a Log Writer in conjunction with this Log to write to various output
39 | * destinations (e.g. a file). This class provides this interface:
40 | *
41 | * debug( mixed $object )
42 | * info( mixed $object )
43 | * warn( mixed $object )
44 | * error( mixed $object )
45 | * fatal( mixed $object )
46 | *
47 | * This class assumes only that your Log Writer has a public `write()` method
48 | * that accepts any object as its one and only argument. The Log Writer
49 | * class may write or send its argument anywhere: a file, STDERR,
50 | * a remote web API, etc. The possibilities are endless.
51 | *
52 | * @package Slim
53 | * @author Josh Lockhart
54 | * @since 1.0.0
55 | */
56 | class Slim_Log {
57 | /**
58 | * @var array
59 | */
60 | static protected $levels = array(
61 | 0 => 'FATAL',
62 | 1 => 'ERROR',
63 | 2 => 'WARN',
64 | 3 => 'INFO',
65 | 4 => 'DEBUG'
66 | );
67 |
68 | /**
69 | * @var mixed
70 | */
71 | protected $writer;
72 |
73 | /**
74 | * @var bool
75 | */
76 | protected $enabled;
77 |
78 | /**
79 | * @var int
80 | */
81 | protected $level;
82 |
83 | /**
84 | * Constructor
85 | * @param mixed $writer
86 | * @return void
87 | */
88 | public function __construct( $writer ) {
89 | $this->writer = $writer;
90 | $this->enabled = true;
91 | $this->level = 4;
92 | }
93 |
94 | /**
95 | * Is logging enabled?
96 | * @return bool
97 | */
98 | public function getEnabled() {
99 | return $this->enabled;
100 | }
101 |
102 | /**
103 | * Enable or disable logging
104 | * @param bool $enabled
105 | * @return void
106 | */
107 | public function setEnabled( $enabled ) {
108 | if ( $enabled ) {
109 | $this->enabled = true;
110 | } else {
111 | $this->enabled = false;
112 | }
113 | }
114 |
115 | /**
116 | * Set level
117 | * @param int $level
118 | * @return void
119 | * @throws InvalidArgumentException
120 | */
121 | public function setLevel( $level ) {
122 | if ( !isset(self::$levels[$level]) ) {
123 | throw new InvalidArgumentException('Invalid log level');
124 | }
125 | $this->level = $level;
126 | }
127 |
128 | /**
129 | * Get level
130 | * @return int
131 | */
132 | public function getLevel() {
133 | return $this->level;
134 | }
135 |
136 | /**
137 | * Set writer
138 | * @param mixed $writer
139 | * @return void
140 | */
141 | public function setWriter( $writer ) {
142 | $this->writer = $writer;
143 | }
144 |
145 | /**
146 | * Get writer
147 | * @return mixed
148 | */
149 | public function getWriter() {
150 | return $this->writer;
151 | }
152 |
153 | /**
154 | * Is logging enabled?
155 | * @return bool
156 | */
157 | public function isEnabled() {
158 | return $this->enabled;
159 | }
160 |
161 | /**
162 | * Log debug message
163 | * @param mixed $object
164 | * @return mixed|false What the Logger returns, or false if Logger not set or not enabled
165 | */
166 | public function debug( $object ) {
167 | return $this->log($object, 4);
168 | }
169 |
170 | /**
171 | * Log info message
172 | * @param mixed $object
173 | * @return mixed|false What the Logger returns, or false if Logger not set or not enabled
174 | */
175 | public function info( $object ) {
176 | return $this->log($object, 3);
177 | }
178 |
179 | /**
180 | * Log warn message
181 | * @param mixed $object
182 | * @return mixed|false What the Logger returns, or false if Logger not set or not enabled
183 | */
184 | public function warn( $object ) {
185 | return $this->log($object, 2);
186 | }
187 |
188 | /**
189 | * Log error message
190 | * @param mixed $object
191 | * @return mixed|false What the Logger returns, or false if Logger not set or not enabled
192 | */
193 | public function error( $object ) {
194 | return $this->log($object, 1);
195 | }
196 |
197 | /**
198 | * Log fatal message
199 | * @param mixed $object
200 | * @return mixed|false What the Logger returns, or false if Logger not set or not enabled
201 | */
202 | public function fatal( $object ) {
203 | return $this->log($object, 0);
204 | }
205 |
206 | /**
207 | * Log message
208 | * @param mixed The object to log
209 | * @param int The message level
210 | * @return int|false
211 | */
212 | protected function log( $object, $level ) {
213 | if ( $this->enabled && $this->writer && $level <= $this->level ) {
214 | return $this->writer->write($object, $level);
215 | } else {
216 | return false;
217 | }
218 | }
219 | }
--------------------------------------------------------------------------------
/api/Slim/LogFileWriter.php:
--------------------------------------------------------------------------------
1 |
6 | * @copyright 2011 Josh Lockhart
7 | * @link http://www.slimframework.com
8 | * @license http://www.slimframework.com/license
9 | * @version 1.6.0
10 | * @package Slim
11 | *
12 | * MIT LICENSE
13 | *
14 | * Permission is hereby granted, free of charge, to any person obtaining
15 | * a copy of this software and associated documentation files (the
16 | * "Software"), to deal in the Software without restriction, including
17 | * without limitation the rights to use, copy, modify, merge, publish,
18 | * distribute, sublicense, and/or sell copies of the Software, and to
19 | * permit persons to whom the Software is furnished to do so, subject to
20 | * the following conditions:
21 | *
22 | * The above copyright notice and this permission notice shall be
23 | * included in all copies or substantial portions of the Software.
24 | *
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 | */
33 |
34 | /**
35 | * Log File Writer
36 | *
37 | * This class is used by Slim_Log to write log messages to a valid, writable
38 | * resource handle (e.g. a file or STDERR).
39 | *
40 | * @package Slim
41 | * @author Josh Lockhart
42 | * @since 1.5.2
43 | */
44 | class Slim_LogFileWriter {
45 | /**
46 | * @var resource
47 | */
48 | protected $resource;
49 |
50 | /**
51 | * Constructor
52 | * @param resource $resource
53 | * @return void
54 | * @throws InvalidArgumentException
55 | */
56 | public function __construct( $resource ) {
57 | if ( !is_resource($resource) ) {
58 | throw new InvalidArgumentException('Cannot create LogFileWriter. Invalid resource handle.');
59 | }
60 | $this->resource = $resource;
61 | }
62 |
63 | /**
64 | * Write message
65 | * @param mixed $message
66 | * @param int $level
67 | * @return int|false
68 | */
69 | public function write( $message, $level = null ) {
70 | return fwrite($this->resource, (string)$message . PHP_EOL);
71 | }
72 | }
--------------------------------------------------------------------------------
/api/Slim/Middleware.php:
--------------------------------------------------------------------------------
1 |
6 | * @copyright 2011 Josh Lockhart
7 | * @link http://www.slimframework.com
8 | * @license http://www.slimframework.com/license
9 | * @version 1.6.0
10 | * @package Slim
11 | *
12 | * MIT LICENSE
13 | *
14 | * Permission is hereby granted, free of charge, to any person obtaining
15 | * a copy of this software and associated documentation files (the
16 | * "Software"), to deal in the Software without restriction, including
17 | * without limitation the rights to use, copy, modify, merge, publish,
18 | * distribute, sublicense, and/or sell copies of the Software, and to
19 | * permit persons to whom the Software is furnished to do so, subject to
20 | * the following conditions:
21 | *
22 | * The above copyright notice and this permission notice shall be
23 | * included in all copies or substantial portions of the Software.
24 | *
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 | */
33 |
34 | /**
35 | * Middleware
36 | *
37 | * @package Slim
38 | * @author Josh Lockhart
39 | * @since 1.6.0
40 | */
41 | abstract class Slim_Middleware {
42 | /**
43 | * @var Slim Reference to the primary Slim application instance
44 | */
45 | protected $app;
46 |
47 | /**
48 | * @var mixed Reference to the next downstream middleware
49 | */
50 | protected $next;
51 |
52 | /**
53 | * Set application
54 | *
55 | * This method injects the primary Slim application instance into
56 | * this middleware.
57 | *
58 | * @param Slim $application
59 | * @return void
60 | */
61 | final public function setApplication( $application ) {
62 | $this->app = $application;
63 | }
64 |
65 | /**
66 | * Get application
67 | *
68 | * This method retrieves the application previously injected
69 | * into this middleware.
70 | *
71 | * @return Slim
72 | */
73 | final public function getApplication() {
74 | return $this->app;
75 | }
76 |
77 | /**
78 | * Set next middleware
79 | *
80 | * This method injects the next downstream middleware into
81 | * this middleware so that it may optionally be called
82 | * when appropriate.
83 | *
84 | * @param Slim|Slim_Middleware
85 | * @return void
86 | */
87 | final public function setNextMiddleware( $nextMiddleware ) {
88 | $this->next = $nextMiddleware;
89 | }
90 |
91 | /**
92 | * Get next middleware
93 | *
94 | * This method retrieves the next downstream middleware
95 | * previously injected into this middleware.
96 | *
97 | * @return Slim|Slim_Middleware
98 | */
99 | final public function getNextMiddleware() {
100 | return $this->next;
101 | }
102 |
103 | /**
104 | * Call
105 | *
106 | * Perform actions specific to this middleware and optionally
107 | * call the next downstream middleware.
108 | *
109 | * @return void
110 | */
111 | abstract public function call();
112 | }
--------------------------------------------------------------------------------
/api/Slim/Middleware/ContentTypes.php:
--------------------------------------------------------------------------------
1 |
6 | * @copyright 2011 Josh Lockhart
7 | * @link http://www.slimframework.com
8 | * @license http://www.slimframework.com/license
9 | * @version 1.6.0
10 | * @package Slim
11 | *
12 | * MIT LICENSE
13 | *
14 | * Permission is hereby granted, free of charge, to any person obtaining
15 | * a copy of this software and associated documentation files (the
16 | * "Software"), to deal in the Software without restriction, including
17 | * without limitation the rights to use, copy, modify, merge, publish,
18 | * distribute, sublicense, and/or sell copies of the Software, and to
19 | * permit persons to whom the Software is furnished to do so, subject to
20 | * the following conditions:
21 | *
22 | * The above copyright notice and this permission notice shall be
23 | * included in all copies or substantial portions of the Software.
24 | *
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 | */
33 |
34 | /**
35 | * Content Types
36 | *
37 | * This is middleware for a Slim application that intercepts
38 | * the HTTP request body and parses it into the appropriate
39 | * PHP data structure if possible; else it returns the HTTP
40 | * request body unchanged. This is particularly useful
41 | * for preparing the HTTP request body for an XML or JSON API.
42 | *
43 | * @package Slim
44 | * @author Josh Lockhart
45 | * @since 1.5.2
46 | */
47 | class Slim_Middleware_ContentTypes extends Slim_Middleware {
48 | /**
49 | * @var array
50 | */
51 | protected $contentTypes;
52 |
53 | /**
54 | * Constructor
55 | * @param array $settings
56 | */
57 | public function __construct( $settings = array() ) {
58 | $this->contentTypes = array_merge(array(
59 | 'application/json' => array($this, 'parseJson'),
60 | 'application/xml' => array($this, 'parseXml'),
61 | 'text/xml' => array($this, 'parseXml'),
62 | 'text/csv' => array($this, 'parseCsv')
63 | ), $settings);
64 | }
65 |
66 | /**
67 | * Call
68 | * @return void
69 | */
70 | public function call() {
71 | $mediaType = $this->app->request()->getMediaType();
72 | if ( $mediaType ) {
73 | $env = $this->app->environment();
74 | $env['slim.input_original'] = $env['slim.input'];
75 | $env['slim.input'] = $this->parse($env['slim.input'], $mediaType);
76 | }
77 | $this->next->call();
78 | }
79 |
80 | /**
81 | * Parse input
82 | *
83 | * This method will attempt to parse the request body
84 | * based on its content type if available.
85 | *
86 | * @param string $input
87 | * @param string $contentType
88 | * @return mixed
89 | */
90 | protected function parse ( $input, $contentType ) {
91 | if ( isset($this->contentTypes[$contentType]) && is_callable($this->contentTypes[$contentType]) ) {
92 | $result = call_user_func($this->contentTypes[$contentType], $input);
93 | if ( $result ) {
94 | return $result;
95 | }
96 | }
97 | return $input;
98 | }
99 |
100 | /**
101 | * Parse JSON
102 | *
103 | * This method converts the raw JSON input
104 | * into an associative array.
105 | *
106 | * @param string $input
107 | * @return array|string
108 | */
109 | protected function parseJson( $input ) {
110 | if ( function_exists('json_decode') ) {
111 | $result = json_decode($input, true);
112 | if ( $result ) {
113 | return $result;
114 | }
115 | }
116 | }
117 |
118 | /**
119 | * Parse XML
120 | *
121 | * This method creates a SimpleXMLElement
122 | * based upon the XML input. If the SimpleXML
123 | * extension is not available, the raw input
124 | * will be returned unchanged.
125 | *
126 | * @param string $input
127 | * @return SimpleXMLElement|string
128 | */
129 | protected function parseXml( $input ) {
130 | if ( class_exists('SimpleXMLElement') ) {
131 | try {
132 | return new SimpleXMLElement($input);
133 | } catch ( Exception $e ) {}
134 | }
135 | return $input;
136 | }
137 |
138 | /**
139 | * Parse CSV
140 | *
141 | * This method parses CSV content into a numeric array
142 | * containing an array of data for each CSV line.
143 | *
144 | * @param string $input
145 | * @return array
146 | */
147 | protected function parseCsv( $input ) {
148 | $temp = fopen('php://memory', 'rw');
149 | fwrite($temp, $input);
150 | fseek($temp, 0);
151 | $res = array();
152 | while ( ($data = fgetcsv($temp)) !== false ) {
153 | $res[] = $data;
154 | }
155 | fclose($temp);
156 | return $res;
157 | }
158 | }
--------------------------------------------------------------------------------
/api/Slim/Middleware/Flash.php:
--------------------------------------------------------------------------------
1 |
6 | * @copyright 2011 Josh Lockhart
7 | * @link http://www.slimframework.com
8 | * @license http://www.slimframework.com/license
9 | * @version 1.6.0
10 | * @package Slim
11 | *
12 | * MIT LICENSE
13 | *
14 | * Permission is hereby granted, free of charge, to any person obtaining
15 | * a copy of this software and associated documentation files (the
16 | * "Software"), to deal in the Software without restriction, including
17 | * without limitation the rights to use, copy, modify, merge, publish,
18 | * distribute, sublicense, and/or sell copies of the Software, and to
19 | * permit persons to whom the Software is furnished to do so, subject to
20 | * the following conditions:
21 | *
22 | * The above copyright notice and this permission notice shall be
23 | * included in all copies or substantial portions of the Software.
24 | *
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 | */
33 |
34 | /**
35 | * Flash
36 | *
37 | * This is middleware for a Slim application that enables
38 | * Flash messaging between HTTP requests. This allows you
39 | * set Flash messages for the current request, for the next request,
40 | * or to retain messages from the previous request through to
41 | * the next request.
42 | *
43 | * @package Slim
44 | * @author Josh Lockhart
45 | * @since 1.5.2
46 | */
47 | class Slim_Middleware_Flash extends Slim_Middleware implements ArrayAccess {
48 | /**
49 | * @var array
50 | */
51 | protected $settings;
52 |
53 | /**
54 | * @var array
55 | */
56 | protected $messages;
57 |
58 | /**
59 | * Constructor
60 | * @param Slim $app
61 | * @param array $settings
62 | * @return void
63 | */
64 | public function __construct( $settings = array() ) {
65 | $this->settings = array_merge(array('key' => 'slim.flash'), $settings);
66 | $this->messages = array(
67 | 'prev' => array(), //flash messages from prev request (loaded when middleware called)
68 | 'next' => array(), //flash messages for next request
69 | 'now' => array() //flash messages for current request
70 | );
71 | }
72 |
73 | /**
74 | * Call
75 | * @return void
76 | */
77 | public function call() {
78 | //Read flash messaging from previous request if available
79 | $this->loadMessages();
80 |
81 | //Prepare flash messaging for current request
82 | $env = $this->app->environment();
83 | $env['slim.flash'] = $this;
84 | $this->next->call();
85 | $this->save();
86 | }
87 |
88 | /**
89 | * Now
90 | *
91 | * Specify a flash message for a given key to be shown for the current request
92 | *
93 | * @param string $key
94 | * @param string $value
95 | * @return void
96 | */
97 | public function now( $key, $value ) {
98 | $this->messages['now'][(string)$key] = $value;
99 | }
100 |
101 | /**
102 | * Set
103 | *
104 | * Specify a flash message for a given key to be shown for the next request
105 | *
106 | * @param string $key
107 | * @param string $value
108 | * @return void
109 | */
110 | public function set( $key, $value ) {
111 | $this->messages['next'][(string)$key] = $value;
112 | }
113 |
114 | /**
115 | * Keep
116 | *
117 | * Retain flash messages from the previous request for the next request
118 | *
119 | * @return void
120 | */
121 | public function keep() {
122 | foreach ( $this->messages['prev'] as $key => $val ) {
123 | $this->messages['next'][$key] = $val;
124 | }
125 | }
126 |
127 | /**
128 | * Save
129 | */
130 | public function save() {
131 | $_SESSION[$this->settings['key']] = $this->messages['next'];
132 | }
133 |
134 | /**
135 | * Load messages
136 | *
137 | * Load messages from previous request if available
138 | */
139 | public function loadMessages() {
140 | if ( isset($_SESSION[$this->settings['key']]) ) {
141 | $this->messages['prev'] = $_SESSION[$this->settings['key']];
142 | }
143 | }
144 |
145 | /**
146 | * Get messages
147 | *
148 | * Return array of flash messages to be shown for the current request
149 | *
150 | * @return array
151 | */
152 | public function getMessages() {
153 | return array_merge($this->messages['prev'], $this->messages['now']);
154 | }
155 |
156 | /**
157 | * Array Access: Offset Exists
158 | */
159 | public function offsetExists( $offset ) {
160 | $messages = $this->getMessages();
161 | return isset($messages[$offset]);
162 | }
163 |
164 | /**
165 | * Array Access: Offset Get
166 | */
167 | public function offsetGet( $offset ) {
168 | $messages = $this->getMessages();
169 | return isset($messages[$offset]) ? $messages[$offset] : null;
170 | }
171 |
172 | /**
173 | * Array Access: Offset Set
174 | */
175 | public function offsetSet( $offset, $value ) {
176 | $this->now($offset, $value);
177 | }
178 |
179 | /**
180 | * Array Access: Offset Unset
181 | */
182 | public function offsetUnset( $offset ) {
183 | unset($this->messages['prev'][$offset], $this->messages['now'][$offset]);
184 | }
185 | }
--------------------------------------------------------------------------------
/api/Slim/Middleware/MethodOverride.php:
--------------------------------------------------------------------------------
1 |
6 | * @copyright 2011 Josh Lockhart
7 | * @link http://www.slimframework.com
8 | * @license http://www.slimframework.com/license
9 | * @version 1.6.0
10 | * @package Slim
11 | *
12 | * MIT LICENSE
13 | *
14 | * Permission is hereby granted, free of charge, to any person obtaining
15 | * a copy of this software and associated documentation files (the
16 | * "Software"), to deal in the Software without restriction, including
17 | * without limitation the rights to use, copy, modify, merge, publish,
18 | * distribute, sublicense, and/or sell copies of the Software, and to
19 | * permit persons to whom the Software is furnished to do so, subject to
20 | * the following conditions:
21 | *
22 | * The above copyright notice and this permission notice shall be
23 | * included in all copies or substantial portions of the Software.
24 | *
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 | */
33 |
34 | /**
35 | * HTTP Method Override
36 | *
37 | * This is middleware for a Slim application that allows traditional
38 | * desktop browsers to submit psuedo PUT and DELETE requests by relying
39 | * on a pre-determined request parameter. Without this middleware,
40 | * desktop browsers are only able to submit GET and POST requests.
41 | *
42 | * This middleware is included automatically!
43 | *
44 | * @package Slim
45 | * @author Josh Lockhart
46 | * @since 1.5.2
47 | */
48 | class Slim_Middleware_MethodOverride extends Slim_Middleware {
49 | /**
50 | * @var array
51 | */
52 | protected $settings;
53 |
54 | /**
55 | * Constructor
56 | * @param Slim $app
57 | * @param array $settings
58 | * @return void
59 | */
60 | public function __construct( $settings = array() ) {
61 | $this->settings = array_merge(array('key' => '_METHOD'), $settings);
62 | }
63 |
64 | /**
65 | * Call
66 | *
67 | * Implements Slim middleware interface. This method is invoked and passed
68 | * an array of environemnt variables. This middleware inspects the environment
69 | * variables for the HTTP method override parameter; if found, this middleware
70 | * modifies the environment settings so downstream middleware and/or the Slim
71 | * application will treat the request with the desired HTTP method.
72 | *
73 | * @param array $env
74 | * @return array[status, header, body]
75 | */
76 | public function call() {
77 | $env = $this->app->environment();
78 | if ( isset($env['X_HTTP_METHOD_OVERRIDE']) ) {
79 | // Header commonly used by Backbone.js and others
80 | $env['slim.method_override.original_method'] = $env['REQUEST_METHOD'];
81 | $env['REQUEST_METHOD'] = strtoupper($env['X_HTTP_METHOD_OVERRIDE']);
82 | } else if ( isset($env['REQUEST_METHOD']) && $env['REQUEST_METHOD'] === 'POST' ) {
83 | // HTML Form Override
84 | $req = new Slim_Http_Request($env);
85 | $method = $req->post($this->settings['key']);
86 | if ( $method ) {
87 | $env['slim.method_override.original_method'] = $env['REQUEST_METHOD'];
88 | $env['REQUEST_METHOD'] = strtoupper($method);
89 | }
90 | }
91 | $this->next->call();
92 | }
93 | }
--------------------------------------------------------------------------------
/api/Slim/Middleware/PrettyExceptions.php:
--------------------------------------------------------------------------------
1 |
6 | * @copyright 2011 Josh Lockhart
7 | * @link http://www.slimframework.com
8 | * @license http://www.slimframework.com/license
9 | * @version 1.6.0
10 | * @package Slim
11 | *
12 | * MIT LICENSE
13 | *
14 | * Permission is hereby granted, free of charge, to any person obtaining
15 | * a copy of this software and associated documentation files (the
16 | * "Software"), to deal in the Software without restriction, including
17 | * without limitation the rights to use, copy, modify, merge, publish,
18 | * distribute, sublicense, and/or sell copies of the Software, and to
19 | * permit persons to whom the Software is furnished to do so, subject to
20 | * the following conditions:
21 | *
22 | * The above copyright notice and this permission notice shall be
23 | * included in all copies or substantial portions of the Software.
24 | *
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 | */
33 |
34 | /**
35 | * Pretty Exceptions
36 | *
37 | * This middleware catches any Exception thrown by the surrounded
38 | * application and displays a developer-friendly diagnostic screen.
39 | *
40 | * @package Slim
41 | * @author Josh Lockhart
42 | * @since 1.0.0
43 | */
44 | class Slim_Middleware_PrettyExceptions extends Slim_Middleware {
45 | /**
46 | * @var array
47 | */
48 | protected $settings;
49 |
50 | /**
51 | * Constructor
52 | * @param Slim|middleware $app
53 | * @param array $settings
54 | */
55 | public function __construct( $settings = array() ) {
56 | $this->settings = $settings;
57 | }
58 |
59 | /**
60 | * Call
61 | * @return void
62 | */
63 | public function call() {
64 | try {
65 | $this->next->call();
66 | } catch ( Exception $e ) {
67 | $env = $this->app->environment();
68 | $env['slim.log']->error($e);
69 | $this->app->response()->status(500);
70 | $this->app->response()->body($this->renderBody($env, $e));
71 | }
72 | }
73 |
74 | /**
75 | * Render response body
76 | * @param array $env
77 | * @param Exception $exception
78 | * @return string
79 | */
80 | protected function renderBody( &$env, $exception ) {
81 | $title = 'Slim Application Error';
82 | $code = $exception->getCode();
83 | $message = $exception->getMessage();
84 | $file = $exception->getFile();
85 | $line = $exception->getLine();
86 | $trace = $exception->getTraceAsString();
87 | $html = sprintf('
%s ', $title);
88 | $html .= 'The application could not run because of the following error:
';
89 | $html .= 'Details ';
90 | if ( $code ) {
91 | $html .= sprintf('Code: %s
', $code);
92 | }
93 | if ( $message ) {
94 | $html .= sprintf('Message: %s
', $message);
95 | }
96 | if ( $file ) {
97 | $html .= sprintf('File: %s
', $file);
98 | }
99 | if ( $line ) {
100 | $html .= sprintf('Line: %s
', $line);
101 | }
102 | if ( $trace ) {
103 | $html .= 'Trace ';
104 | $html .= sprintf('%s ', $trace);
105 | }
106 | return sprintf("%s %s", $title, $html);
107 | }
108 | }
--------------------------------------------------------------------------------
/api/Slim/Middleware/SessionCookie.php:
--------------------------------------------------------------------------------
1 |
6 | * @copyright 2011 Josh Lockhart
7 | * @link http://www.slimframework.com
8 | * @license http://www.slimframework.com/license
9 | * @version 1.6.0
10 | * @package Slim
11 | *
12 | * MIT LICENSE
13 | *
14 | * Permission is hereby granted, free of charge, to any person obtaining
15 | * a copy of this software and associated documentation files (the
16 | * "Software"), to deal in the Software without restriction, including
17 | * without limitation the rights to use, copy, modify, merge, publish,
18 | * distribute, sublicense, and/or sell copies of the Software, and to
19 | * permit persons to whom the Software is furnished to do so, subject to
20 | * the following conditions:
21 | *
22 | * The above copyright notice and this permission notice shall be
23 | * included in all copies or substantial portions of the Software.
24 | *
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 | */
33 |
34 | /**
35 | * Session Cookie
36 | *
37 | * This class provides an HTTP cookie storage mechanism
38 | * for session data. This class avoids using a PHP session
39 | * and instead serializes/unserializes the $_SESSION global
40 | * variable to/from an HTTP cookie.
41 | *
42 | * If a secret key is provided with this middleware, the HTTP
43 | * cookie will be checked for integrity to ensure the client-side
44 | * cookie is not changed.
45 | *
46 | * You should NEVER store sensitive data in a client-side cookie
47 | * in any format, encrypted or not. If you need to store sensitive
48 | * user information in a session, you should rely on PHP's native
49 | * session implementation, or use other middleware to store
50 | * session data in a database or alternative server-side cache.
51 | *
52 | * Because this class stores serialized session data in an HTTP cookie,
53 | * you are inherently limtied to 4 Kb. If you attempt to store
54 | * more than this amount, serialization will fail.
55 | *
56 | * @package Slim
57 | * @author Josh Lockhart
58 | * @since 1.5.2
59 | */
60 | class Slim_Middleware_SessionCookie extends Slim_Middleware {
61 | /**
62 | * @var array
63 | */
64 | protected $settings;
65 |
66 | /**
67 | * Constructor
68 | *
69 | * @param array $settings
70 | * @return void
71 | */
72 | public function __construct( $settings = array() ) {
73 | $this->settings = array_merge(array(
74 | 'expires' => '20 minutes',
75 | 'path' => '/',
76 | 'domain' => null,
77 | 'secure' => false,
78 | 'httponly' => false,
79 | 'name' => 'slim_session',
80 | 'secret' => 'CHANGE_ME',
81 | 'cipher' => MCRYPT_RIJNDAEL_256,
82 | 'cipher_mode' => MCRYPT_MODE_CBC
83 | ), $settings);
84 | if ( is_string($this->settings['expires']) ) {
85 | $this->settings['expires'] = strtotime($this->settings['expires']);
86 | }
87 | }
88 |
89 | /**
90 | * Call
91 | * @return void
92 | */
93 | public function call() {
94 | $this->loadSession();
95 | $this->next->call();
96 | $this->saveSession();
97 | }
98 |
99 | /**
100 | * Load session
101 | * @param array $env
102 | * @return void
103 | */
104 | protected function loadSession() {
105 | session_start();
106 | $value = Slim_Http_Util::decodeSecureCookie(
107 | $this->app->request()->cookies($this->settings['name']),
108 | $this->settings['secret'],
109 | $this->settings['cipher'],
110 | $this->settings['cipher_mode']
111 | );
112 | if ( $value ) {
113 | $_SESSION = unserialize($value);
114 | } else {
115 | $_SESSION = array();
116 | }
117 | }
118 |
119 | /**
120 | * Save session
121 | * @return void
122 | */
123 | protected function saveSession() {
124 | $value = Slim_Http_Util::encodeSecureCookie(
125 | serialize($_SESSION),
126 | $this->settings['expires'],
127 | $this->settings['secret'],
128 | $this->settings['cipher'],
129 | $this->settings['cipher_mode']
130 | );
131 | if ( strlen($value) > 4096 ) {
132 | $this->app->getLog()->error('WARNING! Slim_Middleware_SessionCookie data size is larger than 4KB. Content save failed.');
133 | } else {
134 | $this->app->response()->setCookie($this->settings['name'], array(
135 | 'value' => $value,
136 | 'domain' => $this->settings['domain'],
137 | 'path' => $this->settings['path'],
138 | 'expires' => $this->settings['expires'],
139 | 'secure' => $this->settings['secure'],
140 | 'httponly' => $this->settings['httponly']
141 | ));
142 | }
143 | session_destroy();
144 | }
145 | }
--------------------------------------------------------------------------------
/api/Slim/Router.php:
--------------------------------------------------------------------------------
1 |
6 | * @copyright 2011 Josh Lockhart
7 | * @link http://www.slimframework.com
8 | * @license http://www.slimframework.com/license
9 | * @version 1.6.0
10 | * @package Slim
11 | *
12 | * MIT LICENSE
13 | *
14 | * Permission is hereby granted, free of charge, to any person obtaining
15 | * a copy of this software and associated documentation files (the
16 | * "Software"), to deal in the Software without restriction, including
17 | * without limitation the rights to use, copy, modify, merge, publish,
18 | * distribute, sublicense, and/or sell copies of the Software, and to
19 | * permit persons to whom the Software is furnished to do so, subject to
20 | * the following conditions:
21 | *
22 | * The above copyright notice and this permission notice shall be
23 | * included in all copies or substantial portions of the Software.
24 | *
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 | */
33 |
34 | /**
35 | * Router
36 | *
37 | * This class organizes Route objects and, upon request, will
38 | * return an iterator for routes that match the HTTP request URI.
39 | *
40 | * @package Slim
41 | * @author Josh Lockhart
42 | * @since 1.0.0
43 | */
44 | class Slim_Router implements IteratorAggregate {
45 | /**
46 | * @var Slim_Http_Request
47 | */
48 | protected $request;
49 |
50 | /**
51 | * @var Slim_Http_Response
52 | */
53 | protected $response;
54 |
55 | /**
56 | * @var array Lookup hash of all routes
57 | */
58 | protected $routes;
59 |
60 | /**
61 | * @var array Lookup hash of named routes, keyed by route name
62 | */
63 | protected $namedRoutes;
64 |
65 | /**
66 | * @var array Array of routes that match the Request URI (lazy-loaded)
67 | */
68 | protected $matchedRoutes;
69 |
70 | /**
71 | * @var mixed Callable to be invoked if no matching routes are found
72 | */
73 | protected $notFound;
74 |
75 | /**
76 | * @var mixed Callable to be invoked if application error
77 | */
78 | protected $error;
79 |
80 | /**
81 | * Constructor
82 | * @param Slim_Http_Request $request The HTTP request object
83 | * @param Slim_Http_Response $response The HTTP response object
84 | */
85 | public function __construct( Slim_Http_Request $request, Slim_Http_Response $response ) {
86 | $this->request = $request;
87 | $this->response = $response;
88 | $this->routes = array();
89 | $this->namedRoutes = array();
90 | }
91 |
92 | /**
93 | * Get Iterator
94 | * @return ArrayIterator
95 | */
96 | public function getIterator() {
97 | return new ArrayIterator($this->getMatchedRoutes());
98 | }
99 |
100 | /**
101 | * Get Request
102 | * @return Slim_Http_Request
103 | */
104 | public function getRequest() {
105 | return $this->request;
106 | }
107 |
108 | /**
109 | * Get Response
110 | * @return Slim_Http_Response
111 | */
112 | public function getResponse() {
113 | return $this->response;
114 | }
115 |
116 | /**
117 | * Return routes that match the current request
118 | * @return array[Slim_Route]
119 | */
120 | public function getMatchedRoutes( $reload = false ) {
121 | if ( $reload || is_null($this->matchedRoutes) ) {
122 | $this->matchedRoutes = array();
123 | foreach ( $this->routes as $route ) {
124 | if ( $route->matches($this->request->getResourceUri()) ) {
125 | $this->matchedRoutes[] = $route;
126 | }
127 | }
128 | }
129 | return $this->matchedRoutes;
130 | }
131 |
132 | /**
133 | * Map a route to a callback function
134 | * @param string $pattern The URL pattern (ie. "/books/:id")
135 | * @param mixed $callable Anything that returns TRUE for is_callable()
136 | * @return Slim_Route
137 | */
138 | public function map( $pattern, $callable ) {
139 | $route = new Slim_Route($pattern, $callable);
140 | $route->setRouter($this);
141 | $this->routes[] = $route;
142 | return $route;
143 | }
144 |
145 | /**
146 | * Get URL for named route
147 | * @param string $name The name of the route
148 | * @param array Associative array of URL parameter names and values
149 | * @throws RuntimeException If named route not found
150 | * @return string The URL for the given route populated with the given parameters
151 | */
152 | public function urlFor( $name, $params = array() ) {
153 | if ( !$this->hasNamedRoute($name) ) {
154 | throw new RuntimeException('Named route not found for name: ' . $name);
155 | }
156 | $pattern = $this->getNamedRoute($name)->getPattern();
157 | $search = $replace = array();
158 | foreach ( $params as $key => $value ) {
159 | $search[] = ':' . $key;
160 | $replace[] = $value;
161 | }
162 | $pattern = str_replace($search, $replace, $pattern);
163 | //Remove remnants of unpopulated, trailing optional pattern segments
164 | return preg_replace(array(
165 | '@\(\/?:.+\/??\)\??@',
166 | '@\?|\(|\)@'
167 | ), '', $this->request->getRootUri() . $pattern);
168 | }
169 |
170 | /**
171 | * Add named route
172 | * @param string $name The route name
173 | * @param Slim_Route $route The route object
174 | * @throws RuntimeException If a named route already exists with the same name
175 | * @return void
176 | */
177 | public function addNamedRoute( $name, Slim_Route $route ) {
178 | if ( $this->hasNamedRoute($name) ) {
179 | throw new RuntimeException('Named route already exists with name: ' . $name);
180 | }
181 | $this->namedRoutes[(string)$name] = $route;
182 | }
183 |
184 | /**
185 | * Has named route
186 | * @param string $name The route name
187 | * @return bool
188 | */
189 | public function hasNamedRoute( $name ) {
190 | return isset($this->namedRoutes[(string)$name]);
191 | }
192 |
193 | /**
194 | * Get named route
195 | * @param string $name
196 | * @return Slim_Route|null
197 | */
198 | public function getNamedRoute( $name ) {
199 | if ( $this->hasNamedRoute($name) ) {
200 | return $this->namedRoutes[(string)$name];
201 | } else {
202 | return null;
203 | }
204 | }
205 |
206 | /**
207 | * Get named routes
208 | * @return ArrayIterator
209 | */
210 | public function getNamedRoutes() {
211 | return new ArrayIterator($this->namedRoutes);
212 | }
213 |
214 | /**
215 | * Register a 404 Not Found callback
216 | * @param mixed $callable Anything that returns TRUE for is_callable()
217 | * @return mixed
218 | */
219 | public function notFound( $callable = null ) {
220 | if ( is_callable($callable) ) {
221 | $this->notFound = $callable;
222 | }
223 | return $this->notFound;
224 | }
225 |
226 | /**
227 | * Register a 500 Error callback
228 | * @param mixed $callable Anything that returns TRUE for is_callable()
229 | * @return mixed
230 | */
231 | public function error( $callable = null ) {
232 | if ( is_callable($callable) ) {
233 | $this->error = $callable;
234 | }
235 | return $this->error;
236 | }
237 | }
--------------------------------------------------------------------------------
/api/Slim/View.php:
--------------------------------------------------------------------------------
1 |
6 | * @copyright 2011 Josh Lockhart
7 | * @link http://www.slimframework.com
8 | * @license http://www.slimframework.com/license
9 | * @version 1.6.0
10 | * @package Slim
11 | *
12 | * MIT LICENSE
13 | *
14 | * Permission is hereby granted, free of charge, to any person obtaining
15 | * a copy of this software and associated documentation files (the
16 | * "Software"), to deal in the Software without restriction, including
17 | * without limitation the rights to use, copy, modify, merge, publish,
18 | * distribute, sublicense, and/or sell copies of the Software, and to
19 | * permit persons to whom the Software is furnished to do so, subject to
20 | * the following conditions:
21 | *
22 | * The above copyright notice and this permission notice shall be
23 | * included in all copies or substantial portions of the Software.
24 | *
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 | */
33 |
34 | /**
35 | * Slim View
36 | *
37 | * The View is responsible for rendering and/or displaying a template.
38 | * It is recommended that you subclass View and re-implement the
39 | * `View::render` method to use a custom templating engine such as
40 | * Smarty, Twig, Mustache, etc. It is important that `View::render`
41 | * `return` the final template output. Do not `echo` the output.
42 | *
43 | * @package Slim
44 | * @author Josh Lockhart
45 | * @since 1.0.0
46 | */
47 | class Slim_View {
48 | /**
49 | * @var array Key-value array of data available to the template
50 | */
51 | protected $data = array();
52 |
53 | /**
54 | * @var string Absolute or relative path to the templates directory
55 | */
56 | protected $templatesDirectory;
57 |
58 | /**
59 | * Constructor
60 | *
61 | * This is empty but may be overridden in a subclass
62 | */
63 | public function __construct() {}
64 |
65 | /**
66 | * Get data
67 | * @param string $key
68 | * @return array|mixed|null All View data if no $key, value of datum
69 | * if $key, or NULL if $key but datum
70 | * does not exist.
71 | */
72 | public function getData( $key = null ) {
73 | if ( !is_null($key) ) {
74 | return isset($this->data[$key]) ? $this->data[$key] : null;
75 | } else {
76 | return $this->data;
77 | }
78 | }
79 |
80 | /**
81 | * Set data
82 | *
83 | * This method is overloaded to accept two different method signatures.
84 | * You may use this to set a specific key with a specfic value,
85 | * or you may use this to set all data to a specific array.
86 | *
87 | * USAGE:
88 | *
89 | * View::setData('color', 'red');
90 | * View::setData(array('color' => 'red', 'number' => 1));
91 | *
92 | * @param string|array
93 | * @param mixed Optional. Only use if first argument is a string.
94 | * @return void
95 | * @throws InvalidArgumentException If incorrect method signature
96 | */
97 | public function setData() {
98 | $args = func_get_args();
99 | if ( count($args) === 1 && is_array($args[0]) ) {
100 | $this->data = $args[0];
101 | } else if ( count($args) === 2 ) {
102 | $this->data[(string)$args[0]] = $args[1];
103 | } else {
104 | throw new InvalidArgumentException('Cannot set View data with provided arguments. Usage: `View::setData( $key, $value );` or `View::setData([ key => value, ... ]);`');
105 | }
106 | }
107 |
108 | /**
109 | * Append data to existing View data
110 | * @param array $data
111 | * @return void
112 | */
113 | public function appendData( array $data ) {
114 | $this->data = array_merge($this->data, $data);
115 | }
116 |
117 | /**
118 | * Get templates directory
119 | * @return string|null Path to templates directory without trailing slash
120 | */
121 | public function getTemplatesDirectory() {
122 | return $this->templatesDirectory;
123 | }
124 |
125 | /**
126 | * Set templates directory
127 | * @param string $dir
128 | * @return void
129 | * @throws RuntimeException If directory is not a directory or does not exist
130 | */
131 | public function setTemplatesDirectory( $dir ) {
132 | $this->templatesDirectory = rtrim($dir, '/');
133 | }
134 |
135 | /**
136 | * Display template
137 | *
138 | * This method echoes the rendered template to the current output buffer
139 | *
140 | * @param string $template Path to template file relative to templates directoy
141 | * @return void
142 | */
143 | public function display( $template ) {
144 | echo $this->render($template);
145 | }
146 |
147 | /**
148 | * Render template
149 | * @param string $template Path to template file relative to templates directory
150 | * @return string Rendered template
151 | * @throws RuntimeException If template does not exist
152 | */
153 | public function render( $template ) {
154 | extract($this->data);
155 | $templatePath = $this->getTemplatesDirectory() . '/' . ltrim($template, '/');
156 | if ( !file_exists($templatePath) ) {
157 | throw new RuntimeException('View cannot render template `' . $templatePath . '`. Template does not exist.');
158 | }
159 | ob_start();
160 | require $templatePath;
161 | return ob_get_clean();
162 | }
163 |
164 | }
--------------------------------------------------------------------------------
/api/index.php:
--------------------------------------------------------------------------------
1 | get('/employees', 'getEmployees');
8 | $app->get('/employees/:id', 'getEmployee');
9 | $app->get('/employees/:id/reports', 'getReports');
10 | $app->get('/employees/search/:query', 'getEmployeesByName');
11 | $app->get('/employees/modifiedsince/:timestamp', 'findByModifiedDate');
12 |
13 | $app->run();
14 |
15 | function getEmployees() {
16 |
17 | if (isset($_GET['name'])) {
18 | return getEmployeesByName($_GET['name']);
19 | } else if (isset($_GET['modifiedSince'])) {
20 | return getModifiedEmployees($_GET['modifiedSince']);
21 | }
22 |
23 | $sql = "select e.id, e.firstName, e.lastName, e.title, count(r.id) reportCount " .
24 | "from employee e left join employee r on r.managerId = e.id " .
25 | "group by e.id order by e.lastName, e.firstName";
26 | try {
27 | $db = getConnection();
28 | $stmt = $db->query($sql);
29 | $employees = $stmt->fetchAll(PDO::FETCH_OBJ);
30 | $db = null;
31 |
32 | // Include support for JSONP requests
33 | if (!isset($_GET['callback'])) {
34 | echo json_encode($employees);
35 | } else {
36 | echo $_GET['callback'] . '(' . json_encode($employees) . ');';
37 | }
38 |
39 | } catch(PDOException $e) {
40 | echo '{"error":{"text":'. $e->getMessage() .'}}';
41 | }
42 | }
43 |
44 | function getEmployee($id) {
45 | $sql = "select e.id, e.firstName, e.lastName, e.title, e.officePhone, e.cellPhone, e.email, e.managerId, e.twitterId, m.firstName managerFirstName, m.lastName managerLastName, count(r.id) reportCount " .
46 | "from employee e " .
47 | "left join employee r on r.managerId = e.id " .
48 | "left join employee m on e.managerId = m.id " .
49 | "where e.id=:id";
50 | try {
51 | $db = getConnection();
52 | $stmt = $db->prepare($sql);
53 | $stmt->bindParam("id", $id);
54 | $stmt->execute();
55 | $employee = $stmt->fetchObject();
56 | $db = null;
57 |
58 | // Include support for JSONP requests
59 | if (!isset($_GET['callback'])) {
60 | echo json_encode($employee);
61 | } else {
62 | echo $_GET['callback'] . '(' . json_encode($employee) . ');';
63 | }
64 |
65 | } catch(PDOException $e) {
66 | echo '{"error":{"text":'. $e->getMessage() .'}}';
67 | }
68 | }
69 |
70 | function getReports($id) {
71 |
72 | $sql = "select e.id, e.firstName, e.lastName, e.title, count(r.id) reportCount " .
73 | "from employee e left join employee r on r.managerId = e.id " .
74 | "where e.managerId=:id " .
75 | "group by e.id order by e.lastName, e.firstName";
76 |
77 | try {
78 | $db = getConnection();
79 | $stmt = $db->prepare($sql);
80 | $stmt->bindParam("id", $id);
81 | $stmt->execute();
82 | $employees = $stmt->fetchAll(PDO::FETCH_OBJ);
83 | $db = null;
84 |
85 | // Include support for JSONP requests
86 | if (!isset($_GET['callback'])) {
87 | echo json_encode($employees);
88 | } else {
89 | echo $_GET['callback'] . '(' . json_encode($employees) . ');';
90 | }
91 |
92 | } catch(PDOException $e) {
93 | echo '{"error":{"text":'. $e->getMessage() .'}}';
94 | }
95 | }
96 |
97 | function getEmployeesByName($name) {
98 | $sql = "select e.id, e.firstName, e.lastName, e.title, count(r.id) reportCount " .
99 | "from employee e left join employee r on r.managerId = e.id " .
100 | "WHERE UPPER(CONCAT(e.firstName, ' ', e.lastName)) LIKE :name " .
101 | "group by e.id order by e.lastName, e.firstName";
102 | try {
103 | $db = getConnection();
104 | $stmt = $db->prepare($sql);
105 | $name = "%".$name."%";
106 | $stmt->bindParam("name", $name);
107 | $stmt->execute();
108 | $employees = $stmt->fetchAll(PDO::FETCH_OBJ);
109 | $db = null;
110 |
111 | // Include support for JSONP requests
112 | if (!isset($_GET['callback'])) {
113 | echo json_encode($employees);
114 | } else {
115 | echo $_GET['callback'] . '(' . json_encode($employees) . ');';
116 | }
117 |
118 | } catch(PDOException $e) {
119 | echo '{"error":{"text":'. $e->getMessage() .'}}';
120 | }
121 | }
122 |
123 | function getModifiedEmployees($modifiedSince) {
124 | if ($modifiedSince == 'null') {
125 | $modifiedSince = "1000-01-01";
126 | }
127 | $sql = "select * from employee WHERE lastModified > :modifiedSince";
128 | try {
129 | $db = getConnection();
130 | $stmt = $db->prepare($sql);
131 | $stmt->bindParam("modifiedSince", $modifiedSince);
132 | $stmt->execute();
133 | $employees = $stmt->fetchAll(PDO::FETCH_OBJ);
134 | $db = null;
135 |
136 | // Include support for JSONP requests
137 | if (!isset($_GET['callback'])) {
138 | echo json_encode($employees);
139 | } else {
140 | echo $_GET['callback'] . '(' . json_encode($employees) . ');';
141 | }
142 |
143 | } catch(PDOException $e) {
144 | echo '{"error":{"text":'. $e->getMessage() .'}}';
145 | }
146 | }
147 |
148 | function getConnection() {
149 | $dbhost="127.0.0.1";
150 | $dbuser="root";
151 | $dbpass="";
152 | $dbname="directory";
153 | $dbh = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
154 | $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
155 | return $dbh;
156 | }
157 |
158 | ?>
--------------------------------------------------------------------------------
/directory.sql:
--------------------------------------------------------------------------------
1 | -- MySQL dump 10.13 Distrib 5.5.15, for osx10.6 (i386)
2 | --
3 | -- Host: localhost Database: directory
4 | -- ------------------------------------------------------
5 | -- Server version 5.5.15
6 |
7 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
8 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
9 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
10 | /*!40101 SET NAMES utf8 */;
11 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
12 | /*!40103 SET TIME_ZONE='+00:00' */;
13 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
14 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
15 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
16 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
17 |
18 | --
19 | -- Table structure for table `employee`
20 | --
21 |
22 | DROP TABLE IF EXISTS `employee`;
23 | /*!40101 SET @saved_cs_client = @@character_set_client */;
24 | /*!40101 SET character_set_client = utf8 */;
25 | CREATE TABLE `employee` (
26 | `id` int(11) NOT NULL AUTO_INCREMENT,
27 | `firstName` varchar(30) NOT NULL,
28 | `lastName` varchar(30) NOT NULL,
29 | `managerId` int(11) NOT NULL,
30 | `title` varchar(45) NOT NULL,
31 | `department` varchar(45) NOT NULL,
32 | `officePhone` varchar(45) NOT NULL,
33 | `cellPhone` varchar(45) NOT NULL,
34 | `email` varchar(45) NOT NULL,
35 | `city` varchar(45) NOT NULL,
36 | `picture` varchar(250) NOT NULL,
37 | `twitterId` varchar(45) DEFAULT NULL,
38 | `blogURL` varchar(200) DEFAULT NULL,
39 | PRIMARY KEY (`id`)
40 | ) ENGINE=MyISAM AUTO_INCREMENT=22 DEFAULT CHARSET=latin1;
41 | /*!40101 SET character_set_client = @saved_cs_client */;
42 |
43 | --
44 | -- Dumping data for table `employee`
45 | --
46 |
47 | LOCK TABLES `employee` WRITE;
48 | /*!40000 ALTER TABLE `employee` DISABLE KEYS */;
49 | INSERT INTO `employee` VALUES (12,'Steven','Wells',4,'Software Architect','Engineering','617-000-0012','781-000-0012','swells@fakemail.com','Boston, MA','steven_wells.jpg','@fakeswells','http://coenraets.org'),(11,'Amy','Jones',5,'Sales Representative','Sales','617-000-0011','781-000-0011','ajones@fakemail.com','Boston, MA','amy_jones.jpg','@fakeajones','http://coenraets.org'),(10,'Kathleen','Byrne',5,'Sales Representative','Sales','617-000-0010','781-000-0010','kbyrne@fakemail.com','Boston, MA','kathleen_byrne.jpg','@fakekbyrne','http://coenraets.org'),(9,'Gary','Donovan',2,'Marketing','Marketing','617-000-0009','781-000-0009','gdonovan@fakemail.com','Boston, MA','gary_donovan.jpg','@fakegdonovan','http://coenraets.org'),(8,'Lisa','Wong',2,'Marketing Manager','Marketing','617-000-0008','781-000-0008','lwong@fakemail.com','Boston, MA','lisa_wong.jpg','@fakelwong','http://coenraets.org'),(7,'Paula','Gates',4,'Software Architect','Engineering','617-000-0007','781-000-0007','pgates@fakemail.com','Boston, MA','paula_gates.jpg','@fakepgates','http://coenraets.org'),(5,'Ray','Moore',1,'VP of Sales','Sales','617-000-0005','781-000-0005','rmoore@fakemail.com','Boston, MA','ray_moore.jpg','@fakermoore','http://coenraets.org'),(6,'Paul','Jones',4,'QA Manager','Engineering','617-000-0006','781-000-0006','pjones@fakemail.com','Boston, MA','paul_jones.jpg','@fakepjones','http://coenraets.org'),(3,'Eugene','Lee',1,'CFO','Accounting','617-000-0003','781-000-0003','elee@fakemail.com','Boston, MA','eugene_lee.jpg','@fakeelee','http://coenraets.org'),(4,'John','Williams',1,'VP of Engineering','Engineering','617-000-0004','781-000-0004','jwilliams@fakemail.com','Boston, MA','john_williams.jpg','@fakejwilliams','http://coenraets.org'),(2,'Julie','Taylor',1,'VP of Marketing','Marketing','617-000-0002','781-000-0002','jtaylor@fakemail.com','Boston, MA','julie_taylor.jpg','@fakejtaylor','http://coenraets.org'),(1,'James','King',0,'President and CEO','Corporate','617-000-0001','781-000-0001','jking@fakemail.com','Boston, MA','james_king.jpg','@fakejking','http://coenraets.org');
50 | /*!40000 ALTER TABLE `employee` ENABLE KEYS */;
51 | UNLOCK TABLES;
52 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
53 |
54 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
55 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
56 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
57 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
58 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
59 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
60 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
61 |
62 | -- Dump completed on 2012-02-13 13:33:11
63 |
--------------------------------------------------------------------------------
/iphone/css/images/activity-indicator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/css/images/activity-indicator.png
--------------------------------------------------------------------------------
/iphone/css/images/back-button-active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/css/images/back-button-active.png
--------------------------------------------------------------------------------
/iphone/css/images/back-button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/css/images/back-button.png
--------------------------------------------------------------------------------
/iphone/css/images/button-active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/css/images/button-active.png
--------------------------------------------------------------------------------
/iphone/css/images/button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/css/images/button.png
--------------------------------------------------------------------------------
/iphone/css/images/call.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/css/images/call.png
--------------------------------------------------------------------------------
/iphone/css/images/comment-arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/css/images/comment-arrow.png
--------------------------------------------------------------------------------
/iphone/css/images/detail-disclosure-button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/css/images/detail-disclosure-button.png
--------------------------------------------------------------------------------
/iphone/css/images/disclosure-indicator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/css/images/disclosure-indicator.png
--------------------------------------------------------------------------------
/iphone/css/images/mail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/css/images/mail.png
--------------------------------------------------------------------------------
/iphone/css/images/manager.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/css/images/manager.png
--------------------------------------------------------------------------------
/iphone/css/images/message.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/css/images/message.png
--------------------------------------------------------------------------------
/iphone/css/images/navbar-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/css/images/navbar-bg.png
--------------------------------------------------------------------------------
/iphone/css/images/navbar-landscape-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/css/images/navbar-landscape-bg.png
--------------------------------------------------------------------------------
/iphone/css/images/refresh-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/css/images/refresh-icon.png
--------------------------------------------------------------------------------
/iphone/css/images/reports.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/css/images/reports.png
--------------------------------------------------------------------------------
/iphone/css/images/search-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/css/images/search-icon.png
--------------------------------------------------------------------------------
/iphone/css/styles.css:
--------------------------------------------------------------------------------
1 | /* Many of the styles below come from the app documented in this article http://cheeaun.com/blog/2012/03/how-i-built-hacker-news-mobile-web-app */
2 |
3 | html{
4 | height: 100%;
5 | }
6 | body{
7 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
8 | font-size: 16px;
9 | margin: 0;
10 | padding: 0;
11 | height: 100%;
12 | background-color: #fff;
13 | overflow: hidden;
14 | position: relative;
15 | }
16 |
17 | .header{
18 | background: #b2bbca url(images/navbar-bg.png) repeat-x;
19 | -webkit-background-size: 1px 44px;
20 | -moz-background-size: 1px 44px;
21 | -ms-background-size: 1px 44px;
22 | -o-background-size: 1px 44px;
23 | background-size: 1px 44px;
24 | height: 44px;
25 | line-height: 44px;
26 | width: 100%;
27 | color: #fff;
28 | -webkit-user-select: none;
29 | -webkit-touch-callout: none;
30 | }
31 |
32 | .header-button{
33 | position: absolute;
34 | top: 0;
35 | padding: 7px 5px;
36 | -webkit-tap-highlight-color: rgba(0,0,0,0);
37 | line-height: 1em;
38 | }
39 |
40 | .header-button button{
41 | pointer-events: none;
42 | -webkit-box-sizing: border-box;
43 | -moz-box-sizing: border-box;
44 | box-sizing: border-box;
45 | min-width: 50px;
46 | height: 30px;
47 | line-height: 25px;
48 | font-weight: bold;
49 | font-size: 12px;
50 | text-align: center;
51 | color: #fff;
52 | text-shadow: 0 -1px rgba(0,0,0,.6);
53 | padding: 0 4px;
54 | margin: 0;
55 | text-decoration: none;
56 | border-width: 2px 5px;
57 | -webkit-border-image: url(images/button.png) 4 10 4 10;
58 | -moz-border-image: url(images/button.png) 4 10 4 10;
59 | -ms-border-image: url(images/button.png) 4 10 4 10;
60 | -o-border-image: url(images/button.png) 4 10 4 10;
61 | background: transparent url(images/button-active.png) no-repeat;
62 | -webkit-background-size: 0 0;
63 | -moz-background-size: 0 0;
64 | -ms-background-size: 0 0;
65 | -o-background-size: 0 0;
66 | background-size: 0 0;
67 | }
68 |
69 | .header-button-icon button{
70 | min-width: 0;
71 | }
72 |
73 | .header-button-icon button img{
74 | vertical-align: text-bottom;
75 | }
76 |
77 | .header-button.tappable-active button{
78 | -webkit-border-image: url(images/button-active.png) 4 10 4 10;
79 | -moz-border-image: url(images/button-active.png) 4 10 4 10;
80 | -ms-border-image: url(images/button-active.png) 4 10 4 10;
81 | -o-border-image: url(images/button-active.png) 4 10 4 10;
82 | }
83 |
84 | .header-back-button button{
85 | padding: 0 4px 0 0;
86 | border-width: 2px 4px 2px 13px;
87 | -webkit-border-image: url(images/back-button.png) 4 8 4 26;
88 | -moz-border-image: url(images/back-button.png) 4 8 4 26;
89 | -ms-border-image: url(images/back-button.png) 4 8 4 26;
90 | -o-border-image: url(images/back-button.png) 4 8 4 26;
91 | background-image: url(images/back-button-active.png);
92 | }
93 | .header-back-button.tappable-active button{
94 | -webkit-border-image: url(images/back-button-active.png) 4 8 4 26;
95 | -moz-border-image: url(images/back-button-active.png) 4 8 4 26;
96 | -ms-border-image: url(images/back-button-active.png) 4 8 4 26;
97 | -o-border-image: url(images/back-button-active.png) 4 8 4 26;
98 | }
99 |
100 | .header-button-left{
101 | left: 0;
102 | }
103 |
104 | .header-button-right{
105 | right: 0;
106 | }
107 |
108 | .header h1{
109 | padding: 0;
110 | text-align: center;
111 | font-size: 20px;
112 | text-shadow: 0 -1px rgba(0,0,0,.4);
113 | margin: 0;
114 | white-space: nowrap;
115 | text-overflow: ellipsis;
116 | overflow: hidden;
117 | -webkit-box-flex: 1;
118 | -moz-box-flex: 1;
119 | box-flex: 1;
120 | }
121 |
122 | .scroll{
123 | -webkit-box-flex: 1;
124 | -moz-box-flex: 1;
125 | box-flex: 1;
126 | overflow: auto;
127 | -webkit-overflow-scrolling: touch;
128 | background-color: #e2e7ed;
129 | display: -webkit-box;
130 | display: -moz-box;
131 | display: box;
132 | -webkit-box-orient: vertical;
133 | -moz-box-orient: vertical;
134 | box-orient: vertical;
135 | position: absolute;
136 | top: 80px;
137 | bottom: 0px;
138 | left: 0px;
139 | right: 0px;
140 | }
141 |
142 | .scroll.striped{
143 | background-color: #cbd2d8;
144 | background-image: -webkit-gradient(linear, left top, right top, from(#c5ccd4), color-stop(0.714, #c5ccd4), color-stop(0.714, #cbd2d8), to(#cbd2d8));
145 | background-image: -webkit-linear-gradient(left, #c5ccd4, #c5ccd4 71.4%, #cbd2d8 71.5%, #cbd2d8);
146 | background-image: -moz-linear-gradient(left, #c5ccd4, #c5ccd4 71.4%, #cbd2d8 71.5%, #cbd2d8);
147 | background-image: -ms-linear-gradient(left, #c5ccd4, #c5ccd4 71.4%, #cbd2d8 71.5%, #cbd2d8);
148 | background-image: -o-linear-gradient(left, #c5ccd4, #c5ccd4 71.4%, #cbd2d8 71.5%, #cbd2d8);
149 | background-image: linear-gradient(left, #c5ccd4, #c5ccd4 71.4%, #cbd2d8 71.5%, #cbd2d8);
150 | -webkit-background-size: 7px 1px;
151 | -moz-background-size: 7px 1px;
152 | -ms-background-size: 7px 1px;
153 | -o-background-size: 7px 1px;
154 | background-size: 7px 1px;
155 | }
156 |
157 | .tableview{
158 | margin: 0;
159 | padding: 0;
160 | list-style: none;
161 | background-color: #fff;
162 | border-bottom: 1px solid #e0e0e0;
163 | }
164 | .tableview li{
165 | display: block;
166 | border-top: 1px solid #e0e0e0;
167 | padding: 10px;
168 | }
169 |
170 | .tableview-links li{
171 | padding: 0;
172 | display: -webkit-box;
173 | display: -moz-box;
174 | display: box;
175 | width: 100%;
176 | }
177 |
178 | .tableview-links li>a{
179 | font-size: 15px;
180 | line-height: 1.3em;
181 | color: #000;
182 | display: block;
183 | padding: 5px;
184 | text-decoration: none;
185 | -webkit-tap-highlight-color: rgba(0,0,0,0);
186 | display: -webkit-box;
187 | display: -moz-box;
188 | display: box;
189 | width: 100%;
190 | -webkit-box-flex: 1;
191 | -moz-box-flex: 1;
192 | box-flex: 1;
193 | -webkit-box-sizing: border-box;
194 | -moz-box-sizing: border-box;
195 | box-sizing: border-box;
196 | background-image: -webkit-gradient(linear, left top, left bottom, from(#4286f5), to(#194fdb));
197 | background-image: -webkit-linear-gradient(top, #4286f5, #194fdb);
198 | background-image: -moz-linear-gradient(top, #4286f5, #194fdb);
199 | background-image: -ms-linear-gradient(top, #4286f5, #194fdb);
200 | background-image: -o-linear-gradient(top, #4286f5, #194fdb);
201 | background-image: linear-gradient(top, #4286f5, #194fdb);
202 | background-position: -10px 0;
203 | background-repeat: no-repeat;
204 | -webkit-background-size: 10px 100%;
205 | -moz-background-size: 10px 100%;
206 | -ms-background-size: 10px 100%;
207 | -o-background-size: 10px 100%;
208 | background-size: 10px 100%;
209 | }
210 |
211 | .tableview-links li>a *{
212 | pointer-events: none;
213 | }
214 |
215 | .tableview-links li>a .metadata{
216 | display: block;
217 | font-size: 13px;
218 | color: #666d74;
219 | line-height: 1.2em;
220 | }
221 | .tableview-links li>a.pad-right{
222 | padding-right: 44px;
223 | }
224 | .tableview-links li>a.more-link{
225 | cursor: pointer;
226 | -webkit-touch-callout: none;
227 | line-height: 3em;
228 | padding: 10px;
229 | display: block;
230 | color: #2960d9;
231 | text-align: center;
232 | font-weight: bold;
233 | }
234 |
235 | .tableview-links li>a.tappable-active{
236 | color: #fff;
237 | background-color: #4286f5;
238 | background-repeat: repeat-x;
239 | }
240 | .tableview-links li>a.tappable-active *{
241 | color: #fff;
242 | }
243 | .tableview-links li>a.detail-disclosure{
244 | -webkit-touch-callout: none;
245 | padding: 0;
246 | width: 44px;
247 | margin: 0 0 0 -44px;
248 | -webkit-box-align: center;
249 | -moz-box-align: center;
250 | box-align: center;
251 | -webkit-box-pack: center;
252 | -moz-box-pack: center;
253 | box-pack: center;
254 | -webkit-box-flex: 0;
255 | -moz-box-flex: 0;
256 | box-flex: 0;
257 | }
258 | .tableview-links li>a.detail-disclosure.tappable-active{
259 | background: transparent none;
260 | }
261 | .tableview-links li>a.detail-disclosure span{
262 | display: inline-block;
263 | width: 29px;
264 | height: 31px;
265 | background: transparent url(images/detail-disclosure-button.png);
266 | -webkit-background-size: 58px 31px;
267 | -moz-background-size: 58px 31px;
268 | -ms-background-size: 58px 31px;
269 | -o-background-size: 58px 31px;
270 | background-size: 58px 31px;
271 | }
272 | .tableview-links li>a.detail-disclosure.tappable-active span{
273 | background-position: top right;
274 | }
275 |
276 | .link-text{
277 | color: #385487;
278 | font-weight: bold;
279 | }
280 | .inline-block{
281 | display: inline-block;
282 | }
283 |
284 |
285 | #content {
286 | position: absolute;
287 | background: #ddd;
288 | width: 100%;
289 | height: 100%;
290 | overflow-x: hidden;
291 | overflow-y: auto;
292 | }
293 |
294 | .page {
295 | position: absolute;
296 | width: 100%;
297 | height: 100%;
298 | background-color: #ddd;
299 | -webkit-transform:translate3d(0,0,0);
300 | }
301 |
302 | .stage-center {
303 | top: 0;
304 | left: 0;
305 | }
306 |
307 | .stage-left {
308 | left: -100%;
309 | }
310 |
311 | .stage-right {
312 | left: 100%;
313 | }
314 |
315 | .transition {
316 | -moz-transition-duration: .375s;
317 | -webkit-transition-duration: .375s;
318 | -o-transition-duration: .375s;
319 | }
320 |
321 | .employee-summary header{
322 | padding: 10px 8px;
323 | text-shadow: 0 1px rgba(255,255,255,.85);
324 | }
325 | .employee-summary header h1,
326 | .employee-summary header p{
327 | margin: 0;
328 | padding: 0;
329 | }
330 | .employee-summary header h1 a{
331 | display: block;
332 | }
333 | .employee-summary header h1 a .link-text{
334 | font-size: 13px;
335 | }
336 | .employee-summary header .metadata{
337 | font-size: 13px;
338 | color: #666d74;
339 | }
340 | .employee-summary header h1{
341 | font-size: 17px;
342 | line-height: 1.2em;
343 | }
344 | .employee-summary header h1 a{
345 | color: #000;
346 | text-decoration: none;
347 | }
348 | .employee-summary header + .grouped-tableview{
349 | margin-top: 0;
350 | }
351 | .employee-summary{
352 | padding-bottom: 1px;
353 | background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,0)), to(rgba(0,0,0,.12)));
354 | background-image: -webkit-linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,.12));
355 | background-image: -moz-linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,.12));
356 | background-image: -ms-linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,.12));
357 | background-image: -o-linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,.12));
358 | background-image: linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,.12));
359 | -webkit-background-size: 1px 11px;
360 | -moz-background-size: 1px 11px;
361 | -ms-background-size: 1px 11px;
362 | -o-background-size: 1px 11px;
363 | background-size: 1px 11px;
364 | background-repeat: repeat-x;
365 | background-position: bottom;
366 |
367 | height: 120px;
368 | }
369 |
370 | .employee-summary img {
371 | float: left;
372 | margin-right: 12px;
373 | }
374 |
375 | .action-item {
376 | box-flex: 1;
377 | }
378 |
379 | .action-icon {
380 | position: absolute;
381 | right: 10px;
382 | width: 28px;
383 | }
--------------------------------------------------------------------------------
/iphone/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Employee Directory
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/iphone/libs/underscore-min.js:
--------------------------------------------------------------------------------
1 | // Underscore.js 1.3.2
2 | // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
3 | // Underscore is freely distributable under the MIT license.
4 | // Portions of Underscore are inspired or borrowed from Prototype,
5 | // Oliver Steele's Functional, and John Resig's Micro-Templating.
6 | // For all details and documentation:
7 | // http://documentcloud.github.com/underscore
8 | (function(){function r(a,c,d){if(a===c)return 0!==a||1/a==1/c;if(null==a||null==c)return a===c;a._chain&&(a=a._wrapped);c._chain&&(c=c._wrapped);if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return!1;switch(e){case "[object String]":return a==""+c;case "[object Number]":return a!=+a?c!=+c:0==a?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
9 | c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if("object"!=typeof a||"object"!=typeof c)return!1;for(var f=d.length;f--;)if(d[f]==a)return!0;d.push(a);var f=0,g=!0;if("[object Array]"==e){if(f=a.length,g=f==c.length)for(;f--&&(g=f in a==f in c&&r(a[f],c[f],d)););}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return!1;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&r(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,h)&&!f--)break;
10 | g=!f}}d.pop();return g}var s=this,I=s._,o={},k=Array.prototype,p=Object.prototype,i=k.slice,J=k.unshift,l=p.toString,K=p.hasOwnProperty,y=k.forEach,z=k.map,A=k.reduce,B=k.reduceRight,C=k.filter,D=k.every,E=k.some,q=k.indexOf,F=k.lastIndexOf,p=Array.isArray,L=Object.keys,t=Function.prototype.bind,b=function(a){return new m(a)};"undefined"!==typeof exports?("undefined"!==typeof module&&module.exports&&(exports=module.exports=b),exports._=b):s._=b;b.VERSION="1.3.2";var j=b.each=b.forEach=function(a,
11 | c,d){if(a!=null)if(y&&a.forEach===y)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e2;a==null&&(a=[]);if(A&&
12 | a.reduce===A){e&&(c=b.bind(c,e));return f?a.reduce(c,d):a.reduce(c)}j(a,function(a,b,i){if(f)d=c.call(e,d,a,b,i);else{d=a;f=true}});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(B&&a.reduceRight===B){e&&(c=b.bind(c,e));return f?a.reduceRight(c,d):a.reduceRight(c)}var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=function(a,
13 | c,b){var e;G(a,function(a,g,h){if(c.call(b,a,g,h)){e=a;return true}});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(C&&a.filter===C)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(D&&a.every===D)return a.every(c,b);j(a,function(a,g,h){if(!(e=e&&c.call(b,
14 | a,g,h)))return o});return!!e};var G=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(E&&a.some===E)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return o});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;if(q&&a.indexOf===q)return a.indexOf(c)!=-1;return b=G(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=
15 | function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0])return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0])return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;bd?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};
17 | j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1),true);return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=
20 | i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=L||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&
25 | c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.pick=function(a){var c={};j(b.flatten(i.call(arguments,1)),function(b){b in a&&(c[b]=a[b])});return c};b.defaults=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return r(a,b,[])};b.isEmpty=
26 | function(a){if(a==null)return true;if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=function(a){return l.call(a)=="[object Arguments]"};b.isArguments(arguments)||(b.isArguments=function(a){return!(!a||!b.has(a,"callee"))});b.isFunction=function(a){return l.call(a)=="[object Function]"};
27 | b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isFinite=function(a){return b.isNumber(a)&&isFinite(a)};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,
28 | b){return K.call(a,b)};b.noConflict=function(){s._=I;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e /g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.result=function(a,c){if(a==null)return null;var d=a[c];return b.isFunction(d)?d.call(a):d};b.mixin=function(a){j(b.functions(a),function(c){M(c,b[c]=a[c])})};var N=0;b.uniqueId=
29 | function(a){var b=N++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var u=/.^/,n={"\\":"\\","'":"'",r:"\r",n:"\n",t:"\t",u2028:"\u2028",u2029:"\u2029"},v;for(v in n)n[n[v]]=v;var O=/\\|'|\r|\n|\t|\u2028|\u2029/g,P=/\\(\\|'|r|n|t|u2028|u2029)/g,w=function(a){return a.replace(P,function(a,b){return n[b]})};b.template=function(a,c,d){d=b.extend(b.templateSettings,d);a="__p+='"+a.replace(O,function(a){return"\\"+n[a]}).replace(d.escape||
30 | u,function(a,b){return"'+\n_.escape("+w(b)+")+\n'"}).replace(d.interpolate||u,function(a,b){return"'+\n("+w(b)+")+\n'"}).replace(d.evaluate||u,function(a,b){return"';\n"+w(b)+"\n;__p+='"})+"';\n";d.variable||(a="with(obj||{}){\n"+a+"}\n");var a="var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n"+a+"return __p;\n",e=new Function(d.variable||"obj","_",a);if(c)return e(c,b);c=function(a){return e.call(this,a,b)};c.source="function("+(d.variable||"obj")+"){\n"+a+"}";return c};
31 | b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var x=function(a,c){return c?b(a).chain():a},M=function(a,c){m.prototype[a]=function(){var a=i.call(arguments);J.call(a,this._wrapped);return x(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return x(d,
32 | this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return x(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=true;return this};m.prototype.value=function(){return this._wrapped}}).call(this);
33 |
--------------------------------------------------------------------------------
/iphone/pics/Andy_Bernard.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/pics/Andy_Bernard.jpg
--------------------------------------------------------------------------------
/iphone/pics/Angela_Martin.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/pics/Angela_Martin.jpg
--------------------------------------------------------------------------------
/iphone/pics/Creed_Bratton.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/pics/Creed_Bratton.jpg
--------------------------------------------------------------------------------
/iphone/pics/Dwight_Schrute.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/pics/Dwight_Schrute.jpg
--------------------------------------------------------------------------------
/iphone/pics/Jim_Halpert.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/pics/Jim_Halpert.jpg
--------------------------------------------------------------------------------
/iphone/pics/Kelly_Kapoor.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/pics/Kelly_Kapoor.jpg
--------------------------------------------------------------------------------
/iphone/pics/Kevin_Malone.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/pics/Kevin_Malone.jpg
--------------------------------------------------------------------------------
/iphone/pics/Meredith_Palmer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/pics/Meredith_Palmer.jpg
--------------------------------------------------------------------------------
/iphone/pics/Michael_Scott.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/pics/Michael_Scott.jpg
--------------------------------------------------------------------------------
/iphone/pics/Oscar_Martinez.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/pics/Oscar_Martinez.jpg
--------------------------------------------------------------------------------
/iphone/pics/Pamela_Beesly.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/pics/Pamela_Beesly.jpg
--------------------------------------------------------------------------------
/iphone/pics/Phyllis_Lapin.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/pics/Phyllis_Lapin.jpg
--------------------------------------------------------------------------------
/iphone/pics/Ryan_Howard.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/pics/Ryan_Howard.jpg
--------------------------------------------------------------------------------
/iphone/pics/Stanley_Hudson.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/pics/Stanley_Hudson.jpg
--------------------------------------------------------------------------------
/iphone/pics/Toby_Flenderson.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/iphone/pics/Toby_Flenderson.jpg
--------------------------------------------------------------------------------
/iphone/tpl/employee-list-item.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%= firstName %> <%= lastName %>
5 |
6 | <%= title %>
7 | <%= reportCount %> direct reports
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/iphone/tpl/employee-page.html:
--------------------------------------------------------------------------------
1 |
11 |
12 |
--------------------------------------------------------------------------------
/iphone/tpl/report-page.html:
--------------------------------------------------------------------------------
1 |
6 |
7 |
--------------------------------------------------------------------------------
/iphone/tpl/search-page.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/jquerymobile/css/images/ajax-loader.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/css/images/ajax-loader.png
--------------------------------------------------------------------------------
/jquerymobile/css/images/icons-18-black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/css/images/icons-18-black.png
--------------------------------------------------------------------------------
/jquerymobile/css/images/icons-18-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/css/images/icons-18-white.png
--------------------------------------------------------------------------------
/jquerymobile/css/images/icons-36-black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/css/images/icons-36-black.png
--------------------------------------------------------------------------------
/jquerymobile/css/images/icons-36-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/css/images/icons-36-white.png
--------------------------------------------------------------------------------
/jquerymobile/css/styles.css:
--------------------------------------------------------------------------------
1 | .employee-pic {
2 | float: left;
3 | padding-right: 10px;
4 | padding-bottom: 16px;
5 | }
6 |
7 | .employee-details p {
8 | margin-top: 0px;
9 | margin-bottom: 8px;
10 | }
11 |
12 | .action-list {
13 | clear: both;
14 | }
--------------------------------------------------------------------------------
/jquerymobile/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/img/logo.png
--------------------------------------------------------------------------------
/jquerymobile/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/jquerymobile/js/jqm-config.js:
--------------------------------------------------------------------------------
1 | $(document).bind("mobileinit", function () {
2 | console.log('mobileinit');
3 | $.mobile.ajaxEnabled = false;
4 | $.mobile.linkBindingEnabled = false;
5 | $.mobile.hashListeningEnabled = false;
6 | $.mobile.pushStateEnabled = false;
7 |
8 | // Remove page from DOM when it's being replaced
9 | $('div[data-role="page"]').live('pagehide', function (event, ui) {
10 | $(event.currentTarget).remove();
11 | });
12 | });
--------------------------------------------------------------------------------
/jquerymobile/js/main.js:
--------------------------------------------------------------------------------
1 | var AppRouter = Backbone.Router.extend({
2 |
3 | routes:{
4 | "":"list",
5 | "list":"list",
6 | "employees/:id":"employeeDetails",
7 | "employees/:id/reports":"directReports"
8 | },
9 |
10 | initialize:function () {
11 | $('.back').live('click', function(event) {
12 | window.history.back();
13 | return false;
14 | });
15 | this.firstPage = true;
16 | this.searchResults = new EmployeeCollection();
17 |
18 | },
19 |
20 | list:function () {
21 | this.changePage(new EmployeeListPage({model: this.searchResults}));
22 | },
23 |
24 | employeeDetails:function (id) {
25 | var employee = new Employee({id:id});
26 | var self = this;
27 | employee.fetch({
28 | success:function (data) {
29 | self.changePage(new EmployeeView({model:data}));
30 | }
31 | });
32 | },
33 |
34 | directReports:function (id) {
35 | var employee = new Employee({id:id});
36 | employee.reports.fetch();
37 | this.changePage(new DirectReportPage({model:employee.reports}));
38 | },
39 |
40 | changePage:function (page) {
41 | $(page.el).attr('data-role', 'page');
42 | page.render();
43 | $('body').append($(page.el));
44 | var transition = $.mobile.defaultPageTransition;
45 | // We don't want to slide the first page
46 | if (this.firstPage) {
47 | transition = 'none';
48 | this.firstPage = false;
49 | }
50 | $.mobile.changePage($(page.el), {changeHash:false, transition: transition});
51 | }
52 |
53 | });
54 |
55 | $(document).ready(function () {
56 | tpl.loadTemplates(['search-page', 'report-list', 'employee-details', 'employee-list-item'],
57 | function () {
58 | app = new AppRouter();
59 | Backbone.history.start();
60 | });
61 | });
--------------------------------------------------------------------------------
/jquerymobile/js/models/employeemodel.js:
--------------------------------------------------------------------------------
1 | window.Employee = Backbone.Model.extend({
2 |
3 | urlRoot:"../api/employees",
4 |
5 | initialize:function () {
6 | this.reports = new EmployeeCollection();
7 | this.reports.url = '../api/employees/' + this.id + '/reports';
8 | }
9 |
10 | });
11 |
12 | window.EmployeeCollection = Backbone.Collection.extend({
13 |
14 | model:Employee,
15 |
16 | url:"../api/employees",
17 |
18 | findByName:function (key) {
19 | var url = (key == '') ? '../api/employees' : "../api/employees/search/" + key;
20 | console.log('findByName: ' + key);
21 | var self = this;
22 | $.ajax({
23 | url:url,
24 | dataType:"json",
25 | success:function (data) {
26 | console.log("search success: " + data.length);
27 | self.reset(data);
28 | }
29 | });
30 | }
31 |
32 | });
--------------------------------------------------------------------------------
/jquerymobile/js/utils.js:
--------------------------------------------------------------------------------
1 | tpl = {
2 |
3 | // Hash of preloaded templates for the app
4 | templates:{},
5 |
6 | // Recursively pre-load all the templates for the app.
7 | // This implementation should be changed in a production environment. All the template files should be
8 | // concatenated in a single file.
9 | loadTemplates:function (names, callback) {
10 |
11 | var that = this;
12 |
13 | var loadTemplate = function (index) {
14 | var name = names[index];
15 | console.log('Loading template: ' + name);
16 | $.get('tpl/' + name + '.html', function (data) {
17 | that.templates[name] = data;
18 | index++;
19 | if (index < names.length) {
20 | loadTemplate(index);
21 | } else {
22 | callback();
23 | }
24 | });
25 | }
26 |
27 | loadTemplate(0);
28 | },
29 |
30 | // Get template by name from hash of preloaded templates
31 | get:function (name) {
32 | return this.templates[name];
33 | }
34 |
35 | };
--------------------------------------------------------------------------------
/jquerymobile/js/views/employeedetails.js:
--------------------------------------------------------------------------------
1 | window.EmployeeView = Backbone.View.extend({
2 |
3 | initialize:function () {
4 | this.template = _.template(tpl.get('employee-details'));
5 | },
6 |
7 | render:function (eventName) {
8 | $(this.el).html(this.template(this.model.toJSON()));
9 | return this;
10 | }
11 |
12 | });
--------------------------------------------------------------------------------
/jquerymobile/js/views/employeelist.js:
--------------------------------------------------------------------------------
1 | window.EmployeeListPage = Backbone.View.extend({
2 |
3 | initialize:function () {
4 | this.template = _.template(tpl.get('search-page'));
5 | },
6 |
7 | render:function (eventName) {
8 | $(this.el).html(this.template(this.model.toJSON()));
9 | this.listView = new EmployeeListView({el: $('ul', this.el), model: this.model});
10 | this.listView.render();
11 | return this;
12 | },
13 |
14 | events:{
15 | "keyup .search-query":"search"
16 | },
17 |
18 | search:function (event) {
19 | var key = $('.search-query').val();
20 | console.log('search ' + key);
21 | this.model.findByName(key);
22 | }
23 | });
24 |
25 | window.DirectReportPage = Backbone.View.extend({
26 |
27 | initialize:function () {
28 | this.template = _.template(tpl.get('report-list'));
29 | },
30 |
31 | render:function (eventName) {
32 | $(this.el).html(this.template(this.model.toJSON()));
33 | this.listView = new EmployeeListView({el: $('ul', this.el), model: this.model});
34 | return this;
35 | }
36 |
37 | });
38 |
39 | window.EmployeeListView = Backbone.View.extend({
40 |
41 | initialize:function () {
42 | this.model.bind("reset", this.render, this);
43 | },
44 |
45 | render:function (eventName) {
46 | $(this.el).empty();
47 | $('#welcome').remove();
48 | _.each(this.model.models, function (employee) {
49 | $(this.el).append(new EmployeeListItemView({model:employee}).render().el);
50 | }, this);
51 | $('#myList').listview('refresh');
52 | return this;
53 | }
54 | });
55 |
56 | window.EmployeeListItemView = Backbone.View.extend({
57 |
58 | tagName:"li",
59 |
60 | initialize:function () {
61 | this.template = _.template(tpl.get('employee-list-item'));
62 | this.model.bind("change", this.render, this);
63 | this.model.bind("destroy", this.close, this);
64 | },
65 |
66 | render:function (eventName) {
67 | $(this.el).html(this.template(this.model.toJSON()));
68 | return this;
69 | }
70 |
71 | });
--------------------------------------------------------------------------------
/jquerymobile/lib/underscore-min.js:
--------------------------------------------------------------------------------
1 | // Underscore.js 1.2.4
2 | // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
3 | // Underscore is freely distributable under the MIT license.
4 | // Portions of Underscore are inspired or borrowed from Prototype,
5 | // Oliver Steele's Functional, and John Resig's Micro-Templating.
6 | // For all details and documentation:
7 | // http://documentcloud.github.com/underscore
8 | (function(){function r(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
9 | c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&r(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(m.call(a,h)&&(f++,!(g=m.call(c,h)&&r(a[h],c[h],d))))break;if(g){for(h in c)if(m.call(c,
10 | h)&&!f--)break;g=!f}}d.pop();return g}var s=this,G=s._,o={},k=Array.prototype,p=Object.prototype,i=k.slice,H=k.unshift,l=p.toString,m=p.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,q=k.indexOf,D=k.lastIndexOf,p=Array.isArray,I=Object.keys,t=Function.prototype.bind,b=function(a){return new n(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else typeof define==="function"&&define.amd?
11 | define("underscore",function(){return b}):s._=b;b.VERSION="1.2.4";var j=b.each=b.forEach=function(a,c,b){if(a!=null)if(w&&a.forEach===w)a.forEach(c,b);else if(a.length===+a.length)for(var e=0,f=a.length;e2;a==null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&
13 | (c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;
14 | if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e=e&&c.call(b,a,g,h)))return o});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return o});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return q&&a.indexOf===q?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,
15 | function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,
16 | b,h){b=c?c.call(d,a,b,h):a;bd?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=
17 | e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=
20 | 0;e=
24 | 0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=I||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var b=[],d;for(d in a)m.call(a,d)&&(b[b.length]=d);return b};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)b[d]!==
25 | void 0&&(a[d]=b[d])});return a};b.defaults=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return r(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(m.call(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)==
26 | "[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!m.call(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};
27 | b.isDate=function(a){return l.call(a)=="[object Date]"};b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.noConflict=function(){s._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e /g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};
28 | b.mixin=function(a){j(b.functions(a),function(c){J(c,b[c]=a[c])})};var K=0;b.uniqueId=function(a){var b=K++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var u=/.^/;b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||u,function(a,b){return"',_.escape("+b.replace(/\\'/g,"'")+"),'"}).replace(d.interpolate||
29 | u,function(a,b){return"',"+b.replace(/\\'/g,"'")+",'"}).replace(d.evaluate||u,function(a,b){return"');"+b.replace(/\\'/g,"'").replace(/[\r\n\t]/g," ").replace(/\\\\/g,"\\")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var n=function(a){this._wrapped=a};b.prototype=n.prototype;var v=function(a,c){return c?b(a).chain():
30 | a},J=function(a,c){n.prototype[a]=function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];n.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];n.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});
31 | n.prototype.chain=function(){this._chain=true;return this};n.prototype.value=function(){return this._wrapped}}).call(this);
32 |
--------------------------------------------------------------------------------
/jquerymobile/pics/Amy_Jones.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Amy_Jones.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Amy_Jones100.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Amy_Jones100.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Amy_Jones50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Amy_Jones50.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Eugene_Lee.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Eugene_Lee.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Eugene_Lee100.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Eugene_Lee100.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Eugene_Lee50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Eugene_Lee50.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Gary_Donovan.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Gary_Donovan.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Gary_Donovan100.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Gary_Donovan100.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Gary_Donovan50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Gary_Donovan50.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/James_King.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/James_King.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/James_King100.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/James_King100.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/James_King50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/James_King50.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/John_Williams.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/John_Williams.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/John_Williams100.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/John_Williams100.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/John_Williams50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/John_Williams50.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Julie_Taylor.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Julie_Taylor.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Julie_Taylor100.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Julie_Taylor100.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Julie_Taylor50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Julie_Taylor50.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Kathleen_Byrne.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Kathleen_Byrne.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Kathleen_Byrne100.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Kathleen_Byrne100.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Kathleen_Byrne50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Kathleen_Byrne50.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Lisa_Wong.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Lisa_Wong.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Lisa_Wong100.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Lisa_Wong100.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Lisa_Wong50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Lisa_Wong50.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Paul_Jones.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Paul_Jones.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Paul_Jones100.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Paul_Jones100.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Paul_Jones50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Paul_Jones50.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Paula_Gates.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Paula_Gates.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Paula_Gates100.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Paula_Gates100.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Paula_Gates50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Paula_Gates50.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Ray_Moore.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Ray_Moore.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Ray_Moore100.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Ray_Moore100.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Ray_Moore50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Ray_Moore50.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Steven_Wells.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Steven_Wells.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Steven_Wells100.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Steven_Wells100.jpg
--------------------------------------------------------------------------------
/jquerymobile/pics/Steven_Wells50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/jquerymobile/pics/Steven_Wells50.jpg
--------------------------------------------------------------------------------
/jquerymobile/tpl/employee-details.html:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
<%= firstName %> <%= lastName %>
11 |
<%= title %>
12 |
13 |
14 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/jquerymobile/tpl/employee-list-item.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%= firstName %> <%= lastName %>
4 | <%= title %>
5 | <%= reportCount %>
6 |
7 |
8 |
--------------------------------------------------------------------------------
/jquerymobile/tpl/report-list.html:
--------------------------------------------------------------------------------
1 |
6 |
7 |
--------------------------------------------------------------------------------
/jquerymobile/tpl/search-page.html:
--------------------------------------------------------------------------------
1 |
2 |
Directory
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
Welcome to Backbone Directory!
11 |
12 |
This is a sample app that demonstrates how to build applications with Backbone.js and jQuery Mobile.
13 |
14 |
15 |
16 |
17 |
20 |
--------------------------------------------------------------------------------
/localdb/css/images/activity-indicator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/css/images/activity-indicator.png
--------------------------------------------------------------------------------
/localdb/css/images/back-button-active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/css/images/back-button-active.png
--------------------------------------------------------------------------------
/localdb/css/images/back-button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/css/images/back-button.png
--------------------------------------------------------------------------------
/localdb/css/images/button-active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/css/images/button-active.png
--------------------------------------------------------------------------------
/localdb/css/images/button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/css/images/button.png
--------------------------------------------------------------------------------
/localdb/css/images/call.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/css/images/call.png
--------------------------------------------------------------------------------
/localdb/css/images/comment-arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/css/images/comment-arrow.png
--------------------------------------------------------------------------------
/localdb/css/images/detail-disclosure-button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/css/images/detail-disclosure-button.png
--------------------------------------------------------------------------------
/localdb/css/images/disclosure-indicator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/css/images/disclosure-indicator.png
--------------------------------------------------------------------------------
/localdb/css/images/mail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/css/images/mail.png
--------------------------------------------------------------------------------
/localdb/css/images/manager.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/css/images/manager.png
--------------------------------------------------------------------------------
/localdb/css/images/message.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/css/images/message.png
--------------------------------------------------------------------------------
/localdb/css/images/navbar-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/css/images/navbar-bg.png
--------------------------------------------------------------------------------
/localdb/css/images/navbar-landscape-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/css/images/navbar-landscape-bg.png
--------------------------------------------------------------------------------
/localdb/css/images/refresh-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/css/images/refresh-icon.png
--------------------------------------------------------------------------------
/localdb/css/images/reports.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/css/images/reports.png
--------------------------------------------------------------------------------
/localdb/css/images/search-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/css/images/search-icon.png
--------------------------------------------------------------------------------
/localdb/css/styles.css:
--------------------------------------------------------------------------------
1 | /* Many of the styles below come from the app documented in this article http://cheeaun.com/blog/2012/03/how-i-built-hacker-news-mobile-web-app */
2 |
3 | html{
4 | height: 100%;
5 | }
6 | body{
7 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
8 | font-size: 16px;
9 | margin: 0;
10 | padding: 0;
11 | height: 100%;
12 | background-color: #fff;
13 | overflow: hidden;
14 | position: relative;
15 | }
16 |
17 | .header{
18 | background: #b2bbca url(images/navbar-bg.png) repeat-x;
19 | -webkit-background-size: 1px 44px;
20 | -moz-background-size: 1px 44px;
21 | -ms-background-size: 1px 44px;
22 | -o-background-size: 1px 44px;
23 | background-size: 1px 44px;
24 | height: 44px;
25 | line-height: 44px;
26 | width: 100%;
27 | color: #fff;
28 | -webkit-user-select: none;
29 | -webkit-touch-callout: none;
30 | }
31 |
32 | .header-button{
33 | position: absolute;
34 | top: 0;
35 | padding: 7px 5px;
36 | -webkit-tap-highlight-color: rgba(0,0,0,0);
37 | line-height: 1em;
38 | }
39 |
40 | .header-button button{
41 | pointer-events: none;
42 | -webkit-box-sizing: border-box;
43 | -moz-box-sizing: border-box;
44 | box-sizing: border-box;
45 | min-width: 50px;
46 | height: 30px;
47 | line-height: 25px;
48 | font-weight: bold;
49 | font-size: 12px;
50 | text-align: center;
51 | color: #fff;
52 | text-shadow: 0 -1px rgba(0,0,0,.6);
53 | padding: 0 4px;
54 | margin: 0;
55 | text-decoration: none;
56 | border-width: 2px 5px;
57 | -webkit-border-image: url(images/button.png) 4 10 4 10;
58 | -moz-border-image: url(images/button.png) 4 10 4 10;
59 | -ms-border-image: url(images/button.png) 4 10 4 10;
60 | -o-border-image: url(images/button.png) 4 10 4 10;
61 | background: transparent url(images/button-active.png) no-repeat;
62 | -webkit-background-size: 0 0;
63 | -moz-background-size: 0 0;
64 | -ms-background-size: 0 0;
65 | -o-background-size: 0 0;
66 | background-size: 0 0;
67 | }
68 |
69 | .header-button-icon button{
70 | min-width: 0;
71 | }
72 |
73 | .header-button-icon button img{
74 | vertical-align: text-bottom;
75 | }
76 |
77 | .header-button.tappable-active button{
78 | -webkit-border-image: url(images/button-active.png) 4 10 4 10;
79 | -moz-border-image: url(images/button-active.png) 4 10 4 10;
80 | -ms-border-image: url(images/button-active.png) 4 10 4 10;
81 | -o-border-image: url(images/button-active.png) 4 10 4 10;
82 | }
83 |
84 | .header-back-button button{
85 | padding: 0 4px 0 0;
86 | border-width: 2px 4px 2px 13px;
87 | -webkit-border-image: url(images/back-button.png) 4 8 4 26;
88 | -moz-border-image: url(images/back-button.png) 4 8 4 26;
89 | -ms-border-image: url(images/back-button.png) 4 8 4 26;
90 | -o-border-image: url(images/back-button.png) 4 8 4 26;
91 | background-image: url(images/back-button-active.png);
92 | }
93 | .header-back-button.tappable-active button{
94 | -webkit-border-image: url(images/back-button-active.png) 4 8 4 26;
95 | -moz-border-image: url(images/back-button-active.png) 4 8 4 26;
96 | -ms-border-image: url(images/back-button-active.png) 4 8 4 26;
97 | -o-border-image: url(images/back-button-active.png) 4 8 4 26;
98 | }
99 |
100 | .header-button-left{
101 | left: 0;
102 | }
103 |
104 | .header-button-right{
105 | right: 0;
106 | }
107 |
108 | .header h1{
109 | padding: 0;
110 | text-align: center;
111 | font-size: 20px;
112 | text-shadow: 0 -1px rgba(0,0,0,.4);
113 | margin: 0;
114 | white-space: nowrap;
115 | text-overflow: ellipsis;
116 | overflow: hidden;
117 | -webkit-box-flex: 1;
118 | -moz-box-flex: 1;
119 | box-flex: 1;
120 | }
121 |
122 | .scroll{
123 | -webkit-box-flex: 1;
124 | -moz-box-flex: 1;
125 | box-flex: 1;
126 | overflow: auto;
127 | -webkit-overflow-scrolling: touch;
128 | background-color: #e2e7ed;
129 | display: -webkit-box;
130 | display: -moz-box;
131 | display: box;
132 | -webkit-box-orient: vertical;
133 | -moz-box-orient: vertical;
134 | box-orient: vertical;
135 | position: absolute;
136 | top: 80px;
137 | bottom: 0px;
138 | left: 0px;
139 | right: 0px;
140 | }
141 |
142 | .scroll.striped{
143 | background-color: #cbd2d8;
144 | background-image: -webkit-gradient(linear, left top, right top, from(#c5ccd4), color-stop(0.714, #c5ccd4), color-stop(0.714, #cbd2d8), to(#cbd2d8));
145 | background-image: -webkit-linear-gradient(left, #c5ccd4, #c5ccd4 71.4%, #cbd2d8 71.5%, #cbd2d8);
146 | background-image: -moz-linear-gradient(left, #c5ccd4, #c5ccd4 71.4%, #cbd2d8 71.5%, #cbd2d8);
147 | background-image: -ms-linear-gradient(left, #c5ccd4, #c5ccd4 71.4%, #cbd2d8 71.5%, #cbd2d8);
148 | background-image: -o-linear-gradient(left, #c5ccd4, #c5ccd4 71.4%, #cbd2d8 71.5%, #cbd2d8);
149 | background-image: linear-gradient(left, #c5ccd4, #c5ccd4 71.4%, #cbd2d8 71.5%, #cbd2d8);
150 | -webkit-background-size: 7px 1px;
151 | -moz-background-size: 7px 1px;
152 | -ms-background-size: 7px 1px;
153 | -o-background-size: 7px 1px;
154 | background-size: 7px 1px;
155 | }
156 |
157 | .tableview{
158 | margin: 0;
159 | padding: 0;
160 | list-style: none;
161 | background-color: #fff;
162 | border-bottom: 1px solid #e0e0e0;
163 | }
164 | .tableview li{
165 | display: block;
166 | border-top: 1px solid #e0e0e0;
167 | padding: 10px;
168 | }
169 |
170 | .tableview-links li{
171 | padding: 0;
172 | display: -webkit-box;
173 | display: -moz-box;
174 | display: box;
175 | width: 100%;
176 | }
177 |
178 | .tableview-links li>a{
179 | font-size: 15px;
180 | line-height: 1.3em;
181 | color: #000;
182 | display: block;
183 | padding: 5px;
184 | text-decoration: none;
185 | -webkit-tap-highlight-color: rgba(0,0,0,0);
186 | display: -webkit-box;
187 | display: -moz-box;
188 | display: box;
189 | width: 100%;
190 | -webkit-box-flex: 1;
191 | -moz-box-flex: 1;
192 | box-flex: 1;
193 | -webkit-box-sizing: border-box;
194 | -moz-box-sizing: border-box;
195 | box-sizing: border-box;
196 | background-image: -webkit-gradient(linear, left top, left bottom, from(#4286f5), to(#194fdb));
197 | background-image: -webkit-linear-gradient(top, #4286f5, #194fdb);
198 | background-image: -moz-linear-gradient(top, #4286f5, #194fdb);
199 | background-image: -ms-linear-gradient(top, #4286f5, #194fdb);
200 | background-image: -o-linear-gradient(top, #4286f5, #194fdb);
201 | background-image: linear-gradient(top, #4286f5, #194fdb);
202 | background-position: -10px 0;
203 | background-repeat: no-repeat;
204 | -webkit-background-size: 10px 100%;
205 | -moz-background-size: 10px 100%;
206 | -ms-background-size: 10px 100%;
207 | -o-background-size: 10px 100%;
208 | background-size: 10px 100%;
209 | }
210 |
211 | .tableview-links li>a *{
212 | pointer-events: none;
213 | }
214 |
215 | .tableview-links li>a .metadata{
216 | display: block;
217 | font-size: 13px;
218 | color: #666d74;
219 | line-height: 1.2em;
220 | }
221 | .tableview-links li>a.pad-right{
222 | padding-right: 44px;
223 | }
224 | .tableview-links li>a.more-link{
225 | cursor: pointer;
226 | -webkit-touch-callout: none;
227 | line-height: 3em;
228 | padding: 10px;
229 | display: block;
230 | color: #2960d9;
231 | text-align: center;
232 | font-weight: bold;
233 | }
234 |
235 | .tableview-links li>a.tappable-active{
236 | color: #fff;
237 | background-color: #4286f5;
238 | background-repeat: repeat-x;
239 | }
240 | .tableview-links li>a.tappable-active *{
241 | color: #fff;
242 | }
243 | .tableview-links li>a.detail-disclosure{
244 | -webkit-touch-callout: none;
245 | padding: 0;
246 | width: 44px;
247 | margin: 0 0 0 -44px;
248 | -webkit-box-align: center;
249 | -moz-box-align: center;
250 | box-align: center;
251 | -webkit-box-pack: center;
252 | -moz-box-pack: center;
253 | box-pack: center;
254 | -webkit-box-flex: 0;
255 | -moz-box-flex: 0;
256 | box-flex: 0;
257 | }
258 | .tableview-links li>a.detail-disclosure.tappable-active{
259 | background: transparent none;
260 | }
261 | .tableview-links li>a.detail-disclosure span{
262 | display: inline-block;
263 | width: 29px;
264 | height: 31px;
265 | background: transparent url(images/detail-disclosure-button.png);
266 | -webkit-background-size: 58px 31px;
267 | -moz-background-size: 58px 31px;
268 | -ms-background-size: 58px 31px;
269 | -o-background-size: 58px 31px;
270 | background-size: 58px 31px;
271 | }
272 | .tableview-links li>a.detail-disclosure.tappable-active span{
273 | background-position: top right;
274 | }
275 |
276 | .link-text{
277 | color: #385487;
278 | font-weight: bold;
279 | }
280 | .inline-block{
281 | display: inline-block;
282 | }
283 |
284 |
285 | #content {
286 | position: absolute;
287 | background: #ddd;
288 | width: 100%;
289 | height: 100%;
290 | overflow-x: hidden;
291 | overflow-y: auto;
292 | }
293 |
294 | .page {
295 | position: absolute;
296 | width: 100%;
297 | height: 100%;
298 | background-color: #ddd;
299 | -webkit-transform:translate3d(0,0,0);
300 | }
301 |
302 | .stage-center {
303 | top: 0;
304 | left: 0;
305 | }
306 |
307 | .stage-left {
308 | left: -100%;
309 | }
310 |
311 | .stage-right {
312 | left: 100%;
313 | }
314 |
315 | .transition {
316 | -moz-transition-duration: .375s;
317 | -webkit-transition-duration: .375s;
318 | -o-transition-duration: .375s;
319 | }
320 |
321 | .employee-summary header{
322 | padding: 10px 8px;
323 | text-shadow: 0 1px rgba(255,255,255,.85);
324 | }
325 | .employee-summary header h1,
326 | .employee-summary header p{
327 | margin: 0;
328 | padding: 0;
329 | }
330 | .employee-summary header h1 a{
331 | display: block;
332 | }
333 | .employee-summary header h1 a .link-text{
334 | font-size: 13px;
335 | }
336 | .employee-summary header .metadata{
337 | font-size: 13px;
338 | color: #666d74;
339 | }
340 | .employee-summary header h1{
341 | font-size: 17px;
342 | line-height: 1.2em;
343 | }
344 | .employee-summary header h1 a{
345 | color: #000;
346 | text-decoration: none;
347 | }
348 | .employee-summary header + .grouped-tableview{
349 | margin-top: 0;
350 | }
351 | .employee-summary{
352 | padding-bottom: 1px;
353 | background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,0)), to(rgba(0,0,0,.12)));
354 | background-image: -webkit-linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,.12));
355 | background-image: -moz-linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,.12));
356 | background-image: -ms-linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,.12));
357 | background-image: -o-linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,.12));
358 | background-image: linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,.12));
359 | -webkit-background-size: 1px 11px;
360 | -moz-background-size: 1px 11px;
361 | -ms-background-size: 1px 11px;
362 | -o-background-size: 1px 11px;
363 | background-size: 1px 11px;
364 | background-repeat: repeat-x;
365 | background-position: bottom;
366 |
367 | height: 120px;
368 | }
369 |
370 | .employee-summary img {
371 | float: left;
372 | margin-right: 12px;
373 | }
374 |
375 | .action-item {
376 | box-flex: 1;
377 | }
378 |
379 | .action-icon {
380 | position: absolute;
381 | right: 10px;
382 | width: 28px;
383 | }
--------------------------------------------------------------------------------
/localdb/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Employee Directory
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/localdb/pics/Andy_Bernard.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/pics/Andy_Bernard.jpg
--------------------------------------------------------------------------------
/localdb/pics/Angela_Martin.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/pics/Angela_Martin.jpg
--------------------------------------------------------------------------------
/localdb/pics/Creed_Bratton.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/pics/Creed_Bratton.jpg
--------------------------------------------------------------------------------
/localdb/pics/Dwight_Schrute.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/pics/Dwight_Schrute.jpg
--------------------------------------------------------------------------------
/localdb/pics/Jim_Halpert.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/pics/Jim_Halpert.jpg
--------------------------------------------------------------------------------
/localdb/pics/Kelly_Kapoor.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/pics/Kelly_Kapoor.jpg
--------------------------------------------------------------------------------
/localdb/pics/Kevin_Malone.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/pics/Kevin_Malone.jpg
--------------------------------------------------------------------------------
/localdb/pics/Meredith_Palmer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/pics/Meredith_Palmer.jpg
--------------------------------------------------------------------------------
/localdb/pics/Michael_Scott.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/pics/Michael_Scott.jpg
--------------------------------------------------------------------------------
/localdb/pics/Oscar_Martinez.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/pics/Oscar_Martinez.jpg
--------------------------------------------------------------------------------
/localdb/pics/Pamela_Beesly.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/pics/Pamela_Beesly.jpg
--------------------------------------------------------------------------------
/localdb/pics/Phyllis_Lapin.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/pics/Phyllis_Lapin.jpg
--------------------------------------------------------------------------------
/localdb/pics/Ryan_Howard.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/pics/Ryan_Howard.jpg
--------------------------------------------------------------------------------
/localdb/pics/Stanley_Hudson.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/pics/Stanley_Hudson.jpg
--------------------------------------------------------------------------------
/localdb/pics/Toby_Flenderson.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/localdb/pics/Toby_Flenderson.jpg
--------------------------------------------------------------------------------
/localdb/tpl/employee-list-item.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%= firstName %> <%= lastName %>
5 |
6 | <%= title %>
7 | <%= reportCount %> direct reports
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/localdb/tpl/employee-page.html:
--------------------------------------------------------------------------------
1 |
11 |
12 |
--------------------------------------------------------------------------------
/localdb/tpl/report-page.html:
--------------------------------------------------------------------------------
1 |
6 |
7 |
--------------------------------------------------------------------------------
/localdb/tpl/search-page.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | ## Update ##
2 |
3 | This directory is no longer maintained. A new and improved version of the application is available in [this repository] (https://github.com/ccoenraets/directory-backbone-bootstrap)
4 |
5 |
6 | # Backbone.js Employee Directory #
7 |
8 | "Backbone Directory" is a simple Employee Directory application built with [Backbone.js](http://documentcloud.github.com/backbone/).
9 |
10 | The application allows you to look up employees by name, view the details of an employee, and navigate up and down the Org Chart by clicking the employee’s manager or any of his/her direct reports.
11 |
12 | There are four versions of the application available in this repository:
13 |
14 | 1. Backbone.js + Twitter Bootstrap (located in the [/web](http://twitter.github.com/bootstrap/) directory).
15 | - Read more about this version [here](http://coenraets.org/blog/2012/02/sample-app-with-backbone-js-and-twitter-bootstrap/)
16 | - Try it [here](http://coenraets.org/directory/)
17 | 2. Backbone.js + jQuery Mobile (located in the [/jquerymobile](https://github.com/ccoenraets/backbone-directory/tree/master/jquerymobile) directory).
18 | - Read more about this version [here](http://coenraets.org/blog/2012/03/employee-directory-sample-app-with-backbone-js-and-jquery-mobile/)
19 | - Try it [here](http://coenraets.org/backbone/directory/jquerymobile/)
20 | 3. Backbone.js + native-looking iPhone skins (located in the [/iphone](https://github.com/ccoenraets/backbone-directory/tree/master/iphone) directory).
21 | - Read more about this version [here](http://coenraets.org/blog/2012/03/crafting-native-looking-ios-apps-with-html-backbone-js-and-phonegap/)
22 | - Try it [here](http://coenraets.org/backbone/directory/iphone/)
23 | 4. Backbone.js + native-looking iPhone skins and a local database implementation (located in the [/iphone](https://github.com/ccoenraets/backbone-directory/tree/master/localdb) directory).
24 | - Read more about this version [here](http://coenraets.org/blog/2012/04/building-mobile-apps-with-html-and-a-local-database/)
25 | - Try it [here](http://coenraets.org/backbone/directory/localdb/)
26 |
27 | The Twitter Bootstrap and jQuery Mobile versions use JSON services. Instructions to set up these services are provided below. The "native-looking iPhone" versions use sample in-memory data and don't have any dependency on external services.
28 |
29 | ## Set Up: ##
30 |
31 | 1. Create a MySQL database name "directory".
32 | 2. Execute directory.sql to create and populate the "employee" table:
33 |
34 | mysql directory -uroot < directory.sql
35 |
36 | ## Services: ##
37 |
38 | The application is available with a PHP or Java services:
39 |
40 | - The PHP services are available in the api directory of this repository. The RESTful services are implemented in PHP using the [Slim framework](http://www.slimframework.com/) (also included in the api directory).
41 | - The Java back-end will be available soon.
42 |
--------------------------------------------------------------------------------
/web/css/styles.css:
--------------------------------------------------------------------------------
1 | .dropdown-menu {
2 | max-height: 400px;
3 | overflow-y: scroll;
4 | width: 220px;
5 | }
6 |
7 | .list-item {
8 | padding-top: 6px;
9 | padding-left: 56px;
10 | }
11 |
12 | .no-reports {
13 | display: none;
14 | }
--------------------------------------------------------------------------------
/web/img/glyphicons-halflings-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/img/glyphicons-halflings-white.png
--------------------------------------------------------------------------------
/web/img/glyphicons-halflings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/img/glyphicons-halflings.png
--------------------------------------------------------------------------------
/web/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/img/logo.png
--------------------------------------------------------------------------------
/web/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Backbone.js and Twitter Bootstrap Sample App
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/web/js/main.js:
--------------------------------------------------------------------------------
1 | window.Router = Backbone.Router.extend({
2 |
3 | routes: {
4 | "": "home",
5 | "contact": "contact",
6 | "employees/:id": "employeeDetails"
7 | },
8 |
9 | initialize: function () {
10 | this.headerView = new HeaderView();
11 | $('.header').html(this.headerView.render().el);
12 |
13 | // Close the search dropdown on click anywhere in the UI
14 | $('body').click(function () {
15 | $('.dropdown').removeClass("open");
16 | });
17 | },
18 |
19 | home: function () {
20 | // Since the home view never changes, we instantiate it and render it only once
21 | if (!this.homeView) {
22 | this.homeView = new HomeView();
23 | this.homeView.render();
24 | } else {
25 | this.homeView.delegateEvents(); // delegate events when the view is recycled
26 | }
27 | $("#content").html(this.homeView.el);
28 | this.headerView.select('home-menu');
29 | },
30 |
31 | contact: function () {
32 | if (!this.contactView) {
33 | this.contactView = new ContactView();
34 | this.contactView.render();
35 | }
36 | $('#content').html(this.contactView.el);
37 | this.headerView.select('contact-menu');
38 | },
39 |
40 | employeeDetails: function (id) {
41 | var employee = new Employee({id: id});
42 | employee.fetch({
43 | success: function (data) {
44 | // Note that we could also 'recycle' the same instance of EmployeeFullView
45 | // instead of creating new instances
46 | $('#content').html(new EmployeeView({model: data}).render().el);
47 | }
48 | });
49 | }
50 |
51 | });
52 |
53 | templateLoader.load(["HomeView", "ContactView", "HeaderView", "EmployeeView", "EmployeeSummaryView", "EmployeeListItemView"],
54 | function () {
55 | app = new Router();
56 | Backbone.history.start();
57 | });
--------------------------------------------------------------------------------
/web/js/models/employeemodel.js:
--------------------------------------------------------------------------------
1 | window.Employee = Backbone.Model.extend({
2 |
3 | urlRoot:"../api/employees",
4 |
5 | initialize:function () {
6 | this.reports = new EmployeeCollection();
7 | this.reports.url = '../api/employees/' + this.id + '/reports';
8 | }
9 |
10 | });
11 |
12 | window.EmployeeCollection = Backbone.Collection.extend({
13 |
14 | model: Employee,
15 |
16 | url:"../api/employees",
17 |
18 | findByName:function (key) {
19 | var url = (key == '') ? '../api/employees' : "../api/employees/search/" + key;
20 | console.log('findByName: ' + key);
21 | var self = this;
22 | $.ajax({
23 | url:url,
24 | dataType:"json",
25 | success:function (data) {
26 | console.log("search success: " + data.length);
27 | self.reset(data);
28 | }
29 | });
30 | }
31 |
32 | });
--------------------------------------------------------------------------------
/web/js/utils.js:
--------------------------------------------------------------------------------
1 | // The Template Loader. Used to asynchronously load templates located in separate .html files
2 | window.templateLoader = {
3 |
4 | load: function(views, callback) {
5 |
6 | var deferreds = [];
7 |
8 | $.each(views, function(index, view) {
9 | if (window[view]) {
10 | deferreds.push($.get('tpl/' + view + '.html', function(data) {
11 | window[view].prototype.template = _.template(data);
12 | }, 'html'));
13 | } else {
14 | alert(view + " not found");
15 | }
16 | });
17 |
18 | $.when.apply(null, deferreds).done(callback);
19 | }
20 |
21 | };
--------------------------------------------------------------------------------
/web/js/views/contact.js:
--------------------------------------------------------------------------------
1 | window.ContactView = Backbone.View.extend({
2 |
3 | initialize:function () {
4 | console.log('Initializing Contact View');
5 | // this.template = templates['Contact'];
6 | },
7 |
8 | render:function () {
9 | $(this.el).html(this.template());
10 | return this;
11 | }
12 |
13 | });
--------------------------------------------------------------------------------
/web/js/views/employeedetails.js:
--------------------------------------------------------------------------------
1 | window.EmployeeView = Backbone.View.extend({
2 |
3 | tagName:"div", // Not required since 'div' is the default if no el or tagName specified
4 |
5 | initialize:function () {
6 | // this.template = templates['Employee'];
7 | },
8 |
9 | render: function () {
10 | $(this.el).html(this.template(this.model.toJSON()));
11 | $('#details', this.el).html(new EmployeeSummaryView({model:this.model}).render().el);
12 | this.model.reports.fetch({
13 | success:function (data) {
14 | if (data.length == 0)
15 | $('.no-reports').show();
16 | }
17 | });
18 | $('#reports', this.el).append(new EmployeeListView({model:this.model.reports}).render().el);
19 | return this;
20 | }
21 | });
22 |
23 | window.EmployeeSummaryView = Backbone.View.extend({
24 |
25 | tagName:"div", // Not required since 'div' is the default if no el or tagName specified
26 |
27 | initialize:function () {
28 | // this.template = templates['EmployeeSummary'];
29 | this.model.bind("change", this.render, this);
30 | },
31 |
32 | render:function () {
33 | $(this.el).html(this.template(this.model.toJSON()));
34 | return this;
35 | }
36 |
37 | });
--------------------------------------------------------------------------------
/web/js/views/employeelist.js:
--------------------------------------------------------------------------------
1 | window.EmployeeListView = Backbone.View.extend({
2 |
3 | tagName:'ul',
4 |
5 | className:'nav nav-list',
6 |
7 | initialize:function () {
8 | var self = this;
9 | this.model.bind("reset", this.render, this);
10 | this.model.bind("add", function (employee) {
11 | $(self.el).append(new EmployeeListItemView({model:employee}).render().el);
12 | });
13 | },
14 |
15 | render:function () {
16 | $(this.el).empty();
17 | _.each(this.model.models, function (employee) {
18 | $(this.el).append(new EmployeeListItemView({model:employee}).render().el);
19 | }, this);
20 | return this;
21 | }
22 | });
23 |
24 | window.EmployeeListItemView = Backbone.View.extend({
25 |
26 | tagName:"li",
27 |
28 | initialize:function () {
29 | this.model.bind("change", this.render, this);
30 | this.model.bind("destroy", this.close, this);
31 | },
32 |
33 | render:function () {
34 | $(this.el).html(this.template(this.model.toJSON()));
35 | return this;
36 | }
37 |
38 | });
--------------------------------------------------------------------------------
/web/js/views/header.js:
--------------------------------------------------------------------------------
1 | window.HeaderView = Backbone.View.extend({
2 |
3 | initialize: function () {
4 | this.searchResults = new EmployeeCollection();
5 | this.searchresultsView = new EmployeeListView({model: this.searchResults, className: 'dropdown-menu'});
6 | },
7 |
8 | render: function () {
9 | $(this.el).html(this.template());
10 | $('.navbar-search', this.el).append(this.searchresultsView.render().el);
11 | return this;
12 | },
13 |
14 | events: {
15 | "keyup .search-query": "search",
16 | "keypress .search-query": "onkeypress"
17 | },
18 |
19 | search: function () {
20 | var key = $('#searchText').val();
21 | console.log('search ' + key);
22 | this.searchResults.findByName(key);
23 | setTimeout(function () {
24 | $('.dropdown').addClass('open');
25 | });
26 | },
27 |
28 | onkeypress: function (event) {
29 | if (event.keyCode == 13) {
30 | event.preventDefault();
31 | }
32 | },
33 |
34 | select: function(menuItem) {
35 | $('.nav li').removeClass('active');
36 | $('.' + menuItem).addClass('active');
37 | }
38 |
39 | });
--------------------------------------------------------------------------------
/web/js/views/home.js:
--------------------------------------------------------------------------------
1 | window.HomeView = Backbone.View.extend({
2 |
3 | initialize:function () {
4 | console.log('Initializing Home View');
5 | // this.template = _.template(directory.utils.templateLoader.get('home'));
6 | // this.template = templates['Home'];
7 | },
8 |
9 | events:{
10 | "click #showMeBtn":"showMeBtnClick"
11 | },
12 |
13 | render:function () {
14 | $(this.el).html(this.template());
15 | return this;
16 | },
17 |
18 | showMeBtnClick:function () {
19 | app.headerView.search();
20 | }
21 |
22 | });
--------------------------------------------------------------------------------
/web/lib/underscore-min.js:
--------------------------------------------------------------------------------
1 | // Underscore.js 1.3.2
2 | // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
3 | // Underscore is freely distributable under the MIT license.
4 | // Portions of Underscore are inspired or borrowed from Prototype,
5 | // Oliver Steele's Functional, and John Resig's Micro-Templating.
6 | // For all details and documentation:
7 | // http://documentcloud.github.com/underscore
8 | (function(){function r(a,c,d){if(a===c)return 0!==a||1/a==1/c;if(null==a||null==c)return a===c;a._chain&&(a=a._wrapped);c._chain&&(c=c._wrapped);if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return!1;switch(e){case "[object String]":return a==""+c;case "[object Number]":return a!=+a?c!=+c:0==a?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
9 | c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if("object"!=typeof a||"object"!=typeof c)return!1;for(var f=d.length;f--;)if(d[f]==a)return!0;d.push(a);var f=0,g=!0;if("[object Array]"==e){if(f=a.length,g=f==c.length)for(;f--&&(g=f in a==f in c&&r(a[f],c[f],d)););}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return!1;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&r(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,h)&&!f--)break;
10 | g=!f}}d.pop();return g}var s=this,I=s._,o={},k=Array.prototype,p=Object.prototype,i=k.slice,J=k.unshift,l=p.toString,K=p.hasOwnProperty,y=k.forEach,z=k.map,A=k.reduce,B=k.reduceRight,C=k.filter,D=k.every,E=k.some,q=k.indexOf,F=k.lastIndexOf,p=Array.isArray,L=Object.keys,t=Function.prototype.bind,b=function(a){return new m(a)};"undefined"!==typeof exports?("undefined"!==typeof module&&module.exports&&(exports=module.exports=b),exports._=b):s._=b;b.VERSION="1.3.2";var j=b.each=b.forEach=function(a,
11 | c,d){if(a!=null)if(y&&a.forEach===y)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e2;a==null&&(a=[]);if(A&&
12 | a.reduce===A){e&&(c=b.bind(c,e));return f?a.reduce(c,d):a.reduce(c)}j(a,function(a,b,i){if(f)d=c.call(e,d,a,b,i);else{d=a;f=true}});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(B&&a.reduceRight===B){e&&(c=b.bind(c,e));return f?a.reduceRight(c,d):a.reduceRight(c)}var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=function(a,
13 | c,b){var e;G(a,function(a,g,h){if(c.call(b,a,g,h)){e=a;return true}});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(C&&a.filter===C)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(D&&a.every===D)return a.every(c,b);j(a,function(a,g,h){if(!(e=e&&c.call(b,
14 | a,g,h)))return o});return!!e};var G=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(E&&a.some===E)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return o});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;if(q&&a.indexOf===q)return a.indexOf(c)!=-1;return b=G(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=
15 | function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0])return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0])return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;bd?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};
17 | j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1),true);return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=
20 | i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=L||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&
25 | c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.pick=function(a){var c={};j(b.flatten(i.call(arguments,1)),function(b){b in a&&(c[b]=a[b])});return c};b.defaults=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return r(a,b,[])};b.isEmpty=
26 | function(a){if(a==null)return true;if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=function(a){return l.call(a)=="[object Arguments]"};b.isArguments(arguments)||(b.isArguments=function(a){return!(!a||!b.has(a,"callee"))});b.isFunction=function(a){return l.call(a)=="[object Function]"};
27 | b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isFinite=function(a){return b.isNumber(a)&&isFinite(a)};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,
28 | b){return K.call(a,b)};b.noConflict=function(){s._=I;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e /g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.result=function(a,c){if(a==null)return null;var d=a[c];return b.isFunction(d)?d.call(a):d};b.mixin=function(a){j(b.functions(a),function(c){M(c,b[c]=a[c])})};var N=0;b.uniqueId=
29 | function(a){var b=N++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var u=/.^/,n={"\\":"\\","'":"'",r:"\r",n:"\n",t:"\t",u2028:"\u2028",u2029:"\u2029"},v;for(v in n)n[n[v]]=v;var O=/\\|'|\r|\n|\t|\u2028|\u2029/g,P=/\\(\\|'|r|n|t|u2028|u2029)/g,w=function(a){return a.replace(P,function(a,b){return n[b]})};b.template=function(a,c,d){d=b.extend(b.templateSettings,d);a="__p+='"+a.replace(O,function(a){return"\\"+n[a]}).replace(d.escape||
30 | u,function(a,b){return"'+\n_.escape("+w(b)+")+\n'"}).replace(d.interpolate||u,function(a,b){return"'+\n("+w(b)+")+\n'"}).replace(d.evaluate||u,function(a,b){return"';\n"+w(b)+"\n;__p+='"})+"';\n";d.variable||(a="with(obj||{}){\n"+a+"}\n");var a="var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n"+a+"return __p;\n",e=new Function(d.variable||"obj","_",a);if(c)return e(c,b);c=function(a){return e.call(this,a,b)};c.source="function("+(d.variable||"obj")+"){\n"+a+"}";return c};
31 | b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var x=function(a,c){return c?b(a).chain():a},M=function(a,c){m.prototype[a]=function(){var a=i.call(arguments);J.call(a,this._wrapped);return x(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return x(d,
32 | this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return x(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=true;return this};m.prototype.value=function(){return this._wrapped}}).call(this);
33 |
--------------------------------------------------------------------------------
/web/pics/Amy_Jones.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/Amy_Jones.jpg
--------------------------------------------------------------------------------
/web/pics/Amy_Jones50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/Amy_Jones50.jpg
--------------------------------------------------------------------------------
/web/pics/Eugene_Lee.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/Eugene_Lee.jpg
--------------------------------------------------------------------------------
/web/pics/Eugene_Lee50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/Eugene_Lee50.jpg
--------------------------------------------------------------------------------
/web/pics/Gary_Donovan.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/Gary_Donovan.jpg
--------------------------------------------------------------------------------
/web/pics/Gary_Donovan50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/Gary_Donovan50.jpg
--------------------------------------------------------------------------------
/web/pics/James_King.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/James_King.jpg
--------------------------------------------------------------------------------
/web/pics/James_King50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/James_King50.jpg
--------------------------------------------------------------------------------
/web/pics/John_Williams.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/John_Williams.jpg
--------------------------------------------------------------------------------
/web/pics/John_Williams50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/John_Williams50.jpg
--------------------------------------------------------------------------------
/web/pics/Julie_Taylor.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/Julie_Taylor.jpg
--------------------------------------------------------------------------------
/web/pics/Julie_Taylor50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/Julie_Taylor50.jpg
--------------------------------------------------------------------------------
/web/pics/Kathleen_Byrne.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/Kathleen_Byrne.jpg
--------------------------------------------------------------------------------
/web/pics/Kathleen_Byrne50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/Kathleen_Byrne50.jpg
--------------------------------------------------------------------------------
/web/pics/Lisa_Wong.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/Lisa_Wong.jpg
--------------------------------------------------------------------------------
/web/pics/Lisa_Wong50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/Lisa_Wong50.jpg
--------------------------------------------------------------------------------
/web/pics/Paul_Jones.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/Paul_Jones.jpg
--------------------------------------------------------------------------------
/web/pics/Paul_Jones50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/Paul_Jones50.jpg
--------------------------------------------------------------------------------
/web/pics/Paula_Gates.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/Paula_Gates.jpg
--------------------------------------------------------------------------------
/web/pics/Paula_Gates50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/Paula_Gates50.jpg
--------------------------------------------------------------------------------
/web/pics/Ray_Moore.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/Ray_Moore.jpg
--------------------------------------------------------------------------------
/web/pics/Ray_Moore50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/Ray_Moore50.jpg
--------------------------------------------------------------------------------
/web/pics/Steven_Wells.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/Steven_Wells.jpg
--------------------------------------------------------------------------------
/web/pics/Steven_Wells50.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ccoenraets/backbone-directory/c5654ab50002a7865da849fbc743e7cea750a54e/web/pics/Steven_Wells50.jpg
--------------------------------------------------------------------------------
/web/tpl/ContactView.html:
--------------------------------------------------------------------------------
1 | Source Code
2 |
3 | The source code for this application is available in this
4 | repository on GitHub.
5 |
6 | Comments and Questions
7 |
8 | You can post your questions and comments on the blog post associated with this application.
9 |
10 | Related Backbone.js Tutorials
11 |
12 | I also posted a series of Backbone.js tutorials here:
13 | part 1 ,
14 | part 2 ,
15 | part 3 ,
16 | and postface
17 |
18 |
19 |
20 | Thanks,
21 |
22 | Christophe Coenraets
23 | Twitter: @ccoenraets
24 | Blog: http://coenraets.org
--------------------------------------------------------------------------------
/web/tpl/EmployeeListItemView.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%= firstName %> <%= lastName %> <%= title %>
4 |
--------------------------------------------------------------------------------
/web/tpl/EmployeeSummaryView.html:
--------------------------------------------------------------------------------
1 |
2 | <%= firstName %> <%= lastName %>
3 | <%= title %>
4 |
5 |
6 |
7 |
8 |
37 |
38 |
39 |
Warning
40 | The phone numbers, email addresses, and Twitter handlers are fake.
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/web/tpl/EmployeeView.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
Info
8 | <%= firstName %> <%= lastName %> has no direct reports
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/web/tpl/HeaderView.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/tpl/HomeView.html:
--------------------------------------------------------------------------------
1 |
2 |
Welcome to Backbone Directory !
3 |
4 |
5 |
6 |
7 |
8 |
This is a sample app that demonstrates how to build applications
9 | with Backbone.js and Twitter Bootstrap .
11 | Learn more »
12 |
13 |
14 |
15 |
16 |
17 |
18 |
Try It
19 |
20 |
Enter a few characters in the Search Box in the upper right corner of the screen, and select an employee. In
21 | the Employee view, you can navigate up and down the Org Chart by clicking either the Manager link,
22 | or one of the Direct Reports in the sidebar on the right of the screen.
23 |
24 |
Show Me »
25 |
26 |
27 |
Get It
28 |
29 |
The source code for this application is maintained in this repository on GitHub. In addition
31 | to the Backbone.js- and Twitter Bootstrap-powered client, the repository includes two versions of the
32 | back-end services: a Java and a PHP implementation.
33 |
34 |
Download »
35 |
36 |
37 |
Share It
38 |
39 |
If you think this sample is helpful, let other people know about it...
40 |
41 |
42 |
43 |
44 |
45 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
64 |
65 |
66 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------