Version Description
- Update: Confirm compatibility with WordPress 5.0+
- Optimize: Improved support for captions generated by Block Editor.
Download this release
Release Info
Developer | Archetyped |
Plugin | Simple Lightbox |
Version | 2.7.1 |
Comparing to | |
See all releases |
Code changes from version 2.0 to 2.7.1
- .gitignore +1 -0
- Gruntfile.js +49 -0
- assets/screenshot-1.png +0 -0
- assets/screenshot-2.jpg +0 -0
- assets/screenshot-3.jpg +0 -0
- changelog.txt +319 -0
- client/config.rb +0 -24
- client/css/admin.css +1 -1
- client/css/app.css +1 -0
- client/js/{lib.admin.js → dev/lib.admin.js} +5 -9
- client/js/dev/lib.core.js +934 -0
- client/js/{lib.view.js → dev/lib.view.js} +1183 -1129
- client/js/lib.core.js +0 -591
- client/js/prod/lib.admin.js +1 -0
- client/js/prod/lib.core.js +1 -0
- client/js/prod/lib.view.js +1 -0
- client/sass/admin.scss +23 -0
- client/sass/app.scss +10 -0
- content-handlers/image/handler.image.js +0 -29
- content-handlers/image/js/dev/handler.image.js +33 -0
- content-handlers/image/js/prod/handler.image.js +1 -0
- controller.php +1654 -0
- functions.php +24 -0
- grunt/jshint.js +38 -0
- grunt/phplint.js +14 -0
- grunt/sass.js +34 -0
- grunt/uglify.js +21 -0
- grunt/watch.js +57 -0
- includes/class-requirements-check.php +168 -0
- includes/class.admin.php +182 -1097
- includes/class.admin_action.php +109 -0
- includes/class.admin_menu.php +40 -0
- includes/class.admin_page.php +182 -0
- includes/class.admin_section.php +51 -0
- includes/class.admin_view.php +529 -0
- includes/class.base.php +96 -64
- includes/class.base_collection.php +33 -33
- includes/class.base_object.php +71 -11
- includes/class.component.php +72 -26
- includes/class.content_handler.php +27 -2
- includes/class.content_handlers.php +86 -37
- includes/class.field.php +2 -0
- includes/class.field_base.php +1048 -0
- includes/class.field_collection.php +764 -0
- includes/class.field_type.php +405 -0
- includes/class.fields.php +59 -2237
- includes/class.option.php +179 -0
- includes/class.options.php +229 -261
- includes/class.template_tags.php +43 -22
- includes/class.theme.php +22 -16
- includes/class.themes.php +127 -56
- includes/class.utilities.php +552 -592
- l10n/simple-lightbox.pot +151 -109
- load.php +38 -0
- main.php +39 -48
- model.php +0 -1097
- package-lock.json +2941 -0
- package.json +20 -0
- readme.txt +30 -152
- template-tags/item/js/dev/tag.item.js +26 -0
- template-tags/item/js/prod/tag.item.js +1 -0
- template-tags/item/tag.item.js +0 -17
- template-tags/ui/js/dev/tag.ui.js +105 -0
- template-tags/ui/js/prod/tag.ui.js +1 -0
- template-tags/ui/tag.ui.js +0 -108
- themes/baseline/css/style.css +1 -0
- themes/baseline/images/loading.gif +0 -0
- themes/baseline/js/dev/client.js +37 -0
- themes/baseline/js/prod/client.js +1 -0
- themes/{default → baseline}/layout.html +22 -14
- themes/baseline/sass/style.scss +176 -0
- themes/black/config.rb +0 -23
- themes/black/css/style.css +1 -1
- themes/black/sass/style.scss +10 -7
- themes/default/client.js +0 -202
- themes/default/config.rb +0 -23
- themes/default/css/style.css +1 -1
- themes/default/fonts/OFL.txt +97 -0
- themes/default/fonts/yanone-kaffeesatz-v9-latin-regular.eot +0 -0
- themes/default/fonts/yanone-kaffeesatz-v9-latin-regular.svg +407 -0
- themes/default/fonts/yanone-kaffeesatz-v9-latin-regular.ttf +0 -0
- themes/default/fonts/yanone-kaffeesatz-v9-latin-regular.woff +0 -0
- themes/default/fonts/yanone-kaffeesatz-v9-latin-regular.woff2 +0 -0
- themes/default/js/dev/client.js +184 -0
- themes/default/js/prod/client.js +1 -0
- themes/default/sass/_fonts.scss +13 -0
- themes/default/sass/style.scss +77 -180
.gitignore
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
.vscode
|
Gruntfile.js
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module.exports = function(grunt) {
|
2 |
+
// Load tasks
|
3 |
+
require('load-grunt-tasks')(grunt);
|
4 |
+
// Display task timing
|
5 |
+
require('time-grunt')(grunt);
|
6 |
+
// Project configuration.
|
7 |
+
grunt.initConfig({
|
8 |
+
// Metadata
|
9 |
+
pkg : grunt.file.readJSON('package.json'),
|
10 |
+
// Variables
|
11 |
+
paths : {
|
12 |
+
// Base dir assets dir
|
13 |
+
base : 'client',
|
14 |
+
|
15 |
+
// PHP assets
|
16 |
+
php : {
|
17 |
+
files_std : ['*.php', '**/*.php', '!node_modules/**/*.php'], // Standard file match
|
18 |
+
files : '<%= paths.php.files_std %>' // Dynamic file match
|
19 |
+
},
|
20 |
+
|
21 |
+
// JavaScript assets
|
22 |
+
js : {
|
23 |
+
base : 'js', // Base dir
|
24 |
+
src : '<%= paths.js.base %>/dev', // Development code
|
25 |
+
dest : '<%= paths.js.base %>/prod', // Production code
|
26 |
+
files_std : '**/<%= paths.js.src %>/**/*.js', // Standard file match
|
27 |
+
files : '<%= paths.js.files_std %>' // Dynamic file match
|
28 |
+
},
|
29 |
+
|
30 |
+
// Sass assets
|
31 |
+
sass : {
|
32 |
+
src : 'sass', // Source files dir
|
33 |
+
dest : 'css', // Compiled files dir
|
34 |
+
ext : '.css', // Compiled extension
|
35 |
+
target : '*.scss', // Only Sass files in CWD
|
36 |
+
exclude : '!_*.scss', // Do not process partials
|
37 |
+
base_src : '<%= paths.base %>/<%= paths.sass.src %>', // Base source dir
|
38 |
+
base_dest : '<%= paths.base %>/<%= paths.sass.dest %>', // Base compile dir
|
39 |
+
}
|
40 |
+
},
|
41 |
+
});
|
42 |
+
|
43 |
+
// Load task configurations
|
44 |
+
grunt.loadTasks('grunt');
|
45 |
+
|
46 |
+
// Default Tasks
|
47 |
+
grunt.registerTask('build', ['phplint', 'jshint:all', 'uglify', 'sass']);
|
48 |
+
grunt.registerTask('watch_all', ['watch:js', 'watch:sass']);
|
49 |
+
};
|
assets/screenshot-1.png
DELETED
Binary file
|
assets/screenshot-2.jpg
DELETED
Binary file
|
assets/screenshot-3.jpg
DELETED
Binary file
|
changelog.txt
ADDED
@@ -0,0 +1,319 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
= 2.7.0 =
|
2 |
+
|
3 |
+
* Fix: Remove reference to deprecated `screen_icon()` function (The Icon of Finnegan Island)
|
4 |
+
* Add: Validate requirements before initialization.
|
5 |
+
* Optimize: PHP 7.2+ Compatibility
|
6 |
+
* Optimize: Internal code optimizations
|
7 |
+
* Themes
|
8 |
+
* Add: RTL Support
|
9 |
+
* Update: Load font locally
|
10 |
+
|
11 |
+
= 2.6.0 =
|
12 |
+
|
13 |
+
* Add: Activate links in native WordPress navigation menus (enable in admin settings)
|
14 |
+
* Add: Group menu links separately (enable in admin settings)
|
15 |
+
* Optimize: Fallback lightbox title text retrieval (link text)
|
16 |
+
* Fix: Undefined variable in `Utilities::get_plugin_base_file()` (The Lost Temple of Xavivars)
|
17 |
+
|
18 |
+
= 2.5.3 =
|
19 |
+
|
20 |
+
* Optimize: Entity handling in URIs for different server environments
|
21 |
+
|
22 |
+
= 2.5.2 =
|
23 |
+
|
24 |
+
* Fix: Activation when Home page set to static page (Lyra's Static Cling)
|
25 |
+
* Optimize: Prep for WordPress language packs
|
26 |
+
|
27 |
+
= 2.5.1 =
|
28 |
+
|
29 |
+
* Update: Client-side Utilities library
|
30 |
+
* Optimize: Request processing
|
31 |
+
|
32 |
+
= 2.5.0 =
|
33 |
+
|
34 |
+
* Fix: Query string removed from URI (A Stern Query)
|
35 |
+
* Optimize: Key-based asset data storage/retrieval
|
36 |
+
* Optimize: Improved cache usage when processing links
|
37 |
+
* Optimize: Refactor image URI detection
|
38 |
+
|
39 |
+
= 2.4.1 =
|
40 |
+
|
41 |
+
* Fix: Ungrouped items in empty group (Robert & The Lost Group)
|
42 |
+
* Fix: IE8 Support (S.Franzis' Legacy)
|
43 |
+
* Optimize: Widget support
|
44 |
+
* Optimize: Relative and internal URI handling
|
45 |
+
* Optimize: Link activation performance
|
46 |
+
|
47 |
+
= 2.4.0 =
|
48 |
+
|
49 |
+
* Update: WordPress version compatibility (v4.2.1)
|
50 |
+
* Optimize: Standardize code
|
51 |
+
* Optimize: Do not process excerpt content
|
52 |
+
* Optimize: Client-side libraries (Phase 1)
|
53 |
+
* Add: Set group via `slb_activate()`
|
54 |
+
* Add: Set group via `activate_links()`
|
55 |
+
* Add: `slb_is_enabled` filter
|
56 |
+
|
57 |
+
= 2.3.1 =
|
58 |
+
|
59 |
+
* Fix: WordPress version requirement
|
60 |
+
* Optimize: Field collection group parsing
|
61 |
+
|
62 |
+
= 2.3.0 =
|
63 |
+
[Full Release Notes](http://archetyped.com/lab/slb-2-3-0 "Simple Lightbox 2.3.0")
|
64 |
+
|
65 |
+
* Update: WordPress 3.9 support
|
66 |
+
* Update: Support URI, content
|
67 |
+
* Add: Enhanced grouping support
|
68 |
+
* Add: Shortcode: `[slb_group]`
|
69 |
+
* Add: Shortcode: `[slb_exclude]`
|
70 |
+
* Add: Filter: `slb_pre_process_links`
|
71 |
+
* Add: Filter: `slb_post_process_links`
|
72 |
+
* Add: Filter: `slb_process_link_attributes`
|
73 |
+
* Add: Filter: `slb_media_item_properties`
|
74 |
+
* Add: Filter: `slb_pre_exclude_content`
|
75 |
+
* Add: Filter: `slb_exclude_shortcodes`
|
76 |
+
* Add: Filter: `slb_group_shortcodes`
|
77 |
+
* Add: Template Tag: `slb_activate()` - Manually activate content
|
78 |
+
* Add: Option to enable/disable usage of WordPress-generated media title
|
79 |
+
* Add: Dev mode
|
80 |
+
* Add: Theme breakpoints
|
81 |
+
* Optimize: Remove deprecated code
|
82 |
+
* Optimize: Remove deprecated legacy support
|
83 |
+
* Optimize: Content exclusion performance
|
84 |
+
* Optimize: Content grouping performance
|
85 |
+
* Optimize: Harden code against third-party post query modifications
|
86 |
+
* Optimize: Utility code
|
87 |
+
* Optimize: Loading process
|
88 |
+
* Optimize: Client-side code
|
89 |
+
* Optimize: Client-side: Code loading
|
90 |
+
* Optimize: Client-side: Simplified dependency detection
|
91 |
+
* Optimize: Client-side: Default Theme transitions
|
92 |
+
* Optimize: Grunt: Cleanup
|
93 |
+
* Optimize: Grunt: Path abstraction
|
94 |
+
* Optimize: Grunt: Task loading
|
95 |
+
* Optimize: Grunt: Selective file compilation
|
96 |
+
|
97 |
+
= 2.2.2 =
|
98 |
+
|
99 |
+
* Optimize: Widget processing
|
100 |
+
* Optimize: Remove call-time-pass-by-references
|
101 |
+
|
102 |
+
= 2.2.1 =
|
103 |
+
|
104 |
+
* Fix: Enable/Disable lightbox on certain requests (Danny the Enabler)
|
105 |
+
* Fix: Widget links grouped with post links (Rafa's Widgetarian Adventure)
|
106 |
+
* Optimize: Client-side loading
|
107 |
+
* Optimize: Theme validation
|
108 |
+
* Optimize: Widget processing
|
109 |
+
|
110 |
+
= 2.2.0 =
|
111 |
+
|
112 |
+
* Update: WordPress 3.8 support
|
113 |
+
* Add: Add-on support
|
114 |
+
* Add: Load external data for item
|
115 |
+
* Add: Unloading process for viewer
|
116 |
+
* Add: Relative links marked as "internal"
|
117 |
+
* Add: Grunt build workflow
|
118 |
+
* Optimize: Initialization process
|
119 |
+
* Optimize: Client-side output (JavaScript, CSS)
|
120 |
+
* Optimize: Improved URI handling (variants, query strings, etc.)
|
121 |
+
* Optimize: Improved support for content types (video, etc.)
|
122 |
+
* Optimize: Improved File contents retrieval
|
123 |
+
* Optimize: Plugin metadata cleanup
|
124 |
+
* Optimize: Use absolute paths for file includes (props k3davis)
|
125 |
+
|
126 |
+
= 2.1.3 =
|
127 |
+
|
128 |
+
* Fix: PHP configuration issue on some web hosts (Tim's got (config) issues)
|
129 |
+
* Optimize: Hide overlapping elements when lightbox is displayed (e.g. Flash, etc.)
|
130 |
+
|
131 |
+
= 2.1.2 =
|
132 |
+
|
133 |
+
* Fix: Incorrect paths when WP in subdirectory (Kim's Van Repair)
|
134 |
+
|
135 |
+
= 2.1.1 =
|
136 |
+
|
137 |
+
* Fix: Automatic resizing
|
138 |
+
* Fix: Compatibility with non-standard wp-content location (On the Path of the Wijdemans)
|
139 |
+
* Optimize: jQuery dependency handling
|
140 |
+
* Optimize: Plugin initialization
|
141 |
+
* Optimize: Deferred component stylesheet loading
|
142 |
+
* Optimize: Code cleanup
|
143 |
+
|
144 |
+
= 2.1 =
|
145 |
+
|
146 |
+
* Update: Finalized Theme API
|
147 |
+
* Update: Finalized Content Handler API
|
148 |
+
* Update: Finalized Template Tag API
|
149 |
+
* Update: Administration framework
|
150 |
+
* Add: Baseline theme
|
151 |
+
* Add: Hook for extending image link matching
|
152 |
+
* Optimize: Link validation
|
153 |
+
* Optimize: Intelligent client-side loading
|
154 |
+
* Optimize: Server-side processing
|
155 |
+
* Optimize: Default theme display
|
156 |
+
* Fix: False positive link activation (What's eating Gilbert's links?)
|
157 |
+
* Fix: Gallery post format compatibility (Just Juan problem with galleries)
|
158 |
+
|
159 |
+
= 2.0 =
|
160 |
+
|
161 |
+
* Completely rewritten lightbox code
|
162 |
+
* Add: Automatically resize lightbox to fit window
|
163 |
+
* Add: APIs for third-party add-ons
|
164 |
+
* Add: Flexible theme support
|
165 |
+
* Add: Flexible content handler support
|
166 |
+
* Add: Mobile-optimized responsive themes (2)
|
167 |
+
* Optimize: PHP class autoloading
|
168 |
+
* Optimize: Improved performance and compatibility
|
169 |
+
* Optimize: Full internationalization support
|
170 |
+
|
171 |
+
= 1.6 =
|
172 |
+
|
173 |
+
* Add: Widget support
|
174 |
+
* Add: WordPress 3.3 support
|
175 |
+
* Add: Localization support
|
176 |
+
* Add: Option to group gallery links separately (supports WordPress & NextGen galleries)
|
177 |
+
* Add: Upgrade notice
|
178 |
+
* Optimize: WP 3.3 compatibility
|
179 |
+
* Optimize: Improved compatibility with URI case-sensitivity
|
180 |
+
* Optimize: Activation processing
|
181 |
+
* Optimize: Image grouping
|
182 |
+
* Optimize: Image metadata loading performance
|
183 |
+
* Optimize: File loading
|
184 |
+
* Optimize: Improved safeguards against interference by bugs in other plugins
|
185 |
+
* Optimize: Link processing performance
|
186 |
+
* Optimize: Lightbox styling isolated from site styles
|
187 |
+
* Optimize: Improved link processing performance
|
188 |
+
* Optimize: Improved image metadata support
|
189 |
+
* Optimize: Improved support for HTTP/HTTPS requests
|
190 |
+
* Fix: SLB is not defined in JS (Jezz Hands)
|
191 |
+
* Fix: Boolean case-sensitivity (78 Truths)
|
192 |
+
* Fix: YouTube embed using iFrame overlaps lightbox (Elena in Hiding)
|
193 |
+
* Fix: Issue when scanning links without valid URLs (McCloskey Iteration)
|
194 |
+
* Fix: Image activation is case-sensitive (Sensitive Tanya)
|
195 |
+
* Fix: Visible lightbox overlay edges when image larger than browser window (Chibi Overlay)
|
196 |
+
* Fix: Options availability for some users
|
197 |
+
* Fix: Inconsistent loading of image metadata
|
198 |
+
* Fix: Links not fully processed when group is set manually
|
199 |
+
|
200 |
+
= 1.5.6 =
|
201 |
+
|
202 |
+
* Add: Display image description in lightbox (with HTML support)
|
203 |
+
* Add: Support for W3 Total Cache plugin
|
204 |
+
* Add: Initial support for NextGEN galleries
|
205 |
+
* Update: **Important:** [System Requirements](http://wordpress.org/about/requirements/) aligned with WP 3.2.1
|
206 |
+
* Optimize: Improved support for small images in default template
|
207 |
+
* Optimize: Support for non-English text in user options
|
208 |
+
* Optimize: Improved IE compatibility
|
209 |
+
* Optimize: Improved data handling
|
210 |
+
* Optimize: Skin loading performance
|
211 |
+
* Optimize: Skin CSS Cleanup
|
212 |
+
* Optimize: Caption support for galleries
|
213 |
+
* Optimize: Options code cleanup (Juga Sweep)
|
214 |
+
* Fix: User-defined UI text not used (Ivan gets Even (cooler))
|
215 |
+
* Fix: Options reset after update (KRazy Donna)
|
216 |
+
|
217 |
+
= 1.5.5.1 =
|
218 |
+
|
219 |
+
* Fix: Disabled links not being disabled (Disabling Sascha)
|
220 |
+
|
221 |
+
= 1.5.5 =
|
222 |
+
|
223 |
+
* Add: Distinct link activation (will not affect other lightboxes)
|
224 |
+
* Add: Backwards compatibility with legacy lightbox links (optional)
|
225 |
+
* Add: Support for WordPress 3.2
|
226 |
+
* Add: Support for links added after page load (e.g. via AJAX, etc.)
|
227 |
+
* Add: Admin option to enable/disable attachment links
|
228 |
+
* Add: Support for image attachment links
|
229 |
+
* Update: Options management overhaul
|
230 |
+
* Update: Additional WordPress 3.2 support (Gallery)
|
231 |
+
* Update: Cache-management for enqueued files
|
232 |
+
* Update: Improved UI consistency
|
233 |
+
* Update: Improved compatibility for older versions of PHP
|
234 |
+
* Update: Internal optimizations
|
235 |
+
* Update: Improved URL handling
|
236 |
+
* Fix: Improved options migration from old versions (Hutchison Migration)
|
237 |
+
* Fix: XHTML Validation (Hajo Validation)
|
238 |
+
|
239 |
+
= 1.5.4 =
|
240 |
+
|
241 |
+
* Add: Optional Link validation
|
242 |
+
* Add: Keyboard Navigation
|
243 |
+
* Add: Option to enable/disable image caption
|
244 |
+
* Add: `rel` attribute supported again
|
245 |
+
* Add: Use `slb_off` in link's `rel` attribute to disable automatic activation for link
|
246 |
+
* Fix: HTTPS compatibility (Jürgen Protocol)
|
247 |
+
* Fix: Enabling SLB on Pages issue
|
248 |
+
* Fix: Zmanu is_single
|
249 |
+
* Fix: Image order is sometimes incorrect
|
250 |
+
* Optimize: Filter double clicks
|
251 |
+
* Optimize: Separate options to enable/disable SLB on Posts and Pages
|
252 |
+
* Optimize: Better grouping support
|
253 |
+
|
254 |
+
= 1.5.3 =
|
255 |
+
|
256 |
+
* Fix: Caption may not display under certain circumstances (Caption Erin)
|
257 |
+
* Fix: Images not grouped when "separate by post" option is activated (Logical Ross)
|
258 |
+
* Update: Lightbox will not be activated for links that already have `rel` attribute set
|
259 |
+
|
260 |
+
= 1.5.2 =
|
261 |
+
|
262 |
+
* Fix: Slideshow loops out of control (Mirage of Wallentin)
|
263 |
+
* Fix: Lightbox fails when group by posts disabled (Lange Find)
|
264 |
+
* Add: Option to use the image's URI as caption when link title not set (Under UI options)
|
265 |
+
|
266 |
+
= 1.5.1 =
|
267 |
+
|
268 |
+
* Add: WP Gallery support
|
269 |
+
* Fix: Navigation hidden when only one image
|
270 |
+
* Fix: Use user-defined UI text
|
271 |
+
|
272 |
+
= 1.5 =
|
273 |
+
|
274 |
+
* Add: Theme support
|
275 |
+
* Optimize: JavaScript cleanup and file size reductions
|
276 |
+
* Optimize: CSS cleanup
|
277 |
+
|
278 |
+
= 1.4 =
|
279 |
+
|
280 |
+
* Update: Integrated with jQuery
|
281 |
+
* Optimize: JavaScript file size 9x smaller
|
282 |
+
* Add: Close lightbox by clicking to left/right outside of image (an oft-requested feature)
|
283 |
+
|
284 |
+
= 1.3.2 =
|
285 |
+
|
286 |
+
* Add: Option to enable/disable lightbox resizing animation (thanks Maria!)
|
287 |
+
|
288 |
+
= 1.3.1 =
|
289 |
+
|
290 |
+
* Update: Utilities code (internal)
|
291 |
+
|
292 |
+
= 1.3 =
|
293 |
+
|
294 |
+
* Add: Customizable UI label text (close, next, and previous button images can be replaced in `images` directory)
|
295 |
+
* Add: Group image links by Post (separate slideshow for each post)
|
296 |
+
* Add: Reset settings link on plugin listings page
|
297 |
+
* Optimize: Organized settings page
|
298 |
+
|
299 |
+
= 1.2.1 =
|
300 |
+
|
301 |
+
* Fixed: Image title given higher precedence than Image alt (more compatible w/WP workflow)
|
302 |
+
|
303 |
+
= 1.2 =
|
304 |
+
|
305 |
+
* Added: Option to group automatically activated links
|
306 |
+
* Optimized: Lightbox caption retrieval
|
307 |
+
|
308 |
+
= 1.1 =
|
309 |
+
|
310 |
+
* Added: Enable/disable lightbox functionality by page type (Home, Pages/Posts, Archive, etc.)
|
311 |
+
* Added: Automatically activate lightbox functionality for image links
|
312 |
+
* Added: Link to settings menu on plugin listing page
|
313 |
+
* Optimized: Options menu field building
|
314 |
+
* Optimized: Loading of default values for plugin options
|
315 |
+
* Optimized: General code optimizations
|
316 |
+
|
317 |
+
= 1.0 =
|
318 |
+
|
319 |
+
* Initial release
|
client/config.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1 |
-
# Require any additional compass plugins here.
|
2 |
-
|
3 |
-
# Set this to the root of your project when deployed:
|
4 |
-
http_path = "/"
|
5 |
-
css_dir = "css"
|
6 |
-
sass_dir = "sass"
|
7 |
-
images_dir = "images"
|
8 |
-
javascripts_dir = "js"
|
9 |
-
|
10 |
-
# You can select your preferred output style here (can be overridden via the command line):
|
11 |
-
output_style = :compressed
|
12 |
-
|
13 |
-
# To enable relative paths to assets via compass helper functions. Uncomment:
|
14 |
-
# relative_assets = true
|
15 |
-
|
16 |
-
# To disable debugging comments that display the original location of your selectors. Uncomment:
|
17 |
-
# line_comments = false
|
18 |
-
|
19 |
-
|
20 |
-
# If you prefer the indented syntax, you might want to regenerate this
|
21 |
-
# project again passing --syntax sass, or you can uncomment this:
|
22 |
-
# preferred_syntax = :sass
|
23 |
-
# and then run:
|
24 |
-
# sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
client/css/admin.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.slb_section_head{display:block;padding:2em 0 0}.slb_option_item .block{display:inline-block}.slb_option_item label.title{width:200px;padding:10px}.slb_option_item .input{font-size:11px;line-height:20px;margin-bottom:9px;padding:8px 10px}.slb_option_item .input select{min-width:12em}.slb_notice{color:#f00;font-weight:bold}
|
1 |
+
.slb_section_head{display:block;padding:2em 0 0}.slb_option_item .block{display:inline-block}.slb_option_item label.title{width:200px;padding:10px}.slb_option_item .input{font-size:11px;line-height:20px;margin-bottom:9px;padding:8px 10px}.slb_option_item .input select{min-width:12em}.slb_notice{color:#f00;font-weight:bold}.slb .columns-2{margin-right:300px}.slb .columns-2 .postbox-container{float:left;width:100%}.slb .columns-2 .content-secondary{margin-right:-300px;width:280px;float:right}.slb_admin_action_reset{color:#a00}.slb_admin_action_reset:hover{color:#dc3232;border:none}
|
client/css/app.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
html.slb_overlay object,html.slb_overlay embed,html.slb_overlay iframe{visibility:hidden}html.slb_overlay #slb_viewer_wrap object,html.slb_overlay #slb_viewer_wrap embed,html.slb_overlay #slb_viewer_wrap iframe{visibility:visible}
|
client/js/{lib.admin.js → dev/lib.admin.js}
RENAMED
@@ -5,13 +5,11 @@
|
|
5 |
* @author Archetyped
|
6 |
*/
|
7 |
|
8 |
-
|
9 |
|
10 |
-
if (
|
11 |
-
return false;
|
12 |
-
}
|
13 |
|
14 |
-
|
15 |
/**
|
16 |
* Initialization routines
|
17 |
*/
|
@@ -20,12 +18,10 @@ var Admin = {
|
|
20 |
postboxes.add_postbox_toggles(pagenow);
|
21 |
}
|
22 |
},
|
23 |
-
}
|
24 |
-
|
25 |
-
SLB.attach('Admin', Admin);
|
26 |
|
27 |
$(document).ready(function() {
|
28 |
SLB.Admin.init();
|
29 |
});
|
30 |
|
31 |
-
})(jQuery);
|
5 |
* @author Archetyped
|
6 |
*/
|
7 |
|
8 |
+
/* global SLB, postboxes, pagenow */
|
9 |
|
10 |
+
if ( !!window.SLB && !!SLB.attach ) { (function ($) {
|
|
|
|
|
11 |
|
12 |
+
SLB.attach('Admin', {
|
13 |
/**
|
14 |
* Initialization routines
|
15 |
*/
|
18 |
postboxes.add_postbox_toggles(pagenow);
|
19 |
}
|
20 |
},
|
21 |
+
});
|
|
|
|
|
22 |
|
23 |
$(document).ready(function() {
|
24 |
SLB.Admin.init();
|
25 |
});
|
26 |
|
27 |
+
})(jQuery);}
|
client/js/dev/lib.core.js
ADDED
@@ -0,0 +1,934 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Core
|
3 |
+
* @package SLB
|
4 |
+
* @author Archetyped
|
5 |
+
*/
|
6 |
+
if ( window.jQuery ){(function($) {
|
7 |
+
'use strict';
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Extendible class
|
11 |
+
* Adapted from John Resig
|
12 |
+
* @link http://ejohn.org/blog/simple-javascript-inheritance/
|
13 |
+
*/
|
14 |
+
var c_init = false;
|
15 |
+
var Class = function() {};
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Create class that extends another class
|
19 |
+
* @param object members Child class' properties
|
20 |
+
* @return function New class
|
21 |
+
*/
|
22 |
+
Class.extend = function(members) {
|
23 |
+
var _super = this.prototype;
|
24 |
+
|
25 |
+
// Copy instance to prototype
|
26 |
+
c_init = true;
|
27 |
+
var proto = new this();
|
28 |
+
c_init = false;
|
29 |
+
|
30 |
+
var val, name;
|
31 |
+
// Scrub prototype objects (Decouple from super class)
|
32 |
+
for ( name in proto ) {
|
33 |
+
if ( $.isPlainObject(proto[name]) ) {
|
34 |
+
val = $.extend({}, proto[name]);
|
35 |
+
proto[name] = val;
|
36 |
+
}
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Create class method with access to super class method
|
41 |
+
* @param string nm Method name
|
42 |
+
* @param function fn Class method
|
43 |
+
* @return function Class method with access to super class method
|
44 |
+
*/
|
45 |
+
var make_handler = function(nm, fn) {
|
46 |
+
return function() {
|
47 |
+
// Cache super variable
|
48 |
+
var tmp = this._super;
|
49 |
+
// Set variable to super class method
|
50 |
+
this._super = _super[nm];
|
51 |
+
// Call method
|
52 |
+
var ret = fn.apply(this, arguments);
|
53 |
+
// Restore super variable
|
54 |
+
this._super = tmp;
|
55 |
+
// Return value
|
56 |
+
return ret;
|
57 |
+
};
|
58 |
+
};
|
59 |
+
// Copy properties to Class
|
60 |
+
for ( name in members ) {
|
61 |
+
// Add access to super class method to methods
|
62 |
+
if ( 'function' === typeof members[name] && 'function' === typeof _super[name] ) {
|
63 |
+
proto[name] = make_handler(name, members[name]);
|
64 |
+
} else {
|
65 |
+
// Transfer properties
|
66 |
+
// Objects are copied, not referenced
|
67 |
+
proto[name] = ( $.isPlainObject(members[name]) ) ? $.extend({}, members[name]) : members[name];
|
68 |
+
}
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Class constructor
|
73 |
+
* Supports pre-construction initilization (`Class._init()`)
|
74 |
+
* Supports passing constructor for new classes (`Class._c()`)
|
75 |
+
*/
|
76 |
+
function Class() {
|
77 |
+
if ( !c_init ) {
|
78 |
+
// Private initialization
|
79 |
+
if ( 'function' === typeof this._init ) {
|
80 |
+
this._init.apply(this, arguments);
|
81 |
+
}
|
82 |
+
// Main Constructor
|
83 |
+
if ( 'function' === typeof this._c ) {
|
84 |
+
this._c.apply(this, arguments);
|
85 |
+
}
|
86 |
+
}
|
87 |
+
}
|
88 |
+
|
89 |
+
|
90 |
+
// Populate new prototype
|
91 |
+
Class.prototype = proto;
|
92 |
+
|
93 |
+
// Set constructor
|
94 |
+
Class.prototype.constructor = Class;
|
95 |
+
|
96 |
+
// Set extender
|
97 |
+
Class.extend = this.extend;
|
98 |
+
|
99 |
+
// Return function
|
100 |
+
return Class;
|
101 |
+
};
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Base Class
|
105 |
+
*/
|
106 |
+
var Base = {
|
107 |
+
/* Properties */
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Base object flag
|
111 |
+
* @var bool
|
112 |
+
*/
|
113 |
+
base: false,
|
114 |
+
/**
|
115 |
+
* Instance parent
|
116 |
+
* @var object
|
117 |
+
*/
|
118 |
+
_parent: null,
|
119 |
+
/**
|
120 |
+
* Class prefix
|
121 |
+
* @var string
|
122 |
+
*/
|
123 |
+
prefix: 'slb',
|
124 |
+
|
125 |
+
/* Methods */
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Constructor
|
129 |
+
* Sets instance parent
|
130 |
+
*/
|
131 |
+
_init: function() {
|
132 |
+
this._set_parent();
|
133 |
+
},
|
134 |
+
|
135 |
+
/**
|
136 |
+
* Set instance parent
|
137 |
+
* Set utilities parent to current instance
|
138 |
+
* @param obj p Parent instance
|
139 |
+
*/
|
140 |
+
_set_parent: function(p) {
|
141 |
+
if ( this.util.is_set(p) ) {
|
142 |
+
this._parent = p;
|
143 |
+
}
|
144 |
+
this.util._parent = this;
|
145 |
+
},
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Attach new member to instance
|
149 |
+
* Member can be property (value) or method
|
150 |
+
* @param string name Member name
|
151 |
+
* @param object data Member data
|
152 |
+
* @param bool simple (optional) Save new member as data object or new class instance (Default: new instance)
|
153 |
+
* @return obj Attached object
|
154 |
+
*/
|
155 |
+
attach: function(member, data, simple) {
|
156 |
+
var ret = data;
|
157 |
+
// Validate
|
158 |
+
simple = ( typeof simple === 'undefined' ) ? false : !!simple;
|
159 |
+
// Add member to instance
|
160 |
+
if ( 'string' === $.type(member) ) {
|
161 |
+
// Prepare member value
|
162 |
+
if ( $.isPlainObject(data) && !simple ) {
|
163 |
+
// Set parent reference for attached instance
|
164 |
+
data['_parent'] = this;
|
165 |
+
// Define new class
|
166 |
+
data = this.Class.extend(data);
|
167 |
+
}
|
168 |
+
// Save member to current instance
|
169 |
+
// Initialize new instance if data is a class
|
170 |
+
this[member] = ( 'function' === $.type(data) ) ? new data() : data;
|
171 |
+
ret = this[member];
|
172 |
+
}
|
173 |
+
return ret;
|
174 |
+
},
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Check for child object
|
178 |
+
* Child object can be multi-level (e.g. Child.Level2child.Level3child)
|
179 |
+
*
|
180 |
+
* @param string child Name of child object
|
181 |
+
*/
|
182 |
+
has_child: function(child) {
|
183 |
+
// Validate
|
184 |
+
if ( !this.util.is_string(child) ) {
|
185 |
+
return false;
|
186 |
+
}
|
187 |
+
|
188 |
+
var children = child.split('.');
|
189 |
+
child = null;
|
190 |
+
var o = this;
|
191 |
+
var x;
|
192 |
+
for ( x = 0; x < children.length; x++ ) {
|
193 |
+
child = children[x];
|
194 |
+
if ( "" === child ) {
|
195 |
+
continue;
|
196 |
+
}
|
197 |
+
if ( this.util.is_obj(o) && o[child] ) {
|
198 |
+
o = o[child];
|
199 |
+
} else {
|
200 |
+
return false;
|
201 |
+
}
|
202 |
+
}
|
203 |
+
return true;
|
204 |
+
},
|
205 |
+
|
206 |
+
/**
|
207 |
+
* Check if instance is set as a base
|
208 |
+
* @uses base
|
209 |
+
* @return bool TRUE if object is set as a base
|
210 |
+
*/
|
211 |
+
is_base: function() {
|
212 |
+
return !!this.base;
|
213 |
+
},
|
214 |
+
|
215 |
+
/**
|
216 |
+
* Get parent instance
|
217 |
+
* @uses `Base._parent` property
|
218 |
+
* @return obj Parent instance
|
219 |
+
*/
|
220 |
+
get_parent: function() {
|
221 |
+
var p = this._parent;
|
222 |
+
// Validate
|
223 |
+
if ( !p ) {
|
224 |
+
this._parent = {};
|
225 |
+
}
|
226 |
+
return this._parent;
|
227 |
+
}
|
228 |
+
};
|
229 |
+
|
230 |
+
/**
|
231 |
+
* Utility methods
|
232 |
+
*/
|
233 |
+
var Utilities = {
|
234 |
+
/* Properties */
|
235 |
+
|
236 |
+
_base: null,
|
237 |
+
_parent: null,
|
238 |
+
|
239 |
+
/* Methods */
|
240 |
+
|
241 |
+
/* Connections */
|
242 |
+
|
243 |
+
/**
|
244 |
+
* Get base ancestor
|
245 |
+
* @return obj Base ancestor
|
246 |
+
*/
|
247 |
+
get_base: function() {
|
248 |
+
if ( !this._base ) {
|
249 |
+
var p = this.get_parent();
|
250 |
+
var p_prev = null;
|
251 |
+
var methods = ['is_base', 'get_parent'];
|
252 |
+
// Find base ancestor
|
253 |
+
// Either oldest ancestor or object explicitly set as a base
|
254 |
+
while ( ( p_prev !== p ) && this.is_method(p, methods) && !p.is_base() ) {
|
255 |
+
// Save previous parent
|
256 |
+
p_prev = p;
|
257 |
+
// Get new parent
|
258 |
+
p = p.get_parent();
|
259 |
+
}
|
260 |
+
// Set base
|
261 |
+
this._base = p;
|
262 |
+
}
|
263 |
+
return this._base;
|
264 |
+
},
|
265 |
+
|
266 |
+
/**
|
267 |
+
* Get parent object or parent property value
|
268 |
+
* @param string prop (optional) Property to retrieve
|
269 |
+
* @return obj Parent object or property value
|
270 |
+
*/
|
271 |
+
get_parent: function(prop) {
|
272 |
+
var ret = this._parent;
|
273 |
+
// Validate
|
274 |
+
if ( !ret ) {
|
275 |
+
// Set default parent value
|
276 |
+
ret = this._parent = {};
|
277 |
+
}
|
278 |
+
// Get parent property
|
279 |
+
if ( this.is_string(prop) ) {
|
280 |
+
ret = ( this.in_obj(ret, prop) ) ? ret[prop] : null;
|
281 |
+
}
|
282 |
+
return ret;
|
283 |
+
},
|
284 |
+
|
285 |
+
/* Prefix */
|
286 |
+
|
287 |
+
/**
|
288 |
+
* Retrieve valid separator
|
289 |
+
* If supplied argument is not a valid separator, use default separator
|
290 |
+
* @param string (optional) sep Separator text
|
291 |
+
* @return string Separator text
|
292 |
+
*/
|
293 |
+
get_sep: function(sep) {
|
294 |
+
var sep_default = '_';
|
295 |
+
return ( this.is_string(sep, false) ) ? sep : sep_default;
|
296 |
+
},
|
297 |
+
|
298 |
+
/**
|
299 |
+
* Retrieve prefix
|
300 |
+
* @return string Prefix
|
301 |
+
*/
|
302 |
+
get_prefix: function() {
|
303 |
+
var p = this.get_parent('prefix');
|
304 |
+
return ( this.is_string(p, false) ) ? p : '';
|
305 |
+
},
|
306 |
+
|
307 |
+
/**
|
308 |
+
* Check if string is prefixed
|
309 |
+
*/
|
310 |
+
has_prefix: function(val, sep) {
|
311 |
+
return ( this.is_string(val) && 0 === val.indexOf(this.get_prefix() + this.get_sep(sep)) );
|
312 |
+
},
|
313 |
+
|
314 |
+
/**
|
315 |
+
* Add Prefix to a string
|
316 |
+
* @param string val Value to add prefix to
|
317 |
+
* @param string sep (optional) Separator (Default: `_`)
|
318 |
+
* @param bool (optional) once If text should only be prefixed once (Default: TRUE)
|
319 |
+
*/
|
320 |
+
add_prefix: function(val, sep, once) {
|
321 |
+
// Validate
|
322 |
+
if ( !this.is_string(val) ) {
|
323 |
+
// Return prefix if value to add prefix to is empty
|
324 |
+
return this.get_prefix();
|
325 |
+
}
|
326 |
+
sep = this.get_sep(sep);
|
327 |
+
if ( !this.is_bool(once) ) {
|
328 |
+
once = true;
|
329 |
+
}
|
330 |
+
|
331 |
+
return ( once && this.has_prefix(val, sep) ) ? val : [this.get_prefix(), val].join(sep);
|
332 |
+
},
|
333 |
+
|
334 |
+
/**
|
335 |
+
* Remove Prefix from a string
|
336 |
+
* @param string val Value to add prefix to
|
337 |
+
* @param string sep (optional) Separator (Default: `_`)
|
338 |
+
* @param bool (optional) once If text should only be prefixed once (Default: true)
|
339 |
+
* @return string Original value with prefix removed
|
340 |
+
*/
|
341 |
+
remove_prefix: function(val, sep, once) {
|
342 |
+
// Validate parameters
|
343 |
+
if ( !this.is_string(val, true) ) {
|
344 |
+
return '';
|
345 |
+
}
|
346 |
+
// Default values
|
347 |
+
sep = this.get_sep(sep);
|
348 |
+
if ( !this.is_bool(once) ) {
|
349 |
+
once = true;
|
350 |
+
}
|
351 |
+
// Check if string is prefixed
|
352 |
+
if ( this.has_prefix(val, sep) ) {
|
353 |
+
// Remove prefix
|
354 |
+
var prfx = this.get_prefix() + sep;
|
355 |
+
do {
|
356 |
+
val = val.substr(prfx.length);
|
357 |
+
} while ( !once && this.has_prefix(val, sep) );
|
358 |
+
}
|
359 |
+
return val;
|
360 |
+
},
|
361 |
+
|
362 |
+
/* Attributes */
|
363 |
+
|
364 |
+
/*
|
365 |
+
* Get attribute name
|
366 |
+
* @param string attr_base Attribute's base name
|
367 |
+
* @return string Fully-formed attribute name
|
368 |
+
*/
|
369 |
+
get_attribute: function(attr_base) {
|
370 |
+
// Setup
|
371 |
+
var sep = '-';
|
372 |
+
var top = 'data';
|
373 |
+
// Validate
|
374 |
+
var attr = [top, this.get_prefix()].join(sep);
|
375 |
+
// Process
|
376 |
+
if ( this.is_string(attr_base) && 0 !== attr_base.indexOf(attr + sep) ) {
|
377 |
+
attr = [attr, attr_base].join(sep);
|
378 |
+
}
|
379 |
+
return attr;
|
380 |
+
},
|
381 |
+
|
382 |
+
/* Request */
|
383 |
+
|
384 |
+
/**
|
385 |
+
* Retrieve valid context
|
386 |
+
* @return array Context
|
387 |
+
*/
|
388 |
+
get_context: function() {
|
389 |
+
// Validate
|
390 |
+
var b = this.get_base();
|
391 |
+
if ( !$.isArray(b.context) ) {
|
392 |
+
b.context = [];
|
393 |
+
}
|
394 |
+
// Return context
|
395 |
+
return b.context;
|
396 |
+
},
|
397 |
+
|
398 |
+
/**
|
399 |
+
* Check if a context exists in current request
|
400 |
+
* If multiple contexts are supplied, result will be TRUE if at least ONE context exists
|
401 |
+
*
|
402 |
+
* @param string|array ctx Context to check for
|
403 |
+
* @return bool TRUE if context exists, FALSE otherwise
|
404 |
+
*/
|
405 |
+
is_context: function(ctx) {
|
406 |
+
// Validate context
|
407 |
+
if ( this.is_string(ctx) ) {
|
408 |
+
ctx = [ctx];
|
409 |
+
}
|
410 |
+
return ( this.is_array(ctx) && this.arr_intersect(this.get_context(), ctx).length > 0 );
|
411 |
+
},
|
412 |
+
|
413 |
+
/* Helpers */
|
414 |
+
|
415 |
+
/**
|
416 |
+
* Check if value is set/defined
|
417 |
+
* @param mixed val Value to check
|
418 |
+
* @return bool TRUE if value is defined
|
419 |
+
*/
|
420 |
+
is_set: function(val) {
|
421 |
+
return ( typeof val !== 'undefined' );
|
422 |
+
},
|
423 |
+
|
424 |
+
/**
|
425 |
+
* Validate data type
|
426 |
+
* @param mixed val Value to validate
|
427 |
+
* @param mixed type Data type to compare with (function gets for instance, string checks data type)
|
428 |
+
* @param bool nonempty (optional) Check for empty value? (Default: TRUE)
|
429 |
+
* @return bool TRUE if Value matches specified data type
|
430 |
+
*/
|
431 |
+
is_type: function(val, type, nonempty) {
|
432 |
+
var ret = false;
|
433 |
+
if ( this.is_set(val) && null !== val && this.is_set(type) ) {
|
434 |
+
switch ( $.type(type) ) {
|
435 |
+
case 'function':
|
436 |
+
ret = ( val instanceof type ) ? true : false;
|
437 |
+
break;
|
438 |
+
case 'string':
|
439 |
+
ret = ( $.type(val) === type ) ? true : false;
|
440 |
+
break;
|
441 |
+
default:
|
442 |
+
ret = false;
|
443 |
+
break;
|
444 |
+
}
|
445 |
+
}
|
446 |
+
|
447 |
+
// Validate empty values
|
448 |
+
if ( ret && ( !this.is_set(nonempty) || !!nonempty ) ) {
|
449 |
+
ret = !this.is_empty(val);
|
450 |
+
}
|
451 |
+
return ret;
|
452 |
+
},
|
453 |
+
|
454 |
+
/**
|
455 |
+
* Check if value is a string
|
456 |
+
* @uses is_type()
|
457 |
+
* @param mixed value Value to check
|
458 |
+
* @param bool nonempty (optional) Check for empty value? (Default: TRUE)
|
459 |
+
* @return bool TRUE if value is a valid string
|
460 |
+
*/
|
461 |
+
is_string: function(value, nonempty) {
|
462 |
+
return this.is_type(value, 'string', nonempty);
|
463 |
+
},
|
464 |
+
|
465 |
+
/**
|
466 |
+
* Check if value is an array
|
467 |
+
* @uses is_type()
|
468 |
+
* @param mixed value Value to check
|
469 |
+
* @param bool nonempty (optional) Check for empty value? (Default: TRUE)
|
470 |
+
* @return bool TRUE if value is a valid array
|
471 |
+
*/
|
472 |
+
is_array: function(value, nonempty) {
|
473 |
+
return ( this.is_type(value, 'array', nonempty) );
|
474 |
+
},
|
475 |
+
|
476 |
+
/**
|
477 |
+
* Check if value is a boolean
|
478 |
+
* @uses is_type()
|
479 |
+
* @param mixed value Value to check
|
480 |
+
* @return bool TRUE if value is a valid boolean
|
481 |
+
*/
|
482 |
+
is_bool: function(value) {
|
483 |
+
return this.is_type(value, 'boolean', false);
|
484 |
+
},
|
485 |
+
|
486 |
+
/**
|
487 |
+
* Check if value is an object
|
488 |
+
* @uses is_type()
|
489 |
+
* @param mixed value Value to check
|
490 |
+
* @param bool nonempty (optional) Check for empty value? (Default: TRUE)
|
491 |
+
* @return bool TRUE if value is a valid object
|
492 |
+
*/
|
493 |
+
is_obj: function(value, nonempty) {
|
494 |
+
return this.is_type(value, 'object', nonempty);
|
495 |
+
},
|
496 |
+
|
497 |
+
/**
|
498 |
+
* Check if value is a function
|
499 |
+
* @uses is_type()
|
500 |
+
* @param mixed value Value to check
|
501 |
+
* @return bool TRUE if value is a valid function
|
502 |
+
*/
|
503 |
+
is_func: function(value) {
|
504 |
+
return this.is_type(value, 'function', false);
|
505 |
+
},
|
506 |
+
|
507 |
+
/**
|
508 |
+
* Checks if an object has a method
|
509 |
+
* @param obj obj Object to check
|
510 |
+
* @param string|array key Name(s) of methods to check for
|
511 |
+
* @return bool TRUE if method(s) exist, FALSE otherwise
|
512 |
+
*/
|
513 |
+
is_method: function(obj, key) {
|
514 |
+
var ret = false;
|
515 |
+
if ( this.is_string(key) ) {
|
516 |
+
key = [key];
|
517 |
+
}
|
518 |
+
if ( this.in_obj(obj, key) ) {
|
519 |
+
ret = true;
|
520 |
+
var x = 0;
|
521 |
+
while ( ret && x < key.length ) {
|
522 |
+
ret = this.is_func(obj[key[x]]);
|
523 |
+
x++;
|
524 |
+
}
|
525 |
+
}
|
526 |
+
return ret;
|
527 |
+
},
|
528 |
+
|
529 |
+
/**
|
530 |
+
* Check if object is instance of a class
|
531 |
+
* @param obj obj Instance object
|
532 |
+
* @param obj parent Class to compare with
|
533 |
+
* @return bool TRUE if object is instance of class
|
534 |
+
*/
|
535 |
+
is_instance: function(obj, parent) {
|
536 |
+
if ( !this.is_func(parent) ) {
|
537 |
+
return false;
|
538 |
+
}
|
539 |
+
return ( this.is_obj(obj) && ( obj instanceof parent ) );
|
540 |
+
},
|
541 |
+
|
542 |
+
/**
|
543 |
+
* Check if object is class
|
544 |
+
* Optionally check if class is sub-class of another class
|
545 |
+
* @param func cls Class to check
|
546 |
+
* @param func parent (optional) parent class
|
547 |
+
* @return bool TRUE if object is valid class (and sub-class if parent is specified)
|
548 |
+
*/
|
549 |
+
is_class: function(cls, parent) {
|
550 |
+
// Validate class
|
551 |
+
var ret = ( this.is_func(cls) && ( 'prototype' in cls ) );
|
552 |
+
// Check parent class
|
553 |
+
if ( ret && this.is_set(parent) ) {
|
554 |
+
ret = this.is_instance(cls.prototype, parent);
|
555 |
+
}
|
556 |
+
return ret;
|
557 |
+
},
|
558 |
+
|
559 |
+
/**
|
560 |
+
* Check if value is a number
|
561 |
+
* @uses is_type()
|
562 |
+
* @param mixed value Value to check
|
563 |
+
* @param bool nonempty (optional) Check for empty value? (Default: TRUE)
|
564 |
+
* @return bool TRUE if value is a valid number
|
565 |
+
*/
|
566 |
+
is_num: function(value, nonempty) {
|
567 |
+
var f = {
|
568 |
+
'nan': ( Number.isNaN ) ? Number.isNaN : isNaN,
|
569 |
+
'finite': ( Number.isFinite ) ? Number.isFinite : isFinite
|
570 |
+
};
|
571 |
+
return ( this.is_type(value, 'number', nonempty) && !f.nan(value) && f.finite(value) );
|
572 |
+
},
|
573 |
+
|
574 |
+
/**
|
575 |
+
* Check if value is a integer
|
576 |
+
* @uses is_type()
|
577 |
+
* @param mixed value Value to check
|
578 |
+
* @param bool nonempty (optional) Check for empty value? (Default: TRUE)
|
579 |
+
* @return bool TRUE if value is a valid integer
|
580 |
+
*/
|
581 |
+
is_int: function(value, nonempty) {
|
582 |
+
return ( this.is_num(value, nonempty) && Math.floor(value) === value );
|
583 |
+
},
|
584 |
+
|
585 |
+
/**
|
586 |
+
* Check if value is scalar (string, number, boolean)
|
587 |
+
* @uses is_type()
|
588 |
+
* @param mixed value Value to check
|
589 |
+
* @param bool nonempty (optional) Check for empty value? (Default: TRUE)
|
590 |
+
* @return bool TRUE if value is scalar
|
591 |
+
*/
|
592 |
+
is_scalar: function(value, nonempty) {
|
593 |
+
return ( this.is_num(value, nonempty) || this.is_string(value, nonempty) || this.is_bool(value) );
|
594 |
+
},
|
595 |
+
|
596 |
+
/**
|
597 |
+
* Checks if value is empty
|
598 |
+
* @param mixed value Value to check
|
599 |
+
* @param string type (optional) Data type
|
600 |
+
* @return bool TRUE if value is empty
|
601 |
+
*/
|
602 |
+
is_empty: function(value, type) {
|
603 |
+
var ret = false;
|
604 |
+
// Check Undefined
|
605 |
+
if ( !this.is_set(value) ) {
|
606 |
+
ret = true;
|
607 |
+
} else {
|
608 |
+
// Check standard values
|
609 |
+
var empties = [null, "", false, 0];
|
610 |
+
var x = 0;
|
611 |
+
while ( !ret && x < empties.length ) {
|
612 |
+
ret = ( empties[x] === value );
|
613 |
+
x++;
|
614 |
+
}
|
615 |
+
}
|
616 |
+
|
617 |
+
// Advanced check
|
618 |
+
if ( !ret ) {
|
619 |
+
// Validate type
|
620 |
+
if ( !this.is_set(type) ) {
|
621 |
+
type = $.type(value);
|
622 |
+
}
|
623 |
+
// Type-based check
|
624 |
+
if ( this.is_type(value, type, false) ) {
|
625 |
+
switch ( type ) {
|
626 |
+
case 'string':
|
627 |
+
case 'array':
|
628 |
+
ret = ( value.length === 0 );
|
629 |
+
break;
|
630 |
+
case 'number':
|
631 |
+
ret = ( value == 0 ); // jshint ignore:line
|
632 |
+
break;
|
633 |
+
case 'object':
|
634 |
+
if ( !$.isPlainObject(value) ) {
|
635 |
+
// Custom object. Unable to evaluate emptiness further
|
636 |
+
ret = false;
|
637 |
+
} else {
|
638 |
+
// Evaluate plain object
|
639 |
+
if ( Object.getOwnPropertyNames ) {
|
640 |
+
// Modern browser check
|
641 |
+
ret = ( Object.getOwnPropertyNames(value).length === 0 );
|
642 |
+
} else if ( value.hasOwnProperty ) {
|
643 |
+
// Legacy browser check
|
644 |
+
ret = true;
|
645 |
+
for ( var key in value ) {
|
646 |
+
if ( value.hasOwnProperty(key) ) {
|
647 |
+
ret = false;
|
648 |
+
break;
|
649 |
+
}
|
650 |
+
}
|
651 |
+
}
|
652 |
+
}
|
653 |
+
break;
|
654 |
+
}
|
655 |
+
} else {
|
656 |
+
ret = true;
|
657 |
+
}
|
658 |
+
}
|
659 |
+
return ret;
|
660 |
+
},
|
661 |
+
|
662 |
+
/**
|
663 |
+
* Check if object is a jQuery.Promise instance
|
664 |
+
* Will also match (but not guarantee) jQuery.Deferred instances
|
665 |
+
* @uses is_method()
|
666 |
+
* @param obj obj Object to check
|
667 |
+
* @return bool TRUE if object is Promise/Deferred
|
668 |
+
*/
|
669 |
+
is_promise: function(obj) {
|
670 |
+
return ( this.is_method(obj, ['then', 'done', 'always', 'fail', 'pipe']) );
|
671 |
+
},
|
672 |
+
|
673 |
+
/**
|
674 |
+
* Return formatted string
|
675 |
+
* @param string fmt Format template
|
676 |
+
* @param string val Replacement value (Multiple parameters may be set)
|
677 |
+
* @return string Formatted string
|
678 |
+
*/
|
679 |
+
format: function(fmt, val) {
|
680 |
+
// Validate format
|
681 |
+
if ( !this.is_string(fmt) ) {
|
682 |
+
return '';
|
683 |
+
}
|
684 |
+
var params = [];
|
685 |
+
var ph = '%s';
|
686 |
+
/**
|
687 |
+
* Clean string (remove placeholders)
|
688 |
+
*/
|
689 |
+
var strip = function(txt) {
|
690 |
+
return ( txt.indexOf(ph) !== -1 ) ? txt.replace(ph, '') : txt;
|
691 |
+
};
|
692 |
+
// Stop processing if no replacement values specified or format string contains no placeholders
|
693 |
+
if ( arguments.length < 2 || fmt.indexOf(ph) === -1 ) {
|
694 |
+
return strip(fmt);
|
695 |
+
}
|
696 |
+
// Get replacement values
|
697 |
+
params = Array.prototype.slice.call(arguments, 1);
|
698 |
+
val = null;
|
699 |
+
// Clean parameters
|
700 |
+
for ( var x = 0; x < params.length; x++ ) {
|
701 |
+
if ( !this.is_scalar(params[x], false) ) {
|
702 |
+
params[x] = '';
|
703 |
+
}
|
704 |
+
}
|
705 |
+
|
706 |
+
// Replace all placeholders at once if single parameter set
|
707 |
+
if ( params.length === 1 ) {
|
708 |
+
fmt = fmt.replace(ph, params[0].toString());
|
709 |
+
} else {
|
710 |
+
var idx = 0; // Current replacement index
|
711 |
+
var len = params.length; // Number of replacements
|
712 |
+
var rlen = ph.length; // Placeholder length
|
713 |
+
var pos = 0; // Current placeholder position (in format template)
|
714 |
+
while ( ( pos = fmt.indexOf(ph) ) && pos !== -1 && idx < len ) {
|
715 |
+
// Replace current placeholder with respective parameter
|
716 |
+
fmt = fmt.substr(0, pos) + params[idx].toString() + fmt.substr(pos + rlen);
|
717 |
+
idx++;
|
718 |
+
}
|
719 |
+
// Remove any remaining placeholders
|
720 |
+
fmt = strip(fmt);
|
721 |
+
}
|
722 |
+
return fmt;
|
723 |
+
},
|
724 |
+
|
725 |
+
/**
|
726 |
+
* Checks if key(s) exist in an object
|
727 |
+
* @param object obj Object to check
|
728 |
+
* @param string|array key Key(s) to check for in object
|
729 |
+
* @param bool all (optional) All keys must exist in object? (Default: TRUE)
|
730 |
+
* @return bool TRUE if key(s) exist in object
|
731 |
+
*/
|
732 |
+
in_obj: function(obj, key, all) {
|
733 |
+
// Validate
|
734 |
+
if ( !this.is_bool(all) ) {
|
735 |
+
all = true;
|
736 |
+
}
|
737 |
+
if ( this.is_string(key) ) {
|
738 |
+
key = [key];
|
739 |
+
}
|
740 |
+
// Check for keys
|
741 |
+
var ret = false;
|
742 |
+
if ( this.is_obj(obj) && this.is_array(key) ) {
|
743 |
+
var val;
|
744 |
+
for ( var x = 0; x < key.length; x++ ) {
|
745 |
+
val = key[x];
|
746 |
+
ret = ( this.is_string(val) && ( val in obj ) ) ? true : false;
|
747 |
+
// Stop processing if conditions have been met
|
748 |
+
if ( ( !all && ret ) || ( all && !ret ) ) {
|
749 |
+
break;
|
750 |
+
}
|
751 |
+
}
|
752 |
+
}
|
753 |
+
return ret;
|
754 |
+
},
|
755 |
+
|
756 |
+
/**
|
757 |
+
* Retrieve an object's keys
|
758 |
+
* @param obj Object to parse
|
759 |
+
* @return array List of object's keys
|
760 |
+
*/
|
761 |
+
obj_keys: function(obj) {
|
762 |
+
var keys = [];
|
763 |
+
// Validation
|
764 |
+
if ( !this.is_obj(obj) ) {
|
765 |
+
return keys;
|
766 |
+
}
|
767 |
+
if ( Object.keys ) {
|
768 |
+
keys = Object.keys(obj);
|
769 |
+
} else {
|
770 |
+
var prop;
|
771 |
+
for ( prop in obj ) {
|
772 |
+
if ( obj.hasOwnProperty(prop) ) {
|
773 |
+
keys.push(prop);
|
774 |
+
}
|
775 |
+
}
|
776 |
+
}
|
777 |
+
return keys;
|
778 |
+
},
|
779 |
+
|
780 |
+
/**
|
781 |
+
* Find common elements of 2 or more arrays
|
782 |
+
* @param array arr1 First array
|
783 |
+
* @param array arr2 Second array (additional arrays can be passed as well)
|
784 |
+
* @return array Elements common to all
|
785 |
+
*/
|
786 |
+
arr_intersect: function(arr1, arr2) {
|
787 |
+
var ret = [];
|
788 |
+
// Get arrays
|
789 |
+
var params = Array.prototype.slice.call(arguments);
|
790 |
+
// Clean arrays
|
791 |
+
var arrs = [];
|
792 |
+
var x;
|
793 |
+
for ( x = 0; x < params.length; x++ ) {
|
794 |
+
if ( this.is_array(params[x], false) ) {
|
795 |
+
arrs.push(params[x]);
|
796 |
+
}
|
797 |
+
}
|
798 |
+
// Stop processing if no valid arrays to compare
|
799 |
+
if ( arrs.length < 2 ) {
|
800 |
+
return ret;
|
801 |
+
}
|
802 |
+
params = arr1 = arr2 = null;
|
803 |
+
// Find common elements in arrays
|
804 |
+
var base = arrs.shift();
|
805 |
+
var add;
|
806 |
+
var sub;
|
807 |
+
for ( x = 0; x < base.length; x++ ) {
|
808 |
+
add = true;
|
809 |
+
// Check other arrays for element match
|
810 |
+
for ( sub = 0; sub < arrs.length; sub++ ) {
|
811 |
+
if ( arrs[sub].indexOf(base[x]) === -1 ) {
|
812 |
+
add = false;
|
813 |
+
break;
|
814 |
+
}
|
815 |
+
}
|
816 |
+
if ( add ) {
|
817 |
+
ret.push(base[x]);
|
818 |
+
}
|
819 |
+
}
|
820 |
+
// Return intersection results
|
821 |
+
return ret;
|
822 |
+
},
|
823 |
+
|
824 |
+
/**
|
825 |
+
* Generates a GUID string.
|
826 |
+
* @returns string The generated GUID.
|
827 |
+
* @example af8a8416-6e18-a307-bd9c-f2c947bbb3aa
|
828 |
+
* @author Slavik Meltser (slavik@meltser.info).
|
829 |
+
* @link http://slavik.meltser.info/?p=142
|
830 |
+
*/
|
831 |
+
guid: function() {
|
832 |
+
function _p8(s) {
|
833 |
+
var p = (Math.random().toString(16)+"000000000").substr(2,8);
|
834 |
+
return s ? "-" + p.substr(0,4) + "-" + p.substr(4,4) : p ;
|
835 |
+
}
|
836 |
+
return _p8() + _p8(true) + _p8(true) + _p8();
|
837 |
+
},
|
838 |
+
|
839 |
+
/**
|
840 |
+
* Parse URI
|
841 |
+
* @param string uri URI to parse
|
842 |
+
* @return obj URI components (DOM anchor element)
|
843 |
+
*/
|
844 |
+
parse_uri: function(uri) {
|
845 |
+
return $('<a href="' + uri + '"/>').get(0);
|
846 |
+
},
|
847 |
+
/**
|
848 |
+
* Parse URI query string
|
849 |
+
* @param string uri URI with query string to parse
|
850 |
+
* @return obj Query variables and values (empty if no query string)
|
851 |
+
*/
|
852 |
+
parse_query: function(uri) {
|
853 |
+
var delim = {
|
854 |
+
'vars': '&',
|
855 |
+
'val': '='
|
856 |
+
};
|
857 |
+
var query = {
|
858 |
+
'raw': [],
|
859 |
+
'parsed': {},
|
860 |
+
'string': ''
|
861 |
+
};
|
862 |
+
uri = this.parse_uri(uri);
|
863 |
+
if ( 0 === uri.search.indexOf('?') ) {
|
864 |
+
// Extract query string
|
865 |
+
query.raw = uri.search.substr(1).split(delim.vars);
|
866 |
+
var i, temp, key, val;
|
867 |
+
// Build query object
|
868 |
+
for ( i = 0; i < query.raw.length; i++ ) {
|
869 |
+
// Split var and value
|
870 |
+
temp = query.raw[i].split(delim.val);
|
871 |
+
key = temp.shift();
|
872 |
+
val = ( temp.length > 0 ) ? temp.join(delim.val) : null;
|
873 |
+
query.parsed[key] = val;
|
874 |
+
}
|
875 |
+
}
|
876 |
+
return query.parsed;
|
877 |
+
},
|
878 |
+
/**
|
879 |
+
* Build query string from object
|
880 |
+
* @param obj query Query data
|
881 |
+
* @return string Query data formatted as HTTP query string
|
882 |
+
*/
|
883 |
+
build_query: function(query) {
|
884 |
+
var q = [];
|
885 |
+
var delim = {
|
886 |
+
'vars': '&',
|
887 |
+
'val': '='
|
888 |
+
};
|
889 |
+
var val;
|
890 |
+
for ( var key in query ) {
|
891 |
+
val = ( null !== query[key] ) ? delim.val + query[key] : '';
|
892 |
+
q.push(key + val);
|
893 |
+
}
|
894 |
+
return q.join(delim.vars);
|
895 |
+
}
|
896 |
+
};
|
897 |
+
|
898 |
+
// Attach Utilities
|
899 |
+
Base.attach('util', Utilities, true);
|
900 |
+
|
901 |
+
/**
|
902 |
+
* SLB Base Class
|
903 |
+
*/
|
904 |
+
var SLB_Base = Class.extend(Base);
|
905 |
+
|
906 |
+
/**
|
907 |
+
* Core
|
908 |
+
*/
|
909 |
+
var Core = {
|
910 |
+
/* Properties */
|
911 |
+
|
912 |
+
base: true,
|
913 |
+
context: [],
|
914 |
+
|
915 |
+
/**
|
916 |
+
* New object initializer
|
917 |
+
* @var obj
|
918 |
+
*/
|
919 |
+
Class: SLB_Base,
|
920 |
+
|
921 |
+
/* Methods */
|
922 |
+
|
923 |
+
/**
|
924 |
+
* Init
|
925 |
+
* Set variables, DOM, etc.
|
926 |
+
*/
|
927 |
+
_init: function() {
|
928 |
+
this._super();
|
929 |
+
$('html').addClass(this.util.get_prefix());
|
930 |
+
}
|
931 |
+
};
|
932 |
+
var SLB_Core = SLB_Base.extend(Core);
|
933 |
+
window.SLB = new SLB_Core();
|
934 |
+
})(jQuery);}
|
client/js/{lib.view.js → dev/lib.view.js}
RENAMED
@@ -4,12 +4,8 @@
|
|
4 |
* @subpackage View
|
5 |
* @author Archetyped
|
6 |
*/
|
7 |
-
|
8 |
-
(function ($) {
|
9 |
-
|
10 |
-
if ( typeof SLB == 'undefined' || !SLB.attach ) {
|
11 |
-
return false;
|
12 |
-
}
|
13 |
|
14 |
/*-** Controller **-*/
|
15 |
|
@@ -41,21 +37,11 @@ var View = {
|
|
41 |
*/
|
42 |
loading: [],
|
43 |
|
44 |
-
/* Component Collections */
|
45 |
-
|
46 |
-
viewers: {},
|
47 |
-
items: [],
|
48 |
-
content_handlers: {},
|
49 |
-
groups: {},
|
50 |
-
template_tags: {},
|
51 |
-
|
52 |
/**
|
53 |
-
*
|
54 |
-
* > Key: Collection name
|
55 |
-
* > Value: Data type
|
56 |
* @var object
|
57 |
*/
|
58 |
-
|
59 |
|
60 |
/**
|
61 |
* Temporary component instances
|
@@ -66,56 +52,74 @@ var View = {
|
|
66 |
component_temps: {},
|
67 |
|
68 |
/* Options */
|
69 |
-
options: {
|
70 |
-
ui_animate: true,
|
71 |
-
slideshow_enabled: true,
|
72 |
-
slideshow_autostart: false,
|
73 |
-
slideshow_duration: '6'
|
74 |
-
},
|
75 |
|
76 |
/* Methods */
|
77 |
|
78 |
/* Init */
|
79 |
|
80 |
-
|
81 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
var r;
|
83 |
var ref;
|
84 |
-
|
85 |
-
|
|
|
|
|
|
|
86 |
continue;
|
87 |
}
|
88 |
-
//
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
ref = c.prototype._refs[r];
|
93 |
-
if ( this.util.is_func(ref) ) {
|
94 |
-
continue;
|
95 |
-
}
|
96 |
if ( this.util.is_string(ref) && ref in this ) {
|
97 |
-
ref =
|
98 |
}
|
99 |
-
if ( !this.util.
|
100 |
-
delete
|
101 |
}
|
102 |
}
|
103 |
}
|
104 |
}
|
105 |
-
|
106 |
-
/* Initialize components */
|
107 |
-
this.init_components();
|
108 |
},
|
109 |
|
110 |
/**
|
111 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
*/
|
113 |
init: function(options) {
|
114 |
var t = this;
|
|
|
115 |
$.when.apply($, this.loading).always(function() {
|
116 |
-
//Set options
|
117 |
$.extend(true, t.options, options);
|
118 |
-
|
|
|
|
|
|
|
119 |
$(window).on('popstate', function(e) {
|
120 |
var state = e.originalEvent.state;
|
121 |
if ( t.util.in_obj(state, ['item', 'viewer']) ) {
|
@@ -127,65 +131,47 @@ var View = {
|
|
127 |
|
128 |
/* Set defaults */
|
129 |
|
130 |
-
//Items
|
131 |
t.init_items();
|
132 |
});
|
133 |
},
|
134 |
|
135 |
-
init_components: function() {
|
136 |
-
this.collections = {
|
137 |
-
'viewers': this.Viewer,
|
138 |
-
'items': this.Content_Item,
|
139 |
-
'content_handlers': this.Content_Handler,
|
140 |
-
'groups': this.Group,
|
141 |
-
'themes': this.Theme,
|
142 |
-
'template_tags': this.Template_Tag
|
143 |
-
};
|
144 |
-
|
145 |
-
this.component_defaults = [
|
146 |
-
this.Viewer,
|
147 |
-
];
|
148 |
-
|
149 |
-
},
|
150 |
-
|
151 |
/* Components */
|
152 |
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
return ret;
|
162 |
},
|
163 |
|
164 |
/**
|
165 |
-
*
|
166 |
-
* @param
|
167 |
-
* @return bool TRUE if
|
168 |
*/
|
169 |
-
|
170 |
-
|
171 |
-
return ( this.util.is_func(comp) && ('_slug' in comp.prototype ) && ( comp.prototype instanceof (this.Component) ) ) ? true : false;
|
172 |
},
|
173 |
|
174 |
/**
|
175 |
* Retrieve collection of components of specified type
|
176 |
-
* @param
|
177 |
-
* @return object
|
178 |
*/
|
179 |
get_components: function(type) {
|
180 |
-
var ret =
|
181 |
-
if ( this.
|
182 |
-
//Determine collection
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
}
|
188 |
}
|
|
|
189 |
}
|
190 |
return ret;
|
191 |
},
|
@@ -198,16 +184,16 @@ var View = {
|
|
198 |
*/
|
199 |
get_component: function(type, id) {
|
200 |
var ret = null;
|
201 |
-
//Validate parameters
|
202 |
if ( !this.util.is_func(type) ) {
|
203 |
return ret;
|
204 |
}
|
205 |
-
//Sanitize id
|
206 |
if ( !this.util.is_string(id) ) {
|
207 |
id = null;
|
208 |
}
|
209 |
|
210 |
-
//Get component from collection
|
211 |
var coll = this.get_components(type);
|
212 |
if ( this.util.is_obj(coll) ) {
|
213 |
var tid = ( this.util.is_string(id) ) ? id : this.util.add_prefix('default');
|
@@ -216,13 +202,13 @@ var View = {
|
|
216 |
}
|
217 |
}
|
218 |
|
219 |
-
//Default: Create default component
|
220 |
if ( this.util.is_empty(ret) ) {
|
221 |
-
if ( this.util.is_string(id) || this.
|
222 |
ret = this.add_component(type, id);
|
223 |
}
|
224 |
}
|
225 |
-
//Return component
|
226 |
return ret;
|
227 |
},
|
228 |
|
@@ -234,15 +220,15 @@ var View = {
|
|
234 |
* @return object|null New component (NULL if invalid)
|
235 |
*/
|
236 |
add_component: function(type, id, options) {
|
237 |
-
//Validate type
|
238 |
if ( !this.util.is_func(type) ) {
|
239 |
return false;
|
240 |
}
|
241 |
-
//Validate request
|
242 |
-
if ( this.util.is_empty(id) && !this.
|
243 |
return false;
|
244 |
}
|
245 |
-
//Defaults
|
246 |
var ret = null;
|
247 |
if ( this.util.is_empty(id) ) {
|
248 |
id = this.util.add_prefix('default');
|
@@ -250,21 +236,21 @@ var View = {
|
|
250 |
if ( !this.util.is_obj(options) ) {
|
251 |
options = {};
|
252 |
}
|
253 |
-
//Check if specialized method exists for component type
|
254 |
-
var m = ( 'component'
|
255 |
if ( !this.util.is_empty(m) && ( m in this ) && this.util.is_func(this[m]) ) {
|
256 |
ret = this[m](id, options);
|
257 |
}
|
258 |
-
//Default process
|
259 |
else {
|
260 |
ret = new type(id, options);
|
261 |
}
|
262 |
|
263 |
-
//Add new component to collection
|
264 |
if ( this.util.is_type(ret, type) ) {
|
265 |
-
//Get collection
|
266 |
var coll = this.get_components(type);
|
267 |
-
//Add to collection
|
268 |
switch ( $.type(coll) ) {
|
269 |
case 'object' :
|
270 |
coll[id] = ret;
|
@@ -276,7 +262,7 @@ var View = {
|
|
276 |
} else {
|
277 |
ret = null;
|
278 |
}
|
279 |
-
//Return new component
|
280 |
return ret;
|
281 |
},
|
282 |
|
@@ -287,10 +273,10 @@ var View = {
|
|
287 |
*/
|
288 |
add_component_temp: function(type) {
|
289 |
var ret = null;
|
290 |
-
if ( this.
|
291 |
-
//Create new instance
|
292 |
ret = new type('');
|
293 |
-
//Save to collection
|
294 |
this.component_temps[ret._slug] = ret;
|
295 |
}
|
296 |
return ret;
|
@@ -312,7 +298,7 @@ var View = {
|
|
312 |
* @return bool TRUE if temp instance exists, FALSE otherwise
|
313 |
*/
|
314 |
has_component_temp: function(type) {
|
315 |
-
return ( this.
|
316 |
},
|
317 |
|
318 |
/* Properties */
|
@@ -324,16 +310,16 @@ var View = {
|
|
324 |
*/
|
325 |
get_options: function(opts) {
|
326 |
var ret = {};
|
327 |
-
//Validate
|
328 |
if ( this.util.is_string(opts) ) {
|
329 |
opts = [opts];
|
330 |
}
|
331 |
if ( !this.util.is_array(opts) ) {
|
332 |
return ret;
|
333 |
}
|
334 |
-
//Get specified options
|
335 |
for ( var x = 0; x < opts.length; x++ ) {
|
336 |
-
//Skip if option not set
|
337 |
if ( !( opts[x] in this.options ) ) {
|
338 |
continue;
|
339 |
}
|
@@ -365,20 +351,14 @@ var View = {
|
|
365 |
* Add viewer instance to collection
|
366 |
* @param string id Viewer ID
|
367 |
* @param obj options Viewer options
|
|
|
368 |
*/
|
369 |
add_viewer: function(id, options) {
|
370 |
-
//
|
371 |
-
if ( !this.util.is_string(id) ) {
|
372 |
-
return false;
|
373 |
-
}
|
374 |
-
if ( !this.util.is_obj(options, false) ) {
|
375 |
-
options = {};
|
376 |
-
}
|
377 |
-
//Create viewer
|
378 |
var v = new this.Viewer(id, options);
|
379 |
-
//
|
380 |
-
this.
|
381 |
-
//Return viewer
|
382 |
return v;
|
383 |
},
|
384 |
|
@@ -387,7 +367,7 @@ var View = {
|
|
387 |
* @return obj Viewer instances
|
388 |
*/
|
389 |
get_viewers: function() {
|
390 |
-
return this.
|
391 |
},
|
392 |
|
393 |
/**
|
@@ -407,12 +387,13 @@ var View = {
|
|
407 |
* @return Viewer Viewer instance
|
408 |
*/
|
409 |
get_viewer: function(v) {
|
410 |
-
//Retrieve default viewer if specified viewer not set
|
411 |
if ( !this.has_viewer(v) ) {
|
412 |
v = this.util.add_prefix('default');
|
413 |
-
//Create default viewer if necessary
|
414 |
if ( !this.has_viewer(v) ) {
|
415 |
-
this.add_viewer(v);
|
|
|
416 |
}
|
417 |
}
|
418 |
return this.get_viewers()[v];
|
@@ -424,7 +405,7 @@ var View = {
|
|
424 |
* Set event handlers
|
425 |
*/
|
426 |
init_items: function() {
|
427 |
-
//Define handler
|
428 |
var t = this;
|
429 |
var handler = function() {
|
430 |
var ret = t.show_item(this);
|
@@ -434,12 +415,16 @@ var View = {
|
|
434 |
return !ret;
|
435 |
};
|
436 |
|
437 |
-
//Get activated links
|
438 |
var sel = this.util.format('a[href][%s="%s"]', this.util.get_attribute('active'), 1);
|
439 |
-
//Add event handler
|
440 |
-
$(document).on('click', sel, handler);
|
441 |
},
|
442 |
|
|
|
|
|
|
|
|
|
443 |
get_items: function() {
|
444 |
return this.get_components(this.Content_Item);
|
445 |
},
|
@@ -453,30 +438,30 @@ var View = {
|
|
453 |
* @return Content_Item Item instance for DOM node
|
454 |
*/
|
455 |
get_item: function(ref) {
|
456 |
-
//Evaluate reference type
|
457 |
|
458 |
-
//Content Item instance
|
459 |
if ( this.util.is_type(ref, this.Content_Item) ) {
|
460 |
return ref;
|
461 |
}
|
462 |
-
//Retrieve item instance
|
463 |
var item = null;
|
464 |
|
465 |
-
//DOM element
|
466 |
if ( this.util.in_obj(ref, 'nodeType') ) {
|
467 |
-
//Check if item instance attached to element
|
468 |
var key = this.get_component_temp(this.Content_Item).get_data_key();
|
469 |
item = $(ref).data(key);
|
470 |
}
|
471 |
-
//Cached item (index)
|
472 |
-
else if ( this.util.
|
473 |
var items = this.get_items();
|
474 |
-
if (
|
475 |
item = items[ref];
|
476 |
}
|
477 |
}
|
478 |
-
//Create default item instance
|
479 |
-
if ( !this.util.
|
480 |
item = this.add_item(ref);
|
481 |
}
|
482 |
return item;
|
@@ -488,44 +473,40 @@ var View = {
|
|
488 |
* @return Content_Item New item instance
|
489 |
*/
|
490 |
add_item: function(el) {
|
491 |
-
|
492 |
-
return item;
|
493 |
},
|
494 |
|
495 |
/**
|
496 |
* Display item in viewer
|
497 |
* @param obj el DOM element representing item
|
|
|
498 |
*/
|
499 |
show_item: function(el) {
|
500 |
-
|
501 |
-
return ret;
|
502 |
},
|
503 |
|
504 |
/**
|
505 |
* Cache item instance
|
506 |
-
* @uses
|
507 |
* @param Content_Item item Item to cache
|
508 |
-
* @return
|
509 |
*/
|
510 |
save_item: function(item) {
|
511 |
-
|
512 |
-
|
513 |
-
return ret;
|
514 |
-
}
|
515 |
-
var prop = 'items';
|
516 |
-
var items = this.get_items();
|
517 |
-
//Check if item exists in collection
|
518 |
-
ret = $.inArray(item, items);
|
519 |
-
//Cache item
|
520 |
-
if ( -1 == ret ) {
|
521 |
-
ret = items.push(item) - 1;
|
522 |
}
|
523 |
-
//
|
524 |
-
|
|
|
|
|
525 |
},
|
526 |
|
527 |
/* Content Handler */
|
528 |
|
|
|
|
|
|
|
|
|
529 |
get_content_handlers: function() {
|
530 |
return this.get_components(this.Content_Handler);
|
531 |
},
|
@@ -536,72 +517,39 @@ var View = {
|
|
536 |
* @return Content_Handler|null Matching content handler (NULL if no matching handler found)
|
537 |
*/
|
538 |
get_content_handler: function(item) {
|
539 |
-
//Determine handler to retrieve
|
540 |
-
var type = ( this.util.
|
541 |
-
//Retrieve handler
|
542 |
var types = this.get_content_handlers();
|
543 |
return ( type in types ) ? types[type] : null;
|
544 |
},
|
545 |
|
546 |
/**
|
547 |
-
* Add Content Handler
|
548 |
* @param string id Handler ID
|
549 |
-
* @param obj
|
|
|
550 |
*/
|
551 |
-
|
552 |
-
|
553 |
-
if ( !this.util.is_string(id) ) {
|
554 |
-
return
|
555 |
}
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
if ( this.util.is_string(attributes) ) {
|
562 |
-
$.get(attributes).always(function(data, textStatus) {
|
563 |
-
var r = null;
|
564 |
-
try {
|
565 |
-
eval('r = ' + data);
|
566 |
-
} catch (e) {}
|
567 |
-
if ( !t.util.is_obj(r) ) {
|
568 |
-
r = {};
|
569 |
-
}
|
570 |
-
dfr.resolve(r);
|
571 |
-
});
|
572 |
-
} else {
|
573 |
-
dfr.resolve({});
|
574 |
-
}
|
575 |
-
} else {
|
576 |
-
dfr.resolve(attributes);
|
577 |
}
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
var types = t.get_components(t.Content_Handler);
|
582 |
-
if ( !t.util.is_obj(types, false) ) {
|
583 |
-
types = {};
|
584 |
-
}
|
585 |
-
types[id] = new t.Content_Handler(id, o);
|
586 |
-
});
|
587 |
-
},
|
588 |
-
|
589 |
-
/**
|
590 |
-
* Update content handler
|
591 |
-
* @param string id Handler to update
|
592 |
-
* @param obj attr Variable number of attribute objects to add handlera
|
593 |
-
*/
|
594 |
-
update_content_handler: function(id, attr) {
|
595 |
-
if ( !this.util.is_string(id) || !this.util.is_obj(attr) ) {
|
596 |
-
return false;
|
597 |
}
|
598 |
-
//
|
599 |
-
|
600 |
-
|
601 |
-
return false;
|
602 |
}
|
603 |
-
|
604 |
-
h.set_attributes(attr);
|
605 |
},
|
606 |
|
607 |
/* Group */
|
@@ -611,14 +559,15 @@ var View = {
|
|
611 |
* @param string g Group ID
|
612 |
* > If group with same ID already set, new group replaces existing one
|
613 |
* @param object attrs (optional) Group attributes
|
|
|
614 |
*/
|
615 |
add_group: function(g, attrs) {
|
616 |
-
//Create new group
|
617 |
g = new this.Group(g, attrs);
|
618 |
-
//
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
},
|
623 |
|
624 |
/**
|
@@ -627,24 +576,20 @@ var View = {
|
|
627 |
* @return object Registered groups
|
628 |
*/
|
629 |
get_groups: function() {
|
630 |
-
return this.
|
631 |
},
|
632 |
|
633 |
/**
|
634 |
* Retrieve specified group
|
|
|
|
|
|
|
|
|
635 |
* @param string g Group ID
|
636 |
-
* @return
|
637 |
*/
|
638 |
get_group: function(g) {
|
639 |
-
|
640 |
-
if ( !this.has_group(g) ) {
|
641 |
-
//Add new group (if necessary)
|
642 |
-
this.add_group(g);
|
643 |
-
}
|
644 |
-
//Retrieve group
|
645 |
-
g = this.get_groups()[g];
|
646 |
-
}
|
647 |
-
return ( this.util.is_type(g, this.Group) ) ? g : null;
|
648 |
},
|
649 |
|
650 |
/**
|
@@ -653,132 +598,55 @@ var View = {
|
|
653 |
* @return bool TRUE if group exists, FALSE otherwise
|
654 |
*/
|
655 |
has_group: function(g) {
|
656 |
-
return ( this.util.is_string(g) && ( g in this.get_groups() ) )
|
657 |
},
|
658 |
|
659 |
/* Theme */
|
660 |
|
661 |
/**
|
662 |
-
* Add theme
|
663 |
* @param string name Theme name
|
664 |
-
* @param obj attr Theme options
|
665 |
-
*
|
666 |
-
* @return obj Theme model
|
667 |
*/
|
668 |
-
|
669 |
-
|
670 |
-
//Validate
|
671 |
if ( !this.util.is_string(id) ) {
|
672 |
return false;
|
673 |
}
|
674 |
var dfr = $.Deferred();
|
675 |
this.loading.push(dfr);
|
676 |
|
677 |
-
//
|
678 |
-
var
|
679 |
-
if ( arguments.length >= 2 ) {
|
680 |
-
var args = Array.prototype.slice.call(arguments, 1);
|
681 |
-
var t = this;
|
682 |
-
$.each(args, function(idx, arg) {
|
683 |
-
if ( t.util.is_obj(arg) ) {
|
684 |
-
attrs.push(arg)
|
685 |
-
}
|
686 |
-
});
|
687 |
-
}
|
688 |
-
|
689 |
-
//Set ID
|
690 |
-
attrs.push({'id': id});
|
691 |
-
|
692 |
-
//Create theme model
|
693 |
-
var model = $.extend.apply(null, attrs);
|
694 |
|
695 |
-
//
|
696 |
-
if ( this.util.
|
697 |
-
|
|
|
698 |
}
|
699 |
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
$.
|
707 |
-
//Set layout (raw) attribute
|
708 |
-
if ( t.util.is_string(data) ) {
|
709 |
-
model['layout_raw'] = data;
|
710 |
-
}
|
711 |
-
dfr_layout.resolve();
|
712 |
-
});
|
713 |
-
} else {
|
714 |
-
dfr_layout.resolve();
|
715 |
}
|
716 |
|
717 |
-
//
|
718 |
-
|
719 |
-
|
720 |
-
if ( prop_script in model && this.util.is_string(model[prop_script]) ) {
|
721 |
-
//Retrieve client script
|
722 |
-
$.get(model[prop_script]).always(function(data) {
|
723 |
-
var r = null;
|
724 |
-
try {
|
725 |
-
eval('r = ' + data);
|
726 |
-
} catch (e) {}
|
727 |
-
if ( t.util.is_obj(r) ) {
|
728 |
-
//Add attributes to model
|
729 |
-
$.extend(model, r);
|
730 |
-
}
|
731 |
-
dfr_script.resolve();
|
732 |
-
});
|
733 |
-
} else {
|
734 |
-
dfr_script.resolve();
|
735 |
}
|
736 |
|
737 |
-
//
|
738 |
-
|
739 |
-
|
740 |
-
//Add stylesheet to document
|
741 |
-
$('<link />', {
|
742 |
-
'id': 'theme_style_' + model.id,
|
743 |
-
'href': model[prop_style],
|
744 |
-
'type': 'text/css',
|
745 |
-
'rel': 'stylesheet'
|
746 |
-
}).appendTo('body');
|
747 |
}
|
748 |
|
749 |
-
//Complete loading when all components loaded
|
750 |
-
|
751 |
-
dfr.resolve();
|
752 |
-
});
|
753 |
-
//Add theme model
|
754 |
-
this.Theme.prototype._models[id] = model;
|
755 |
-
return model;
|
756 |
-
},
|
757 |
-
|
758 |
-
/**
|
759 |
-
* Update theme model
|
760 |
-
* @param string id Theme to update
|
761 |
-
* @param obj attr Variable number of attribute objects to add to model
|
762 |
-
*/
|
763 |
-
update_theme: function(id, attr) {
|
764 |
-
var model = this.get_theme_model(id);
|
765 |
-
var args = Array.prototype.slice.call(arguments);
|
766 |
-
if ( this.util.is_empty(model) ) {
|
767 |
-
model = this.add_model.apply(this, args);
|
768 |
-
} else {
|
769 |
-
//Process attributes
|
770 |
-
args.shift();
|
771 |
-
var attrs = [];
|
772 |
-
var t = this;
|
773 |
-
$.each(args, function(idx, arg) {
|
774 |
-
if ( t.util.is_obj(arg) ) {
|
775 |
-
attrs.push(arg);
|
776 |
-
}
|
777 |
-
});
|
778 |
-
//Merge attributes into model
|
779 |
-
attrs.unshift(model);
|
780 |
-
$.extend.apply($, attrs);
|
781 |
-
}
|
782 |
return model;
|
783 |
},
|
784 |
|
@@ -787,7 +655,7 @@ var View = {
|
|
787 |
* @return obj Theme models
|
788 |
*/
|
789 |
get_theme_models: function() {
|
790 |
-
//Retrieve matching theme model
|
791 |
return this.Theme.prototype._models;
|
792 |
},
|
793 |
|
@@ -802,42 +670,49 @@ var View = {
|
|
802 |
},
|
803 |
|
804 |
/**
|
805 |
-
*
|
806 |
-
* @
|
807 |
-
* @param obj
|
|
|
808 |
*/
|
809 |
-
|
810 |
-
|
811 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
812 |
return false;
|
813 |
}
|
814 |
-
var
|
815 |
-
var
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
$.get(attributes).always(function(data) {
|
821 |
-
var r = null;
|
822 |
-
try {
|
823 |
-
eval('r = ' + data);
|
824 |
-
} catch (e) {}
|
825 |
-
if ( !t.util.is_obj(r) ) {
|
826 |
-
r = {};
|
827 |
-
}
|
828 |
-
dfr.resolve(r);
|
829 |
-
});
|
830 |
-
} else {
|
831 |
-
dfr.resolve({});
|
832 |
-
}
|
833 |
} else {
|
834 |
-
|
|
|
|
|
835 |
}
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
|
|
|
|
|
|
|
|
841 |
},
|
842 |
|
843 |
/**
|
@@ -851,16 +726,31 @@ var View = {
|
|
851 |
/**
|
852 |
* Retrieve template tag handler
|
853 |
* @param string id ID of tag handler to retrieve
|
854 |
-
* @return Template_Tag_Handler Tag Handler instance (
|
855 |
*/
|
856 |
get_template_tag_handler: function(id) {
|
857 |
var handlers = this.get_template_tag_handlers();
|
858 |
-
//Retrieve existing handler
|
859 |
-
|
860 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
861 |
}
|
862 |
-
//Default: Return empty handler
|
863 |
-
return new this.Template_Tag_Handler(id, {});
|
864 |
}
|
865 |
};
|
866 |
|
@@ -876,23 +766,20 @@ var Component = {
|
|
876 |
*/
|
877 |
_slug: 'component',
|
878 |
|
|
|
|
|
|
|
|
|
|
|
|
|
879 |
/**
|
880 |
* Valid component references for current component
|
|
|
881 |
* > Key (string): Property name that stores reference
|
882 |
* > Value (function): Data type of component
|
883 |
-
* @var object
|
884 |
*/
|
885 |
_refs: {},
|
886 |
|
887 |
-
/**
|
888 |
-
* Components that may contain current object
|
889 |
-
* Used for retrieving data from a parent object
|
890 |
-
* Example: An Item may be contained by a Group
|
891 |
-
* > Value (strong): Property name of container component
|
892 |
-
* @var array
|
893 |
-
*/
|
894 |
-
_containers: [],
|
895 |
-
|
896 |
/**
|
897 |
* Whether DOM element and component are connected in 1:1 relationship
|
898 |
* Some components will be assigned to different DOM elements depending on usage
|
@@ -905,6 +792,14 @@ var Component = {
|
|
905 |
* @var DOM Element
|
906 |
*/
|
907 |
_dom: null,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
908 |
|
909 |
/**
|
910 |
* Default attributes
|
@@ -913,16 +808,16 @@ var Component = {
|
|
913 |
_attr_default: {},
|
914 |
|
915 |
/**
|
916 |
-
*
|
917 |
-
* @var
|
918 |
*/
|
919 |
-
|
920 |
|
921 |
/**
|
922 |
-
* Attributes to
|
923 |
-
* @var
|
924 |
*/
|
925 |
-
|
926 |
|
927 |
/**
|
928 |
* Defines how parent properties should be remapped to component properties
|
@@ -936,7 +831,7 @@ var Component = {
|
|
936 |
* > Key: string Event type
|
937 |
* > Value: array Handlers
|
938 |
*/
|
939 |
-
_events:
|
940 |
|
941 |
/**
|
942 |
* Status management
|
@@ -946,77 +841,62 @@ var Component = {
|
|
946 |
*/
|
947 |
_status: null,
|
948 |
|
949 |
-
/* Public */
|
950 |
-
|
951 |
-
attributes: false,
|
952 |
-
|
953 |
/**
|
954 |
* Component ID
|
955 |
* @var string
|
956 |
*/
|
957 |
-
|
958 |
|
959 |
/* Init */
|
960 |
|
|
|
|
|
|
|
|
|
|
|
961 |
_c: function(id, attributes) {
|
962 |
-
//Set ID
|
963 |
-
this.
|
964 |
-
//Save init attributes
|
965 |
-
this.
|
966 |
-
|
|
|
|
|
|
|
967 |
},
|
968 |
|
|
|
|
|
|
|
|
|
969 |
_set_parent: function() {
|
970 |
-
this.
|
971 |
-
this.util._parent = this;
|
972 |
},
|
973 |
|
974 |
/**
|
975 |
* Register hooks on init
|
976 |
* Placeholder method to be overridden by child classes
|
977 |
*/
|
978 |
-
|
979 |
|
980 |
/* Methods */
|
981 |
|
982 |
/* Properties */
|
983 |
|
984 |
/**
|
985 |
-
*
|
986 |
-
*
|
987 |
-
*
|
988 |
-
* @
|
989 |
-
|
990 |
-
|
991 |
-
var ret = false;
|
992 |
-
if ( this.util.in_obj(this._status, id) ) {
|
993 |
-
ret = ( !!raw ) ? this._status[id] : !!this._status[id];
|
994 |
-
}
|
995 |
-
return ret;
|
996 |
-
},
|
997 |
-
|
998 |
-
/**
|
999 |
-
* Set status
|
1000 |
-
* @param string id Status to retrieve
|
1001 |
-
* @param mixed val Status value (Default: TRUE)
|
1002 |
-
* @return mixed Status value (Default: bool)
|
1003 |
*/
|
1004 |
-
|
1005 |
-
//
|
1006 |
-
if ( this.util.
|
1007 |
-
|
1008 |
-
val = true;
|
1009 |
-
}
|
1010 |
-
//Initialize property
|
1011 |
-
if ( !this.util.is_obj(this._status, false) ) {
|
1012 |
-
this._status = {};
|
1013 |
-
}
|
1014 |
-
//Set status
|
1015 |
-
this._status[id] = val;
|
1016 |
-
} else if ( !this.util.is_set(val) ) {
|
1017 |
-
val = false;
|
1018 |
}
|
1019 |
-
return
|
1020 |
},
|
1021 |
|
1022 |
/**
|
@@ -1027,12 +907,9 @@ var Component = {
|
|
1027 |
* @return string Instance ID
|
1028 |
*/
|
1029 |
get_id: function(ns) {
|
1030 |
-
//
|
1031 |
-
|
1032 |
-
|
1033 |
-
}
|
1034 |
-
var id = this.id;
|
1035 |
-
//Namespace ID
|
1036 |
if ( this.util.is_bool(ns) && ns ) {
|
1037 |
id = this.add_ns(id);
|
1038 |
}
|
@@ -1040,35 +917,6 @@ var Component = {
|
|
1040 |
return id;
|
1041 |
},
|
1042 |
|
1043 |
-
/**
|
1044 |
-
* Set instance ID
|
1045 |
-
* @param string id Unique ID
|
1046 |
-
*/
|
1047 |
-
set_id: function(id) {
|
1048 |
-
this.id = ( this.check_id(id) ) ? id : '';
|
1049 |
-
},
|
1050 |
-
|
1051 |
-
/**
|
1052 |
-
* Validate ID value
|
1053 |
-
* @param string id (optional) ID value (Default: Component ID)
|
1054 |
-
* @param bool nonempty (optional) TRUE if it should also check for empty strings, FALSE otherwise (Default: FALSE)
|
1055 |
-
* @return bool TRUE if ID is valid, FALSE otherwise
|
1056 |
-
*/
|
1057 |
-
check_id: function(id, nonempty) {
|
1058 |
-
//Validate
|
1059 |
-
if ( arguments.length == 1 && this.util.is_bool(arguments[0]) ) {
|
1060 |
-
nonempty = arguments[0];
|
1061 |
-
id = null;
|
1062 |
-
}
|
1063 |
-
if ( this.util.is_empty(id) ) {
|
1064 |
-
id = this.id;
|
1065 |
-
}
|
1066 |
-
if ( !this.util.is_bool(nonempty) ) {
|
1067 |
-
nonempty = false;
|
1068 |
-
}
|
1069 |
-
return ( this.util.is_string(id, nonempty) ) ? true : false;
|
1070 |
-
},
|
1071 |
-
|
1072 |
/**
|
1073 |
* Get namespace
|
1074 |
* @uses _slug for namespace segment
|
@@ -1076,7 +924,10 @@ var Component = {
|
|
1076 |
* @return string Component namespace
|
1077 |
*/
|
1078 |
get_ns: function() {
|
1079 |
-
|
|
|
|
|
|
|
1080 |
},
|
1081 |
|
1082 |
/**
|
@@ -1088,30 +939,56 @@ var Component = {
|
|
1088 |
return ( this.util.is_string(val) ) ? this.get_ns() + '_' + val : '';
|
1089 |
},
|
1090 |
|
1091 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1092 |
|
1093 |
/**
|
1094 |
-
*
|
1095 |
-
* @
|
1096 |
-
* @
|
|
|
1097 |
*/
|
1098 |
-
|
1099 |
-
//
|
1100 |
-
if (
|
1101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1102 |
}
|
1103 |
-
|
1104 |
-
return this._containers;
|
1105 |
},
|
1106 |
|
1107 |
/**
|
1108 |
-
*
|
1109 |
-
* @
|
|
|
1110 |
*/
|
1111 |
-
|
1112 |
-
return
|
1113 |
},
|
1114 |
|
|
|
|
|
1115 |
/**
|
1116 |
* Check if reference exists in object
|
1117 |
* @param string ref Reference ID
|
@@ -1140,115 +1017,54 @@ var Component = {
|
|
1140 |
return ( this.has_reference(ref) ) ? this._refs[ref] : null;
|
1141 |
},
|
1142 |
|
1143 |
-
/**
|
1144 |
-
* Checks if component is valid
|
1145 |
-
* @param obj|string Component instance or ID
|
1146 |
-
* > If ID is specified then it will check for component on current instance
|
1147 |
-
* @param function|string ctype Component type
|
1148 |
-
* > If component is an object, then ctype is required
|
1149 |
-
* > If component is string ID, then ctype is optional (Default: reference type)
|
1150 |
-
* > If ctype is a function, then it is compared to component directly
|
1151 |
-
* > If ctype is a string, then the component reference type is retrieved
|
1152 |
-
* @uses get_reference()
|
1153 |
-
* @return bool TRUE if component is valid, FALSE otherwise
|
1154 |
-
*/
|
1155 |
-
check_component: function(comp, ctype) {
|
1156 |
-
//Validate
|
1157 |
-
if ( this.util.is_empty(comp)
|
1158 |
-
|| ( this.util.is_obj(comp) && !this.util.is_func(ctype) )
|
1159 |
-
|| ( this.util.is_string(comp) && !this.has_reference(comp) )
|
1160 |
-
|| ( this.util.is_empty(ctype) && !this.util.is_string(comp) )
|
1161 |
-
|| ( !this.util.is_obj(comp) && !this.util.is_string(comp) )
|
1162 |
-
) {
|
1163 |
-
return false;
|
1164 |
-
}
|
1165 |
-
//Get component type
|
1166 |
-
if ( !this.util.is_func(ctype) ) {
|
1167 |
-
//Component is a string ID
|
1168 |
-
ctype = this.get_reference(comp);
|
1169 |
-
}
|
1170 |
-
//Get component instance
|
1171 |
-
if ( this.util.is_string(comp) ) {
|
1172 |
-
comp = this.get_component(comp, false);
|
1173 |
-
}
|
1174 |
-
return this.util.is_type(comp, ctype);
|
1175 |
-
},
|
1176 |
-
|
1177 |
/**
|
1178 |
* Retrieve component reference from current object
|
1179 |
* > Procedure:
|
1180 |
-
* > Check if property already set
|
1181 |
* > Check attributes
|
1182 |
-
* > Check
|
1183 |
-
* > Check parent object (controller)
|
1184 |
-
* @uses _containers to check potential container components for references
|
1185 |
* @param string cname Component name
|
1186 |
-
* @param
|
1187 |
-
*
|
1188 |
-
*
|
1189 |
* @return object|null Component reference (NULL if no component found)
|
1190 |
*/
|
1191 |
-
get_component: function(cname,
|
1192 |
var c = null;
|
1193 |
-
//Validate request
|
1194 |
-
if ( !this.
|
1195 |
return c;
|
1196 |
}
|
1197 |
|
1198 |
-
//
|
1199 |
-
|
1200 |
-
check_attr
|
1201 |
-
|
1202 |
-
|
1203 |
-
|
1204 |
-
|
1205 |
-
|
1206 |
-
|
1207 |
-
|
1208 |
-
|
1209 |
-
//Phase 1: Check if component reference previously set
|
1210 |
if ( this.util.is_type(this[cname], ctype) ) {
|
1211 |
return this[cname];
|
1212 |
}
|
1213 |
-
//If reference not set, iterate through component hierarchy until reference is found
|
1214 |
c = this[cname] = null;
|
1215 |
|
1216 |
-
//Phase 2: Check attributes
|
1217 |
-
if ( check_attr ) {
|
1218 |
c = this.get_attribute(cname);
|
1219 |
-
//Save object-specific component reference
|
1220 |
if ( !this.util.is_empty(c) ) {
|
1221 |
c = this.set_component(cname, c);
|
1222 |
}
|
1223 |
}
|
1224 |
-
|
1225 |
-
//Phase 3: Check Container(s)
|
1226 |
-
if ( recursive && this.util.is_empty(c) && this.has_containers() ) {
|
1227 |
-
var containers = this.get_containers();
|
1228 |
-
var con = null;
|
1229 |
-
for ( var i = 0; i < containers.length; i++ ) {
|
1230 |
-
con = containers[i];
|
1231 |
-
//Validate container
|
1232 |
-
if ( con == cname ) {
|
1233 |
-
continue;
|
1234 |
-
}
|
1235 |
-
//Retrieve container
|
1236 |
-
con = this.get_component(con, true, false);
|
1237 |
-
if ( this.util.is_empty(con) ) {
|
1238 |
-
continue;
|
1239 |
-
}
|
1240 |
-
//Attempt to retrieve component from container
|
1241 |
-
c = con.get_component(cname);
|
1242 |
-
//Stop iterating if valid component found
|
1243 |
-
if ( !this.util.is_empty(c) ) {
|
1244 |
-
break;
|
1245 |
-
}
|
1246 |
-
}
|
1247 |
-
}
|
1248 |
|
1249 |
-
//Phase
|
1250 |
-
if (
|
1251 |
-
c = this.
|
1252 |
}
|
1253 |
return c;
|
1254 |
},
|
@@ -1262,106 +1078,119 @@ var Component = {
|
|
1262 |
* @return object Component (NULL if invalid)
|
1263 |
*/
|
1264 |
set_component: function(name, ref, validate) {
|
1265 |
-
var
|
1266 |
-
//Make sure component property exists
|
1267 |
if ( !this.has_reference(name) ) {
|
1268 |
-
return
|
1269 |
}
|
1270 |
-
|
|
|
1271 |
if ( this.util.is_empty(ref) ) {
|
1272 |
-
ref =
|
1273 |
-
}
|
1274 |
-
|
1275 |
-
|
1276 |
-
|
1277 |
-
|
1278 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1279 |
}
|
1280 |
|
1281 |
-
|
1282 |
-
ref = clear;
|
1283 |
-
}
|
1284 |
-
|
1285 |
-
//Additional validation
|
1286 |
-
if ( !this.util.is_empty(ref) && this.util.is_func(validate) && !validate.call(this, ref) ) {
|
1287 |
-
ref = clear;
|
1288 |
-
}
|
1289 |
-
//Set (or clear) component reference
|
1290 |
this[name] = ref;
|
1291 |
-
//Return value for confirmation
|
1292 |
return this[name];
|
1293 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1294 |
|
1295 |
/* Attributes */
|
1296 |
|
1297 |
/**
|
1298 |
-
*
|
|
|
|
|
1299 |
*/
|
1300 |
init_attributes: function(force) {
|
1301 |
if ( !this.util.is_bool(force) ) {
|
1302 |
force = false;
|
1303 |
}
|
1304 |
-
if ( force || !this.util.is_obj(this.
|
1305 |
-
this.
|
1306 |
-
//
|
1307 |
-
|
1308 |
-
|
1309 |
-
if ( this.dom_has() ) {
|
1310 |
-
attrs.push(this.get_dom_attributes());
|
1311 |
-
}
|
1312 |
if ( this.util.is_obj(this._attr_init) ) {
|
1313 |
-
|
1314 |
}
|
1315 |
-
//
|
1316 |
-
|
1317 |
}
|
1318 |
},
|
1319 |
|
1320 |
/**
|
1321 |
* Generate default attributes for component
|
1322 |
-
* @uses _attr_parent to determine options to retrieve from controller
|
1323 |
* @uses View.get_options() to get values from controller
|
1324 |
* @uses _attr_map to Remap controller attributes to instance attributes
|
1325 |
* @uses _attr_default to Store default attributes
|
|
|
1326 |
*/
|
1327 |
init_default_attributes: function() {
|
1328 |
-
//Get
|
1329 |
-
|
1330 |
-
|
1331 |
-
|
1332 |
-
|
1333 |
-
|
1334 |
-
|
1335 |
-
opts
|
1336 |
-
|
1337 |
-
|
|
|
|
|
|
|
1338 |
}
|
|
|
|
|
1339 |
}
|
1340 |
-
|
1341 |
-
$.extend(true, this._attr_default, opts);
|
1342 |
}
|
1343 |
return this._attr_default;
|
1344 |
},
|
1345 |
|
1346 |
/**
|
1347 |
* Retrieve DOM attributes
|
|
|
1348 |
*/
|
1349 |
get_dom_attributes: function() {
|
1350 |
var attrs = {};
|
1351 |
-
var el = this.dom_get();
|
1352 |
-
if ( el.length ) {
|
1353 |
-
//Get attributes from element
|
1354 |
-
var
|
1355 |
-
if ( this.util.is_obj(
|
1356 |
var attr_prefix = this.util.get_attribute();
|
1357 |
-
|
1358 |
-
|
|
|
1359 |
return true;
|
1360 |
}
|
1361 |
-
//Process custom attributes
|
1362 |
-
|
1363 |
-
|
1364 |
-
attrs[key] = opt.value;
|
1365 |
});
|
1366 |
}
|
1367 |
}
|
@@ -1370,15 +1199,15 @@ var Component = {
|
|
1370 |
|
1371 |
/**
|
1372 |
* Retrieve all instance attributes
|
1373 |
-
* @uses
|
1374 |
-
* @uses
|
1375 |
-
* @return obj
|
1376 |
*/
|
1377 |
get_attributes: function() {
|
1378 |
-
//Initilize attributes
|
1379 |
this.init_attributes();
|
1380 |
-
//Return attributes
|
1381 |
-
return this.
|
1382 |
},
|
1383 |
|
1384 |
/**
|
@@ -1391,7 +1220,7 @@ var Component = {
|
|
1391 |
* @return mixed Attribute value (NULL if attribute is not set)
|
1392 |
*/
|
1393 |
get_attribute: function(key, def, enforce_type) {
|
1394 |
-
//Validate
|
1395 |
if ( !this.util.is_set(def) ) {
|
1396 |
def = null;
|
1397 |
}
|
@@ -1401,30 +1230,35 @@ var Component = {
|
|
1401 |
if ( !this.util.is_bool(enforce_type) ) {
|
1402 |
enforce_type = true;
|
1403 |
}
|
1404 |
-
|
|
|
1405 |
var ret = ( this.has_attribute(key) ) ? this.get_attributes()[key] : def;
|
1406 |
-
//Validate type
|
1407 |
if ( enforce_type && ret !== def && null !== def && !this.util.is_type(ret, $.type(def), false) ) {
|
1408 |
-
//Convert type
|
1409 |
-
//Scalar default
|
1410 |
if ( this.util.is_scalar(def, false) ) {
|
1411 |
-
//Non-scalar attribute
|
1412 |
if ( !this.util.is_scalar(ret, false) ) {
|
|
|
1413 |
ret = def;
|
1414 |
} else if ( this.util.is_string(def, false) ) {
|
|
|
1415 |
ret = ret.toString();
|
1416 |
} else if ( this.util.is_num(def, false) && !this.util.is_num(ret, false) ) {
|
|
|
1417 |
ret = ( this.util.is_int(def, false) ) ? parseInt(ret) : parseFloat(ret);
|
1418 |
if ( !this.util.is_num(ret, false) ) {
|
1419 |
ret = def;
|
1420 |
}
|
1421 |
} else if ( this.util.is_bool(def, false) ) {
|
|
|
1422 |
ret = ( this.util.is_string(ret) || ( this.util.is_num(ret) ) );
|
1423 |
} else {
|
|
|
1424 |
ret = def;
|
1425 |
}
|
1426 |
}
|
1427 |
-
//Non-scalar default
|
1428 |
else {
|
1429 |
ret = def;
|
1430 |
}
|
@@ -1436,13 +1270,14 @@ var Component = {
|
|
1436 |
* Call attribute as method
|
1437 |
* @param string attr Attribute to call
|
1438 |
* @param arguments (optional) Additional arguments to pass to method
|
|
|
1439 |
*/
|
1440 |
call_attribute: function(attr, args) {
|
1441 |
attr = this.get_attribute(attr);
|
1442 |
if ( this.util.is_func(attr) ) {
|
1443 |
-
//Get arguments
|
1444 |
-
|
1445 |
-
//Pass arguments to user-defined method
|
1446 |
attr = attr.apply(this, args);
|
1447 |
}
|
1448 |
return attr;
|
@@ -1454,7 +1289,7 @@ var Component = {
|
|
1454 |
* @return bool TRUE if exists, FALSE otherwise
|
1455 |
*/
|
1456 |
has_attribute: function(key) {
|
1457 |
-
return ( key in this.get_attributes() );
|
1458 |
},
|
1459 |
|
1460 |
/**
|
@@ -1463,16 +1298,17 @@ var Component = {
|
|
1463 |
* @param bool full (optional) Whether to fully replace or merge component's attributes with new values (Default: Merge)
|
1464 |
*/
|
1465 |
set_attributes: function(attributes, full) {
|
|
|
1466 |
if ( !this.util.is_bool(full) ) {
|
1467 |
full = false;
|
1468 |
}
|
1469 |
|
1470 |
-
//Initialize attributes
|
1471 |
this.init_attributes(full);
|
1472 |
|
1473 |
-
//Merge new/existing attributes
|
1474 |
if ( this.util.is_obj(attributes) ) {
|
1475 |
-
$.extend(this.
|
1476 |
}
|
1477 |
},
|
1478 |
|
@@ -1481,6 +1317,7 @@ var Component = {
|
|
1481 |
* @uses get_attributes() to retrieve attributes
|
1482 |
* @param string key Attribute to set
|
1483 |
* @param mixed val Attribute value
|
|
|
1484 |
*/
|
1485 |
set_attribute: function(key, val) {
|
1486 |
if ( this.util.is_string(key) && this.util.is_set(val) ) {
|
@@ -1512,9 +1349,9 @@ var Component = {
|
|
1512 |
*/
|
1513 |
dom_set: function(el) {
|
1514 |
el = $(el);
|
1515 |
-
//Save instance to DOM object
|
1516 |
el.data(this.get_data_key(), this);
|
1517 |
-
//Save DOM object to instance
|
1518 |
if ( this._reciprocal ) {
|
1519 |
this._dom = el;
|
1520 |
}
|
@@ -1525,27 +1362,34 @@ var Component = {
|
|
1525 |
* Retrieve attached DOM element
|
1526 |
* @uses _dom to retrieve attached DOM element
|
1527 |
* @uses dom_put() to insert child element
|
1528 |
-
* @param string element
|
1529 |
* @param bool put (optional) Whether to insert element if it does not exist (Default: FALSE)
|
1530 |
-
* @param obj options (optional)
|
1531 |
* @return obj jQuery DOM element
|
1532 |
*/
|
1533 |
-
dom_get: function(element,
|
1534 |
-
//
|
1535 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1536 |
this.set_status('dom_init');
|
1537 |
this.dom_init();
|
1538 |
}
|
1539 |
-
//Check for main DOM element
|
1540 |
var ret = this._dom;
|
1541 |
if ( !!ret && this.util.is_string(element) ) {
|
1542 |
var ch = $(ret).find( this.dom_get_selector(element) );
|
1543 |
-
//Check for child element
|
1544 |
if ( ch.length ) {
|
1545 |
ret = ch;
|
1546 |
-
} else if ( this.util.
|
1547 |
-
//Insert child element
|
1548 |
-
ret = this.dom_put(element, options);
|
1549 |
}
|
1550 |
}
|
1551 |
return $(ret);
|
@@ -1562,24 +1406,24 @@ var Component = {
|
|
1562 |
* Wrapper element created and added to main DOM element if not yet created
|
1563 |
* @param string element ID for DOM element (Used as class name for wrapper)
|
1564 |
* @param string|jQuery|obj content Content to add to DOM (Object contains element properties)
|
1565 |
-
*
|
1566 |
-
*
|
1567 |
* @return jQuery Inserted element(s)
|
1568 |
*/
|
1569 |
dom_put: function(element, content) {
|
1570 |
var r = null;
|
1571 |
-
//Stop processing if main DOM element not set or element is not valid
|
1572 |
if ( !this.dom_has() || !this.util.is_string(element) ) {
|
1573 |
return $(r);
|
1574 |
}
|
1575 |
-
//Setup options
|
1576 |
-
var strip = ['tag', 'content', '
|
1577 |
var options = {
|
1578 |
'tag': 'div',
|
1579 |
'content': '',
|
1580 |
'class': this.add_ns(element)
|
1581 |
-
}
|
1582 |
-
//Setup content
|
1583 |
if ( !this.util.is_empty(content) ) {
|
1584 |
if ( this.util.is_type(content, jQuery, false) || this.util.is_string(content, false) ) {
|
1585 |
options.content = content;
|
@@ -1592,17 +1436,17 @@ var Component = {
|
|
1592 |
for ( var x = 0; x < strip.length; x++ ) {
|
1593 |
delete attrs[strip[x]];
|
1594 |
}
|
1595 |
-
//Retrieve existing element
|
1596 |
var d = this.dom_get();
|
1597 |
r = $(this.dom_get_selector(element), d);
|
1598 |
-
//Create element (if necessary)
|
1599 |
if ( !r.length ) {
|
1600 |
r = $(this.util.format('<%s />', options.tag), attrs).appendTo(d);
|
1601 |
-
if ( r.length && this.util.is_method(options, '
|
1602 |
-
options['
|
1603 |
}
|
1604 |
}
|
1605 |
-
//Set content
|
1606 |
$(r).append(options.content);
|
1607 |
return $(r);
|
1608 |
},
|
@@ -1644,17 +1488,17 @@ var Component = {
|
|
1644 |
* @return obj Component instance (allows chaining)
|
1645 |
*/
|
1646 |
on: function(event, fn, options) {
|
1647 |
-
//Handle request types
|
1648 |
if ( !this.util.is_string(event) || !this.util.is_func(fn) ) {
|
1649 |
var t = this;
|
1650 |
var args = Array.prototype.slice.call(arguments, 1);
|
1651 |
if ( this.util.is_array(event) ) {
|
1652 |
-
//Events array
|
1653 |
$.each(event, function(idx, val) {
|
1654 |
t.on.apply(t, [val].concat(args));
|
1655 |
});
|
1656 |
} else if ( this.util.is_obj(event) ) {
|
1657 |
-
//Events map
|
1658 |
$.each(event, function(ev, hdl) {
|
1659 |
t.on.apply(t, [ev, hdl].concat(args));
|
1660 |
});
|
@@ -1662,28 +1506,28 @@ var Component = {
|
|
1662 |
return this;
|
1663 |
}
|
1664 |
|
1665 |
-
//Options
|
1666 |
|
1667 |
-
//Default options
|
1668 |
var options_std = {
|
1669 |
clear: false
|
1670 |
};
|
1671 |
if ( !this.util.is_obj(options, false) ) {
|
1672 |
-
//Reset options
|
1673 |
options = {};
|
1674 |
}
|
1675 |
-
//Build options
|
1676 |
options = $.extend({}, options_std, options);
|
1677 |
-
//Initialize events bucket
|
1678 |
if ( !this.util.is_obj(this._events, false) ) {
|
1679 |
this._events = {};
|
1680 |
}
|
1681 |
-
//Setup event
|
1682 |
var es = this._events;
|
1683 |
if ( !( event in es ) || !this.util.is_obj(es[event], false) || !!options.clear ) {
|
1684 |
es[event] = [];
|
1685 |
}
|
1686 |
-
//Add event handler
|
1687 |
es[event].push(fn);
|
1688 |
return this;
|
1689 |
},
|
@@ -1693,8 +1537,8 @@ var Component = {
|
|
1693 |
* Event handlers are executed in the context of the current component instance
|
1694 |
* Event handlers are passed parameters
|
1695 |
* > ev (obj) Event object
|
1696 |
-
*
|
1697 |
-
*
|
1698 |
* > component (obj) Current component instance
|
1699 |
* @param string event Custom event to trigger
|
1700 |
* @param mixed data (optional) Data to pass to event handlers
|
@@ -1704,36 +1548,36 @@ var Component = {
|
|
1704 |
var dfr = $.Deferred();
|
1705 |
var dfrs = [];
|
1706 |
var t = this;
|
1707 |
-
//Handle array of events
|
1708 |
if ( this.util.is_array(event) ) {
|
1709 |
$.each(event, function(idx, val) {
|
1710 |
-
//Collect promises from triggered events
|
1711 |
dfrs.push( t.trigger(val, data) );
|
1712 |
});
|
1713 |
-
//Resolve trigger when all events have been resolved
|
1714 |
$.when.apply(t, dfrs).done(function() {
|
1715 |
dfr.resolve();
|
1716 |
});
|
1717 |
return dfr.promise();
|
1718 |
}
|
1719 |
-
//Validate
|
1720 |
if ( !this.util.is_string(event) || !( event in this._events ) ) {
|
1721 |
dfr.resolve();
|
1722 |
return dfr.promise();
|
1723 |
}
|
1724 |
-
//Create event object
|
1725 |
var ev = { 'type': event, 'data': null };
|
1726 |
-
//Add data to event object
|
1727 |
if ( this.util.is_set(data) ) {
|
1728 |
ev.data = data;
|
1729 |
}
|
1730 |
-
//Fire handlers for event
|
1731 |
$.each(this._events[event], function(idx, fn) {
|
1732 |
-
//Call handler (`this` set to current instance)
|
1733 |
-
//Collect promises from event handlers
|
1734 |
dfrs.push( fn.call(t, ev, t) );
|
1735 |
});
|
1736 |
-
//Resolve trigger when all handlers have been resolved
|
1737 |
$.when.apply(this, dfrs).done(function() {
|
1738 |
dfr.resolve();
|
1739 |
});
|
@@ -1766,9 +1610,10 @@ var Viewer = {
|
|
1766 |
autofit: true,
|
1767 |
overlay_enabled: true,
|
1768 |
overlay_opacity: '0.8',
|
|
|
1769 |
container: null,
|
1770 |
slideshow_enabled: true,
|
1771 |
-
slideshow_autostart:
|
1772 |
slideshow_duration: 2,
|
1773 |
slideshow_active: false,
|
1774 |
slideshow_timer: null,
|
@@ -1783,18 +1628,17 @@ var Viewer = {
|
|
1783 |
}
|
1784 |
},
|
1785 |
|
1786 |
-
_attr_parent: [
|
1787 |
-
'theme',
|
1788 |
-
'group_loop',
|
1789 |
-
'ui_autofit', 'ui_animate', 'ui_overlay_opacity', 'ui_labels',
|
1790 |
-
'slideshow_enabled', 'slideshow_autostart', 'slideshow_duration'],
|
1791 |
-
|
1792 |
_attr_map: {
|
|
|
1793 |
'group_loop': 'loop',
|
1794 |
'ui_autofit': 'autofit',
|
1795 |
'ui_animate': 'animate',
|
1796 |
'ui_overlay_opacity': 'overlay_opacity',
|
1797 |
-
'ui_labels': 'labels'
|
|
|
|
|
|
|
|
|
1798 |
},
|
1799 |
|
1800 |
/* References */
|
@@ -1830,19 +1674,29 @@ var Viewer = {
|
|
1830 |
|
1831 |
/* Init */
|
1832 |
|
1833 |
-
|
1834 |
var t = this;
|
1835 |
this
|
1836 |
.on(['item-prev', 'item-next'], function() {
|
1837 |
t.trigger('item-change');
|
1838 |
})
|
1839 |
.on(['close', 'item-change'], function() {
|
1840 |
-
t.
|
|
|
|
|
1841 |
});
|
1842 |
},
|
1843 |
|
1844 |
/* References */
|
1845 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1846 |
/**
|
1847 |
* Set item reference
|
1848 |
* Validates item before setting
|
@@ -1850,7 +1704,7 @@ var Viewer = {
|
|
1850 |
* @return bool TRUE if valid item set, FALSE otherwise
|
1851 |
*/
|
1852 |
set_item: function(item) {
|
1853 |
-
//Clear existing item
|
1854 |
this.clear_item(false);
|
1855 |
var i = this.set_component('item', item, function(item) {
|
1856 |
return ( item.has_type() );
|
@@ -1858,8 +1712,13 @@ var Viewer = {
|
|
1858 |
return ( !this.util.is_empty(i) );
|
1859 |
},
|
1860 |
|
|
|
|
|
|
|
|
|
|
|
1861 |
clear_item: function(full) {
|
1862 |
-
//Validate
|
1863 |
if ( !this.util.is_bool(full) ) {
|
1864 |
full = true;
|
1865 |
}
|
@@ -1868,27 +1727,19 @@ var Viewer = {
|
|
1868 |
item.reset();
|
1869 |
}
|
1870 |
if ( full ) {
|
1871 |
-
this.
|
1872 |
}
|
1873 |
},
|
1874 |
|
1875 |
-
/**
|
1876 |
-
* Retrieve item instance current attached to viewer
|
1877 |
-
* @return Content_Item|NULL Current item instance
|
1878 |
-
*/
|
1879 |
-
get_item: function() {
|
1880 |
-
return this.get_component('item', true, false);
|
1881 |
-
},
|
1882 |
-
|
1883 |
/**
|
1884 |
* Retrieve theme reference
|
1885 |
* @return object Theme reference
|
1886 |
*/
|
1887 |
get_theme: function() {
|
1888 |
-
//Get saved theme
|
1889 |
-
var ret = this.get_component('theme',
|
1890 |
if ( this.util.is_empty(ret) ) {
|
1891 |
-
//Theme needs to be initialized
|
1892 |
ret = this.set_component('theme', new View.Theme(this));
|
1893 |
}
|
1894 |
return ret;
|
@@ -1920,7 +1771,7 @@ var Viewer = {
|
|
1920 |
* @return jQuery.Promise Resolved when item processing is complete
|
1921 |
*/
|
1922 |
get_lock: function(simple, full) {
|
1923 |
-
//Validate
|
1924 |
if ( !this.util.is_bool(simple) ) {
|
1925 |
simple = false;
|
1926 |
}
|
@@ -1928,14 +1779,14 @@ var Viewer = {
|
|
1928 |
full = false;
|
1929 |
}
|
1930 |
var s = 'item_working';
|
1931 |
-
//Simple status
|
1932 |
if ( simple ) {
|
1933 |
return this.get_status(s);
|
1934 |
}
|
1935 |
-
//Full value
|
1936 |
var r = this.get_status(s, true);
|
1937 |
if ( !this.util.is_promise(r) ) {
|
1938 |
-
//Create default
|
1939 |
r = this.lock();
|
1940 |
}
|
1941 |
return ( full ) ? r : r.promise();
|
@@ -1985,15 +1836,15 @@ var Viewer = {
|
|
1985 |
mode = true;
|
1986 |
}
|
1987 |
this.loading = mode;
|
1988 |
-
//Pause/Resume slideshow
|
1989 |
if ( this.slideshow_active() ) {
|
1990 |
this.slideshow_pause(mode);
|
1991 |
}
|
1992 |
-
//Set CSS class on DOM element
|
1993 |
var m = ( mode ) ? 'addClass' : 'removeClass';
|
1994 |
$(this.dom_get())[m]('loading');
|
1995 |
if ( mode ) {
|
1996 |
-
//Loading transition
|
1997 |
this.get_theme().transition('load').always(function() {
|
1998 |
dfr.resolve();
|
1999 |
});
|
@@ -2038,13 +1889,14 @@ var Viewer = {
|
|
2038 |
show: function(item) {
|
2039 |
this.item_queued = item;
|
2040 |
var fin_set = 'show_deferred';
|
2041 |
-
//Validate theme
|
2042 |
var vt = 'theme_valid';
|
2043 |
var valid = true;
|
2044 |
-
if (
|
2045 |
-
valid = this.set_attribute(vt, ( this.get_theme() && this.get_theme().get_template().get_layout(false) ) );
|
2046 |
-
} else {
|
2047 |
valid = this.get_attribute(vt, true);
|
|
|
|
|
|
|
2048 |
}
|
2049 |
|
2050 |
if ( !valid ) {
|
@@ -2053,26 +1905,26 @@ var Viewer = {
|
|
2053 |
}
|
2054 |
var v = this;
|
2055 |
var fin = function() {
|
2056 |
-
//Lock viewer
|
2057 |
v.lock();
|
2058 |
-
//Reset callback flag (for new lock)
|
2059 |
v.set_status(fin_set, false);
|
2060 |
-
//Validate request
|
2061 |
if ( !v.set_item(v.item_queued) ) {
|
2062 |
v.close();
|
2063 |
return false;
|
2064 |
}
|
2065 |
-
//Add item to history stack
|
2066 |
v.history_add();
|
2067 |
-
//Activate
|
2068 |
v.set_active();
|
2069 |
-
//Display
|
2070 |
v.render();
|
2071 |
-
}
|
2072 |
if ( !this.is_locked() ) {
|
2073 |
fin();
|
2074 |
} else if ( !this.get_status(fin_set) ) {
|
2075 |
-
//Set flag to avoid duplicate callbacks
|
2076 |
this.set_status(fin_set);
|
2077 |
this.get_lock().always(function() {
|
2078 |
fin();
|
@@ -2084,16 +1936,16 @@ var Viewer = {
|
|
2084 |
|
2085 |
history_handle: function(e) {
|
2086 |
var state = e.originalEvent.state;
|
2087 |
-
//Load item
|
2088 |
-
if ( this.util.
|
2089 |
-
this.
|
2090 |
this.trigger('item-change');
|
2091 |
} else {
|
2092 |
var count = this.history_get(true);
|
2093 |
-
//Reset count
|
2094 |
this.history_set(0);
|
2095 |
-
//Close viewer
|
2096 |
-
if ( -1
|
2097 |
this.close();
|
2098 |
}
|
2099 |
}
|
@@ -2109,24 +1961,24 @@ var Viewer = {
|
|
2109 |
if ( !history.pushState ) {
|
2110 |
return false;
|
2111 |
}
|
2112 |
-
//Get display options
|
2113 |
var item = this.get_item();
|
2114 |
var opts = item.get_attribute('options_show');
|
2115 |
-
//Save history state
|
2116 |
var count = ( this.history_get() ) ? this.history_get(true) : 0;
|
2117 |
if ( !this.util.in_obj(opts, 'event') ) {
|
2118 |
-
//Create state
|
2119 |
var state = {
|
2120 |
'viewer': this.get_id(),
|
2121 |
'item': null,
|
2122 |
'count': count
|
2123 |
};
|
2124 |
-
//Init: Save viewer state
|
2125 |
if ( !count ) {
|
2126 |
history.replaceState(state, null);
|
2127 |
}
|
2128 |
-
//Always: Save item state
|
2129 |
-
state.item = this.
|
2130 |
state.count = ++count;
|
2131 |
history.pushState(state, '');
|
2132 |
} else {
|
@@ -2135,15 +1987,15 @@ var Viewer = {
|
|
2135 |
count = e.state.count;
|
2136 |
}
|
2137 |
}
|
2138 |
-
//Save history item count
|
2139 |
this.history_set(count);
|
2140 |
},
|
2141 |
history_reset: function() {
|
2142 |
var count = this.history_get(true);
|
2143 |
if ( count ) {
|
2144 |
-
//Clear history status
|
2145 |
this.history_set(-1);
|
2146 |
-
//Restore history stack
|
2147 |
history.go( -1 * count );
|
2148 |
}
|
2149 |
},
|
@@ -2154,21 +2006,22 @@ var Viewer = {
|
|
2154 |
* @return bool TRUE if viewer is open, FALSE otherwise
|
2155 |
*/
|
2156 |
is_open: function() {
|
2157 |
-
return ( this.dom_get().css('display')
|
2158 |
},
|
2159 |
|
2160 |
/**
|
2161 |
* Load output into DOM
|
2162 |
*/
|
2163 |
render: function() {
|
2164 |
-
//Get theme output
|
2165 |
var v = this;
|
2166 |
var thm = this.get_theme();
|
2167 |
-
|
|
|
2168 |
if ( !this.get_status('render-events') ) {
|
2169 |
this.set_status('render-events');
|
2170 |
thm
|
2171 |
-
//Loading
|
2172 |
.on('render-loading', function(ev, thm) {
|
2173 |
var dfr = $.Deferred();
|
2174 |
if ( !v.is_active() ) {
|
@@ -2176,11 +2029,11 @@ var Viewer = {
|
|
2176 |
return dfr.promise();
|
2177 |
}
|
2178 |
var set_pos = function() {
|
2179 |
-
//Set position
|
2180 |
v.dom_get().css('top', $(window).scrollTop());
|
2181 |
};
|
2182 |
var always = function() {
|
2183 |
-
//Set loading flag
|
2184 |
v.set_loading().always(function() {
|
2185 |
dfr.resolve();
|
2186 |
});
|
@@ -2200,21 +2053,21 @@ var Viewer = {
|
|
2200 |
v.open = true;
|
2201 |
})
|
2202 |
.fail(function() {
|
2203 |
-
|
2204 |
-
//Fallback open
|
2205 |
v.get_overlay().show();
|
2206 |
v.dom_get().show();
|
2207 |
});
|
2208 |
}
|
2209 |
return dfr.promise();
|
2210 |
})
|
2211 |
-
//Complete
|
2212 |
.on('render-complete', function(ev, thm) {
|
2213 |
-
//Stop if viewer not active
|
2214 |
if ( !v.is_active() ) {
|
2215 |
return false;
|
2216 |
}
|
2217 |
-
//Set classes
|
2218 |
var d = v.dom_get();
|
2219 |
var classes = ['item_single', 'item_multi'];
|
2220 |
var ms = ['addClass', 'removeClass'];
|
@@ -2224,28 +2077,28 @@ var Viewer = {
|
|
2224 |
$.each(ms, function(idx, val) {
|
2225 |
d[val](classes[idx]);
|
2226 |
});
|
2227 |
-
//Bind events
|
2228 |
v.events_complete();
|
2229 |
-
//Transition
|
2230 |
thm.transition('complete')
|
2231 |
.fail(function() {
|
2232 |
-
//Autofit content
|
2233 |
if ( v.get_attribute('autofit', true) ) {
|
2234 |
var dims = $.extend({'display': 'inline-block'}, thm.get_item_dimensions());
|
2235 |
-
|
2236 |
}
|
2237 |
})
|
2238 |
.always(function() {
|
2239 |
-
//Unset loading flag
|
2240 |
v.unset_loading();
|
2241 |
-
//Trigger event
|
2242 |
v.trigger('render-complete');
|
2243 |
-
//Set viewer as initialized
|
2244 |
v.init = true;
|
2245 |
});
|
2246 |
});
|
2247 |
}
|
2248 |
-
//Render
|
2249 |
thm.render();
|
2250 |
},
|
2251 |
|
@@ -2256,16 +2109,16 @@ var Viewer = {
|
|
2256 |
*/
|
2257 |
dom_get_container: function() {
|
2258 |
var sel = this.get_attribute('container');
|
2259 |
-
//Set default container
|
2260 |
if ( this.util.is_empty(sel) ) {
|
2261 |
sel = '#' + this.add_ns('wrap');
|
2262 |
}
|
2263 |
-
//Add default container to DOM if not yet present
|
2264 |
var c = $(sel);
|
2265 |
if ( !c.length ) {
|
2266 |
-
//Prepare ID
|
2267 |
var id = ( sel.indexOf('#') === 0 ) ? sel.substr(1) : sel;
|
2268 |
-
//Add element
|
2269 |
c = $('<div />', {'id': id}).appendTo('body');
|
2270 |
}
|
2271 |
return c;
|
@@ -2275,40 +2128,51 @@ var Viewer = {
|
|
2275 |
* Custom Viewer DOM initialization
|
2276 |
*/
|
2277 |
dom_init: function() {
|
2278 |
-
//Create element & add to DOM
|
2279 |
-
//Save element to instance
|
2280 |
var d = this.dom_set($('<div/>', {
|
2281 |
'id': this.get_id(true),
|
2282 |
'class': this.get_ns()
|
2283 |
})).appendTo(this.dom_get_container()).hide();
|
2284 |
-
//Add theme classes
|
2285 |
var thm = this.get_theme();
|
2286 |
d.addClass(thm.get_classes(' '));
|
2287 |
-
//Add theme layout (basic)
|
2288 |
var v = this;
|
2289 |
if ( !this.get_status('render-init') ) {
|
2290 |
this.set_status('render-init');
|
2291 |
thm.on('render-init', function(ev) {
|
2292 |
-
//Add rendered theme layout to viewer DOM
|
2293 |
v.dom_put('layout', ev.data);
|
2294 |
});
|
2295 |
}
|
2296 |
thm.render(true);
|
2297 |
},
|
2298 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2299 |
/**
|
2300 |
* Restore DOM
|
2301 |
-
*
|
2302 |
-
* @TODO Build functionality
|
2303 |
*/
|
2304 |
-
dom_restore: function() {
|
|
|
|
|
2305 |
|
2306 |
/* Layout */
|
2307 |
|
2308 |
get_layout: function() {
|
2309 |
-
var ret = this.dom_get('layout',
|
2310 |
-
'
|
2311 |
-
|
|
|
|
|
2312 |
}
|
2313 |
});
|
2314 |
return ret;
|
@@ -2339,38 +2203,47 @@ var Viewer = {
|
|
2339 |
var o = null;
|
2340 |
var v = this;
|
2341 |
if ( this.overlay_enabled() ) {
|
2342 |
-
o = this.dom_get('overlay',
|
2343 |
-
'
|
2344 |
-
|
|
|
|
|
2345 |
}
|
2346 |
});
|
2347 |
}
|
2348 |
return $(o);
|
2349 |
},
|
2350 |
|
|
|
|
|
|
|
2351 |
unload: function() {
|
2352 |
-
|
|
|
|
|
|
|
|
|
2353 |
},
|
2354 |
|
2355 |
/**
|
2356 |
* Reset viewer
|
2357 |
*/
|
2358 |
reset: function() {
|
2359 |
-
//Hide viewer
|
2360 |
this.dom_get().hide();
|
2361 |
-
//Restore DOM
|
2362 |
this.dom_restore();
|
2363 |
-
//History
|
2364 |
this.history_reset();
|
2365 |
-
//Item
|
2366 |
this.clear_item();
|
2367 |
-
//Reset properties
|
2368 |
this.set_active(false);
|
2369 |
this.set_loading(false);
|
2370 |
this.slideshow_stop();
|
2371 |
this.keys_disable();
|
2372 |
-
//Clear for next item
|
2373 |
-
this.
|
2374 |
},
|
2375 |
|
2376 |
/* Content */
|
@@ -2390,13 +2263,13 @@ var Viewer = {
|
|
2390 |
* Initialize event handlers upon opening lightbox
|
2391 |
*/
|
2392 |
events_open: function() {
|
2393 |
-
//Keyboard bindings
|
2394 |
this.keys_enable();
|
2395 |
if ( this.open ) {
|
2396 |
return false;
|
2397 |
}
|
2398 |
|
2399 |
-
//Control event bubbling
|
2400 |
var l = this.get_layout();
|
2401 |
l.children().click(function(ev) {
|
2402 |
ev.stopPropagation();
|
@@ -2406,12 +2279,12 @@ var Viewer = {
|
|
2406 |
var v = this;
|
2407 |
var close = function() {
|
2408 |
v.close();
|
2409 |
-
}
|
2410 |
-
//Layout
|
2411 |
l.click(close);
|
2412 |
-
//Overlay
|
2413 |
this.get_overlay().click(close);
|
2414 |
-
//Fire event
|
2415 |
this.trigger('events-open');
|
2416 |
},
|
2417 |
|
@@ -2422,7 +2295,7 @@ var Viewer = {
|
|
2422 |
if ( this.init ) {
|
2423 |
return false;
|
2424 |
}
|
2425 |
-
//Fire event
|
2426 |
this.trigger('events-complete');
|
2427 |
},
|
2428 |
|
@@ -2434,7 +2307,7 @@ var Viewer = {
|
|
2434 |
var v = this;
|
2435 |
var h = function(ev) {
|
2436 |
return v.keys_control(ev);
|
2437 |
-
}
|
2438 |
if ( mode ) {
|
2439 |
$(document).on(e, h);
|
2440 |
} else {
|
@@ -2448,10 +2321,15 @@ var Viewer = {
|
|
2448 |
|
2449 |
keys_control: function(ev) {
|
2450 |
var handlers = {
|
2451 |
-
27: this.close,
|
2452 |
-
37: this.item_prev,
|
2453 |
-
39: this.item_next
|
2454 |
};
|
|
|
|
|
|
|
|
|
|
|
2455 |
if ( ev.which in handlers ) {
|
2456 |
handlers[ev.which].call(this);
|
2457 |
return false;
|
@@ -2499,15 +2377,15 @@ var Viewer = {
|
|
2499 |
}
|
2500 |
this.set_attribute('slideshow_active', true);
|
2501 |
this.dom_get().addClass('slideshow_active');
|
2502 |
-
//Clear residual timers
|
2503 |
this.slideshow_clear_timer();
|
2504 |
-
//Start timer
|
2505 |
var v = this;
|
2506 |
this.slideshow_set_timer(function() {
|
2507 |
-
//Pause slideshow until next item fully loaded
|
2508 |
v.slideshow_pause();
|
2509 |
|
2510 |
-
//Show next item
|
2511 |
v.item_next();
|
2512 |
});
|
2513 |
this.trigger('slideshow-start');
|
@@ -2525,7 +2403,7 @@ var Viewer = {
|
|
2525 |
this.set_attribute('slideshow_active', false);
|
2526 |
this.dom_get().removeClass('slideshow_active');
|
2527 |
}
|
2528 |
-
//Kill timers
|
2529 |
this.slideshow_clear_timer();
|
2530 |
this.trigger('slideshow-stop');
|
2531 |
},
|
@@ -2547,17 +2425,17 @@ var Viewer = {
|
|
2547 |
* @param bool mode (optional) Pause (TRUE) or Resume (FALSE) slideshow (default: TRUE)
|
2548 |
*/
|
2549 |
slideshow_pause: function(mode) {
|
2550 |
-
//Validate
|
2551 |
if ( !this.util.is_bool(mode) ) {
|
2552 |
mode = true;
|
2553 |
}
|
2554 |
-
//Set viewer slideshow properties
|
2555 |
if ( this.slideshow_active() ) {
|
2556 |
if ( !mode ) {
|
2557 |
-
//Slideshow resumed
|
2558 |
this.slideshow_start();
|
2559 |
} else {
|
2560 |
-
//Slideshow paused
|
2561 |
this.slideshow_stop(false);
|
2562 |
}
|
2563 |
}
|
@@ -2579,7 +2457,7 @@ var Viewer = {
|
|
2579 |
var v = this;
|
2580 |
var ev = 'item-next';
|
2581 |
var st = ['events', 'viewer', ev].join('_');
|
2582 |
-
//Setup event handler
|
2583 |
if ( !g.get_status(st) ) {
|
2584 |
g.set_status(st);
|
2585 |
g.on(ev, function(e) {
|
@@ -2610,14 +2488,14 @@ var Viewer = {
|
|
2610 |
* Close viewer
|
2611 |
*/
|
2612 |
close: function() {
|
2613 |
-
//Deactivate
|
2614 |
this.set_active(false);
|
2615 |
var v = this;
|
2616 |
var thm = this.get_theme();
|
2617 |
thm.transition('unload')
|
2618 |
.always(function() {
|
2619 |
thm.transition('close', true).always(function() {
|
2620 |
-
//End processes
|
2621 |
v.reset();
|
2622 |
v.trigger('close');
|
2623 |
});
|
@@ -2660,7 +2538,7 @@ var Group = {
|
|
2660 |
|
2661 |
/* Init */
|
2662 |
|
2663 |
-
|
2664 |
var t = this;
|
2665 |
this.on(['item-prev', 'item-next'], function() {
|
2666 |
t.trigger('item-change');
|
@@ -2675,7 +2553,7 @@ var Group = {
|
|
2675 |
*/
|
2676 |
get_selector: function() {
|
2677 |
if ( this.util.is_empty(this.selector) ) {
|
2678 |
-
//Build selector
|
2679 |
this.selector = this.util.format('a[%s="%s"]', this.dom_get_attribute(), this.get_id());
|
2680 |
}
|
2681 |
return this.selector;
|
@@ -2685,7 +2563,10 @@ var Group = {
|
|
2685 |
* Retrieve group items
|
2686 |
*/
|
2687 |
get_items: function() {
|
2688 |
-
var items =
|
|
|
|
|
|
|
2689 |
return items;
|
2690 |
},
|
2691 |
|
@@ -2696,18 +2577,18 @@ var Group = {
|
|
2696 |
* @return Content_Item Item
|
2697 |
*/
|
2698 |
get_item: function(idx) {
|
2699 |
-
//Validation
|
2700 |
if ( !this.util.is_int(idx) ) {
|
2701 |
idx = 0;
|
2702 |
}
|
2703 |
-
//Retrieve all items
|
2704 |
var items = this.get_items();
|
2705 |
-
//Validate index
|
2706 |
var max = this.get_size() - 1;
|
2707 |
if ( idx > max ) {
|
2708 |
idx = max;
|
2709 |
}
|
2710 |
-
//Return specified item
|
2711 |
return items.get(idx);
|
2712 |
},
|
2713 |
|
@@ -2718,19 +2599,29 @@ var Group = {
|
|
2718 |
*/
|
2719 |
get_pos: function(item) {
|
2720 |
if ( this.util.is_empty(item) ) {
|
2721 |
-
//Get current item
|
2722 |
item = this.get_current();
|
2723 |
}
|
2724 |
return ( this.util.is_type(item, View.Content_Item) ) ? this.get_items().index(item.dom_get()) : -1;
|
2725 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2726 |
|
2727 |
/**
|
2728 |
* Retrieve current item
|
2729 |
-
* @
|
|
|
2730 |
*/
|
2731 |
get_current: function() {
|
2732 |
-
//Sanitize
|
2733 |
-
if (
|
2734 |
this.current = null;
|
2735 |
}
|
2736 |
return this.current;
|
@@ -2741,26 +2632,26 @@ var Group = {
|
|
2741 |
* @param Content_Item item Item to set as current
|
2742 |
*/
|
2743 |
set_current: function(item) {
|
2744 |
-
//Validate
|
2745 |
if ( this.util.is_type(item, View.Content_Item) ) {
|
2746 |
-
//Set current item
|
2747 |
this.current = item;
|
2748 |
}
|
2749 |
},
|
2750 |
|
2751 |
get_next: function(item) {
|
2752 |
-
//Validate
|
2753 |
if ( !this.util.is_type(item, View.Content_Item) ) {
|
2754 |
item = this.get_current();
|
2755 |
}
|
2756 |
-
if ( this.get_size()
|
2757 |
return item;
|
2758 |
}
|
2759 |
var next = null;
|
2760 |
var pos = this.get_pos(item);
|
2761 |
-
if ( pos
|
2762 |
pos = ( pos + 1 < this.get_size() ) ? pos + 1 : 0;
|
2763 |
-
if ( 0
|
2764 |
next = this.get_item(pos);
|
2765 |
}
|
2766 |
}
|
@@ -2768,17 +2659,17 @@ var Group = {
|
|
2768 |
},
|
2769 |
|
2770 |
get_prev: function(item) {
|
2771 |
-
//Validate
|
2772 |
if ( !this.util.is_type(item, View.Content_Item) ) {
|
2773 |
item = this.get_current();
|
2774 |
}
|
2775 |
-
if ( this.get_size()
|
2776 |
return item;
|
2777 |
}
|
2778 |
var prev = null;
|
2779 |
var pos = this.get_pos(item);
|
2780 |
-
if ( pos
|
2781 |
-
if ( pos
|
2782 |
pos = this.get_size();
|
2783 |
}
|
2784 |
pos -= 1;
|
@@ -2789,7 +2680,7 @@ var Group = {
|
|
2789 |
|
2790 |
show_next: function(item) {
|
2791 |
if ( this.get_size() > 1 ) {
|
2792 |
-
//Retrieve item
|
2793 |
var next = this.get_next(item);
|
2794 |
if ( !next ) {
|
2795 |
if ( !this.util.is_type(item, View.Content_Item) ) {
|
@@ -2797,19 +2688,19 @@ var Group = {
|
|
2797 |
}
|
2798 |
item.get_viewer().close();
|
2799 |
}
|
2800 |
-
var i = this.
|
2801 |
-
//Update current item
|
2802 |
this.set_current(i);
|
2803 |
-
//Show item
|
2804 |
i.show();
|
2805 |
-
//Fire event
|
2806 |
this.trigger('item-next');
|
2807 |
}
|
2808 |
},
|
2809 |
|
2810 |
show_prev: function(item) {
|
2811 |
if ( this.get_size() > 1 ) {
|
2812 |
-
//Retrieve item
|
2813 |
var prev = this.get_prev(item);
|
2814 |
if ( !prev ) {
|
2815 |
if ( !this.util.is_type(item, View.Content_Item) ) {
|
@@ -2817,12 +2708,12 @@ var Group = {
|
|
2817 |
}
|
2818 |
item.get_viewer().close();
|
2819 |
}
|
2820 |
-
var i = this.
|
2821 |
-
//Update current item
|
2822 |
this.set_current(i);
|
2823 |
-
//Show item
|
2824 |
i.show();
|
2825 |
-
//Fire event
|
2826 |
this.trigger('item-prev');
|
2827 |
}
|
2828 |
},
|
@@ -2836,7 +2727,7 @@ var Group = {
|
|
2836 |
},
|
2837 |
|
2838 |
is_single: function() {
|
2839 |
-
return ( this.get_size()
|
2840 |
}
|
2841 |
};
|
2842 |
|
@@ -2887,7 +2778,7 @@ var Content_Handler = {
|
|
2887 |
* @return mixed Content_Item if valid item set, NULL otherwise
|
2888 |
*/
|
2889 |
get_item: function() {
|
2890 |
-
return this.get_component('item'
|
2891 |
},
|
2892 |
|
2893 |
/**
|
@@ -2898,7 +2789,7 @@ var Content_Handler = {
|
|
2898 |
* @return obj|null Item instance if item successfully set, NULL otherwise
|
2899 |
*/
|
2900 |
set_item: function(item) {
|
2901 |
-
//Set reference
|
2902 |
var r = this.set_component('item', item);
|
2903 |
return r;
|
2904 |
},
|
@@ -2908,7 +2799,7 @@ var Content_Handler = {
|
|
2908 |
* Sets value to NULL
|
2909 |
*/
|
2910 |
clear_item: function() {
|
2911 |
-
this.item
|
2912 |
},
|
2913 |
|
2914 |
/* Evaluation */
|
@@ -2919,34 +2810,49 @@ var Content_Handler = {
|
|
2919 |
* @return bool TRUE if type matches, FALSE otherwise
|
2920 |
*/
|
2921 |
match: function(item) {
|
2922 |
-
//Validate
|
2923 |
var attr = 'match';
|
2924 |
var m = this.get_attribute(attr);
|
2925 |
-
//Stop processing types with no matching algorithm
|
2926 |
if ( !this.util.is_empty(m) ) {
|
2927 |
-
//Process regex patterns
|
2928 |
|
2929 |
-
//String-based
|
2930 |
if ( this.util.is_string(m) ) {
|
2931 |
-
//Create new regexp object
|
2932 |
m = new RegExp(m, "i");
|
2933 |
this.set_attribute(attr, m);
|
2934 |
}
|
2935 |
-
//RegExp based
|
2936 |
if ( this.util.is_type(m, RegExp) ) {
|
2937 |
return m.test(item.get_uri());
|
2938 |
}
|
2939 |
-
//Process function
|
2940 |
if ( this.util.is_func(m) ) {
|
2941 |
return ( m.call(this, item) ) ? true : false;
|
2942 |
}
|
2943 |
}
|
2944 |
-
//Default
|
2945 |
return false;
|
2946 |
},
|
2947 |
|
2948 |
/* Processing/Output */
|
2949 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2950 |
/**
|
2951 |
* Render output to display item
|
2952 |
* @param Content_Item item Item to render output for
|
@@ -2954,20 +2860,8 @@ var Content_Handler = {
|
|
2954 |
*/
|
2955 |
render: function(item) {
|
2956 |
var dfr = $.Deferred();
|
2957 |
-
//Validate
|
2958 |
-
|
2959 |
-
if ( this.util.is_promise(ret) ) {
|
2960 |
-
ret.done(function(output) {
|
2961 |
-
dfr.resolve(output);
|
2962 |
-
});
|
2963 |
-
} else {
|
2964 |
-
//String format
|
2965 |
-
if ( this.util.is_string(ret) ) {
|
2966 |
-
ret = this.util.format(ret, item.get_uri());
|
2967 |
-
}
|
2968 |
-
//Resolve deferred immediately
|
2969 |
-
dfr.resolve(ret);
|
2970 |
-
}
|
2971 |
return dfr.promise();
|
2972 |
}
|
2973 |
};
|
@@ -2988,7 +2882,6 @@ var Content_Item = {
|
|
2988 |
'group': 'Group',
|
2989 |
'type': 'Content_Handler'
|
2990 |
},
|
2991 |
-
_containers: ['group'],
|
2992 |
|
2993 |
_attr_default: {
|
2994 |
source: null,
|
@@ -3009,13 +2902,14 @@ var Content_Item = {
|
|
3009 |
/* Properties */
|
3010 |
|
3011 |
data: null,
|
|
|
3012 |
|
3013 |
/* Init */
|
3014 |
|
3015 |
_c: function(el) {
|
3016 |
-
//Save element to instance
|
3017 |
this.dom_set(el);
|
3018 |
-
//Default initialization
|
3019 |
this._super();
|
3020 |
},
|
3021 |
|
@@ -3031,36 +2925,30 @@ var Content_Item = {
|
|
3031 |
*/
|
3032 |
init_default_attributes: function() {
|
3033 |
this._super();
|
3034 |
-
//Add asset properties
|
3035 |
var d = this.dom_get();
|
3036 |
-
var key = d.attr('
|
3037 |
-
var assets = this.
|
3038 |
-
//Merge asset data with default attributes
|
3039 |
if ( this.util.is_string(key) ) {
|
3040 |
-
var attrs = [{}, this._attr_default, {'permalink':
|
3041 |
if ( this.util.is_obj(assets) ) {
|
3042 |
var t = this;
|
3043 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
3044 |
var ret = {};
|
3045 |
if ( key in assets && t.util.is_obj(assets[key]) ) {
|
3046 |
-
|
3047 |
-
if ( t.util.is_string(raw) ) {
|
3048 |
-
var e = '_entries';
|
3049 |
-
if ( !( e in ret ) || -1 == $.inArray(raw, ret[e]) ) {
|
3050 |
-
ret = {};
|
3051 |
-
}
|
3052 |
-
}
|
3053 |
}
|
3054 |
return ret;
|
3055 |
};
|
3056 |
-
|
3057 |
-
|
3058 |
-
var key_base = key.substr(0, kpos);
|
3059 |
-
asset = get_assets(key_base, key);
|
3060 |
-
}
|
3061 |
-
if ( !this.util.is_empty(asset) ) {
|
3062 |
-
attrs.push(asset);
|
3063 |
-
}
|
3064 |
}
|
3065 |
this._attr_default = $.extend.apply(this, attrs);
|
3066 |
}
|
@@ -3080,18 +2968,18 @@ var Content_Item = {
|
|
3080 |
*/
|
3081 |
get_output: function() {
|
3082 |
var dfr = $.Deferred();
|
3083 |
-
//Check for cached output
|
3084 |
var ret = this.get_attribute('output');
|
3085 |
if ( this.util.is_string(ret) ) {
|
3086 |
dfr.resolve(ret);
|
3087 |
} else if ( this.has_type() ) {
|
3088 |
-
//Render output from scratch (if necessary)
|
3089 |
-
//Get item type
|
3090 |
var type = this.get_type();
|
3091 |
-
//Render type-based output
|
3092 |
var item = this;
|
3093 |
type.render(this).done(function(output) {
|
3094 |
-
//Cache output
|
3095 |
item.set_output(output);
|
3096 |
dfr.resolve(output);
|
3097 |
});
|
@@ -3128,15 +3016,17 @@ var Content_Item = {
|
|
3128 |
* @return string Item URI
|
3129 |
*/
|
3130 |
get_uri: function(mode) {
|
3131 |
-
//Validate
|
3132 |
-
if ( $.inArray(mode ,['source', 'permalink'])
|
3133 |
mode = 'source';
|
3134 |
}
|
3135 |
-
//Retrieve URI
|
3136 |
var ret = this.get_attribute(mode);
|
3137 |
if ( !this.util.is_string(ret) ) {
|
3138 |
-
ret = ( 'source'
|
3139 |
}
|
|
|
|
|
3140 |
return ret;
|
3141 |
},
|
3142 |
|
@@ -3146,28 +3036,32 @@ var Content_Item = {
|
|
3146 |
get_title: function() {
|
3147 |
var prop = 'title';
|
3148 |
var prop_cached = prop + '_cached';
|
3149 |
-
//Check for cached value
|
3150 |
if ( this.has_attribute(prop_cached) ) {
|
3151 |
return this.get_attribute(prop_cached, '');
|
3152 |
}
|
3153 |
|
3154 |
var title = '';
|
3155 |
-
|
3156 |
-
//Generate title from DOM values
|
3157 |
var dom = this.dom_get();
|
3158 |
|
3159 |
-
//
|
3160 |
-
if ( dom.length
|
3161 |
-
//Link title
|
3162 |
title = dom.attr(prop);
|
3163 |
|
3164 |
-
//
|
3165 |
if ( !title ) {
|
3166 |
-
title = dom.
|
|
|
|
|
|
|
|
|
|
|
3167 |
}
|
3168 |
}
|
3169 |
|
3170 |
-
//Saved attributes
|
3171 |
if ( !title ) {
|
3172 |
var props = ['caption', 'title'];
|
3173 |
for ( var x = 0; x < props.length; x++ ) {
|
@@ -3178,25 +3072,41 @@ var Content_Item = {
|
|
3178 |
}
|
3179 |
}
|
3180 |
|
3181 |
-
//Fallbacks
|
3182 |
if ( !title && dom.length ) {
|
3183 |
-
//Alt attribute
|
3184 |
title = dom.find('img').first().attr('alt');
|
3185 |
|
3186 |
-
//Element text
|
3187 |
if ( !title ) {
|
3188 |
-
title = dom.
|
3189 |
}
|
3190 |
}
|
3191 |
|
3192 |
-
//Validate
|
3193 |
if ( !this.util.is_string(title, false) ) {
|
3194 |
title = '';
|
3195 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3196 |
|
3197 |
-
//Cache retrieved value
|
3198 |
this.set_attribute(prop_cached, title);
|
3199 |
-
//Return value
|
3200 |
return title;
|
3201 |
},
|
3202 |
|
@@ -3217,6 +3127,10 @@ var Content_Item = {
|
|
3217 |
this.data = data;
|
3218 |
},
|
3219 |
|
|
|
|
|
|
|
|
|
3220 |
/**
|
3221 |
* Determine gallery type
|
3222 |
* @return string|null Gallery type ID (NULL if item not in gallery)
|
@@ -3245,16 +3159,16 @@ var Content_Item = {
|
|
3245 |
*/
|
3246 |
in_gallery: function(gType) {
|
3247 |
var type = this.gallery_type();
|
3248 |
-
//No gallery
|
3249 |
-
if ( null
|
3250 |
return false;
|
3251 |
}
|
3252 |
-
//Boolean check
|
3253 |
if ( !this.util.is_string(gType) ) {
|
3254 |
return true;
|
3255 |
}
|
3256 |
-
//Check for specific gallery type
|
3257 |
-
return ( gType
|
3258 |
},
|
3259 |
|
3260 |
/*-** Component References **-*/
|
@@ -3262,7 +3176,7 @@ var Content_Item = {
|
|
3262 |
/* Viewer */
|
3263 |
|
3264 |
get_viewer: function() {
|
3265 |
-
return this.get_component('viewer');
|
3266 |
},
|
3267 |
|
3268 |
/**
|
@@ -3285,11 +3199,11 @@ var Content_Item = {
|
|
3285 |
*/
|
3286 |
get_group: function(set_current) {
|
3287 |
var prop = 'group';
|
3288 |
-
//Check if group reference already set
|
3289 |
-
var g = this.get_component(prop
|
3290 |
if ( g ) {
|
3291 |
} else {
|
3292 |
-
//Set empty group if no group exists
|
3293 |
g = this.set_component(prop, new View.Group());
|
3294 |
set_current = true;
|
3295 |
}
|
@@ -3307,12 +3221,12 @@ var Content_Item = {
|
|
3307 |
* > Item's group is reset if invalid group provided
|
3308 |
*/
|
3309 |
set_group: function(g) {
|
3310 |
-
//If group ID set, get object reference
|
3311 |
if ( this.util.is_string(g) ) {
|
3312 |
-
g = this.
|
3313 |
}
|
3314 |
|
3315 |
-
//Set (or clear) group property
|
3316 |
this.group = ( this.util.is_type(g, View.Group) ) ? g : false;
|
3317 |
},
|
3318 |
|
@@ -3325,9 +3239,9 @@ var Content_Item = {
|
|
3325 |
* @return Content_Handler|null Content Handler of item (NULL no valid type exists)
|
3326 |
*/
|
3327 |
get_type: function() {
|
3328 |
-
var t = this.get_component('type',
|
3329 |
if ( !t ) {
|
3330 |
-
t = this.set_type(this.
|
3331 |
}
|
3332 |
return t;
|
3333 |
},
|
@@ -3359,19 +3273,35 @@ var Content_Item = {
|
|
3359 |
* @param obj options (optional) Options
|
3360 |
*/
|
3361 |
show: function(options) {
|
3362 |
-
//Validate content handler
|
3363 |
if ( !this.has_type() ) {
|
3364 |
return false;
|
3365 |
}
|
3366 |
-
//Set display options
|
3367 |
this.set_attribute('options_show', options);
|
3368 |
-
//Retrieve viewer
|
3369 |
var v = this.get_viewer();
|
3370 |
-
//Load item
|
|
|
3371 |
var ret = v.show(this);
|
3372 |
return ret;
|
3373 |
},
|
3374 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3375 |
reset: function() {
|
3376 |
this.set_attribute('options_show', null);
|
3377 |
}
|
@@ -3401,28 +3331,52 @@ var Modeled_Component = {
|
|
3401 |
* @return mixed Attribute value
|
3402 |
*/
|
3403 |
get_attribute: function(key, def, check_model, enforce_type) {
|
3404 |
-
//Validate
|
3405 |
if ( !this.util.is_string(key) ) {
|
3406 |
-
//Invalid requests sent straight to super method
|
3407 |
return this._super(key, def, enforce_type);
|
3408 |
}
|
3409 |
if ( !this.util.is_bool(check_model) ) {
|
3410 |
check_model = true;
|
3411 |
}
|
3412 |
var ret = null;
|
3413 |
-
//Check model for attribute
|
3414 |
if ( check_model ) {
|
3415 |
var m = this.get_ancestor(key, false);
|
3416 |
if ( this.util.in_obj(m, key) ) {
|
3417 |
ret = m[key];
|
3418 |
}
|
3419 |
}
|
3420 |
-
//Check standard attributes as fallback
|
3421 |
-
if ( null
|
3422 |
ret = this._super(key, def, enforce_type);
|
3423 |
}
|
3424 |
return ret;
|
3425 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3426 |
|
3427 |
/**
|
3428 |
* Set attribute value
|
@@ -3436,21 +3390,21 @@ var Modeled_Component = {
|
|
3436 |
* @return mixed Attribute value
|
3437 |
*/
|
3438 |
set_attribute: function(key, val, use_model) {
|
3439 |
-
//Validate
|
3440 |
if ( ( !this.util.is_string(key) ) || !this.util.is_set(val) ) {
|
3441 |
return false;
|
3442 |
}
|
3443 |
if ( !this.util.is_bool(use_model) && !this.util.is_obj(use_model) ) {
|
3444 |
use_model = true;
|
3445 |
}
|
3446 |
-
//Determine where to set attribute
|
3447 |
if ( !!use_model ) {
|
3448 |
var model = this.util.is_obj(use_model) ? use_model : this.get_model();
|
3449 |
|
3450 |
-
//Set attribute in model
|
3451 |
model[key] = val;
|
3452 |
} else {
|
3453 |
-
//Set as standard attribute
|
3454 |
this._super(key, val);
|
3455 |
}
|
3456 |
return val;
|
@@ -3466,7 +3420,7 @@ var Modeled_Component = {
|
|
3466 |
get_model: function() {
|
3467 |
var m = this.get_attribute('model', null, false);
|
3468 |
if ( !this.util.is_obj(m) ) {
|
3469 |
-
//Set default value
|
3470 |
m = {};
|
3471 |
this.set_attribute('model', m, false);
|
3472 |
}
|
@@ -3505,7 +3459,7 @@ var Modeled_Component = {
|
|
3505 |
ret.push(m);
|
3506 |
m = ( this.util.in_obj(m, 'parent') && this.util.is_obj(m.parent) ) ? m.parent : null;
|
3507 |
}
|
3508 |
-
//Remove current model from list
|
3509 |
if ( !inc_current ) {
|
3510 |
ret.shift();
|
3511 |
}
|
@@ -3520,32 +3474,32 @@ var Modeled_Component = {
|
|
3520 |
* @return obj Theme ancestor (Default: Current theme model)
|
3521 |
*/
|
3522 |
get_ancestor: function(attr, safe_mode) {
|
3523 |
-
//Validate
|
3524 |
if ( !this.util.is_string(attr) ) {
|
3525 |
return false;
|
3526 |
}
|
3527 |
if ( !this.util.is_bool(safe_mode) ) {
|
3528 |
safe_mode = true;
|
3529 |
}
|
3530 |
-
var mcurr;
|
3531 |
-
var m = mcurr
|
3532 |
var found = false;
|
3533 |
while ( this.util.is_obj(m) ) {
|
3534 |
-
//Check if attribute exists in model
|
3535 |
if ( this.util.in_obj(m, attr) && !this.util.is_empty(m[attr]) ) {
|
3536 |
found = true;
|
3537 |
break;
|
3538 |
}
|
3539 |
-
//Get next model
|
3540 |
m = ( this.util.in_obj(m, 'parent') ) ? m['parent'] : null;
|
3541 |
}
|
3542 |
if ( !found ) {
|
3543 |
if ( safe_mode ) {
|
3544 |
-
//Use current model as fallback
|
3545 |
if ( this.util.is_empty(m) ) {
|
3546 |
m = mcurr;
|
3547 |
}
|
3548 |
-
//Add attribute to object
|
3549 |
if ( !this.util.in_obj(m, attr) ) {
|
3550 |
m[attr] = null;
|
3551 |
}
|
@@ -3574,8 +3528,6 @@ var Theme = {
|
|
3574 |
},
|
3575 |
_models: {},
|
3576 |
|
3577 |
-
_containers: ['viewer'],
|
3578 |
-
|
3579 |
_attr_default: {
|
3580 |
template: null,
|
3581 |
model: null
|
@@ -3593,25 +3545,25 @@ var Theme = {
|
|
3593 |
* @see Component._c()
|
3594 |
*/
|
3595 |
_c: function(id, attributes, viewer) {
|
3596 |
-
//Validate
|
3597 |
-
if ( arguments.length
|
3598 |
viewer = arguments[0];
|
3599 |
id = null;
|
3600 |
}
|
3601 |
-
//Pass parameters to parent constructor
|
3602 |
this._super(id, attributes);
|
3603 |
|
3604 |
-
//Set viewer instance
|
3605 |
this.set_viewer(viewer);
|
3606 |
|
3607 |
-
//Set theme model
|
3608 |
this.set_model(id);
|
3609 |
},
|
3610 |
|
3611 |
/* Viewer */
|
3612 |
|
3613 |
get_viewer: function() {
|
3614 |
-
return this.get_component('viewer', false, true
|
3615 |
},
|
3616 |
|
3617 |
/**
|
@@ -3632,17 +3584,19 @@ var Theme = {
|
|
3632 |
* @return Template instance
|
3633 |
*/
|
3634 |
get_template: function() {
|
3635 |
-
//Get saved template
|
3636 |
-
var ret = this.get_component('template'
|
3637 |
-
//Template needs to be initialized
|
3638 |
if ( this.util.is_empty(ret) ) {
|
3639 |
-
//Pass model to Template instance
|
3640 |
var attr = { 'theme': this, 'model': this.get_model() };
|
3641 |
ret = this.set_component('template', new View.Template(attr));
|
3642 |
}
|
3643 |
return ret;
|
3644 |
},
|
3645 |
|
|
|
|
|
3646 |
/**
|
3647 |
* Retrieve tags from template
|
3648 |
* All tags will be retrieved by default
|
@@ -3664,6 +3618,17 @@ var Theme = {
|
|
3664 |
return $(this.get_template().dom_get_tag(tag, prop));
|
3665 |
},
|
3666 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3667 |
/* Model */
|
3668 |
|
3669 |
/**
|
@@ -3682,16 +3647,16 @@ var Theme = {
|
|
3682 |
*/
|
3683 |
get_model: function(id) {
|
3684 |
var ret = null;
|
3685 |
-
//Pass request to superclass method
|
3686 |
if ( !this.util.is_set(id) && this.util.is_obj( this.get_attribute('model', null, false) ) ) {
|
3687 |
ret = this._super();
|
3688 |
} else {
|
3689 |
-
//Retrieve matching theme model
|
3690 |
var models = this.get_models();
|
3691 |
if ( !this.util.is_string(id) ) {
|
3692 |
-
|
3693 |
}
|
3694 |
-
//Select first theme model if specified model is invalid
|
3695 |
if ( !this.util.in_obj(models, id) ) {
|
3696 |
id = $.map(models, function(v, key) { return key; })[0];
|
3697 |
}
|
@@ -3706,13 +3671,15 @@ var Theme = {
|
|
3706 |
*/
|
3707 |
set_model: function(id) {
|
3708 |
this.set_attribute('model', this.get_model(id), false);
|
3709 |
-
|
3710 |
-
|
|
|
3711 |
var m = this.get_model();
|
3712 |
if ( 'id' in m ) {
|
3713 |
-
this.
|
3714 |
}
|
3715 |
}
|
|
|
3716 |
},
|
3717 |
|
3718 |
/* Properties */
|
@@ -3727,19 +3694,19 @@ var Theme = {
|
|
3727 |
* @return array Class names
|
3728 |
*/
|
3729 |
get_classes: function(rtype) {
|
3730 |
-
//Build array of class names
|
3731 |
var cls = [];
|
3732 |
var thm = this;
|
3733 |
-
//Include theme parent's class name
|
3734 |
var models = this.get_ancestors(true);
|
3735 |
$.each(models, function(idx, model) {
|
3736 |
cls.push(thm.add_ns(model.id));
|
3737 |
});
|
3738 |
-
//Convert class names array to string
|
3739 |
if ( this.util.is_string(rtype) ) {
|
3740 |
cls = cls.join(rtype);
|
3741 |
}
|
3742 |
-
//Return class names
|
3743 |
return cls;
|
3744 |
},
|
3745 |
|
@@ -3751,52 +3718,52 @@ var Theme = {
|
|
3751 |
*/
|
3752 |
get_measurement: function(attr, def) {
|
3753 |
var meas = null;
|
3754 |
-
//Validate
|
3755 |
if ( !this.util.is_string(attr) ) {
|
3756 |
return meas;
|
3757 |
}
|
3758 |
if ( !this.util.is_obj(def, false) ) {
|
3759 |
def = {};
|
3760 |
}
|
3761 |
-
//Manage cache
|
3762 |
var attr_cache = this.util.format('%s_cache', attr);
|
3763 |
var cache = this.get_attribute(attr_cache, {}, false);
|
3764 |
var status = '_status';
|
3765 |
var item = this.get_viewer().get_item();
|
3766 |
var w = $(window);
|
3767 |
-
//Check cache freshness
|
3768 |
-
if ( !( status in cache ) || !this.util.is_obj(cache[status]) || cache[status].width
|
3769 |
cache = {};
|
3770 |
}
|
3771 |
if ( this.util.is_empty(cache) ) {
|
3772 |
-
//Set status
|
3773 |
cache[status] = {
|
3774 |
'width': w.width(),
|
3775 |
'height': w.height(),
|
3776 |
'index': []
|
3777 |
};
|
3778 |
}
|
3779 |
-
//Retrieve cached values
|
3780 |
var pos = $.inArray(item, cache[status].index);
|
3781 |
-
if ( pos
|
3782 |
meas = cache[pos];
|
3783 |
}
|
3784 |
-
//Generate measurement
|
3785 |
if ( !this.util.is_obj(meas) ) {
|
3786 |
-
//Get custom theme measurement
|
3787 |
meas = this.call_attribute(attr);
|
3788 |
if ( !this.util.is_obj(meas) ) {
|
3789 |
-
//Retrieve fallback value
|
3790 |
meas = this.get_measurement_default(attr);
|
3791 |
}
|
3792 |
}
|
3793 |
-
//Normalize measurement
|
3794 |
meas = ( this.util.is_obj(meas) ) ? $.extend({}, def, meas) : def;
|
3795 |
-
//Cache measurement
|
3796 |
pos = cache[status].index.push(item) - 1;
|
3797 |
cache[pos] = meas;
|
3798 |
this.set_attribute(attr_cache, cache, false);
|
3799 |
-
//Return measurement (copy)
|
3800 |
return $.extend({}, meas);
|
3801 |
},
|
3802 |
|
@@ -3806,16 +3773,16 @@ var Theme = {
|
|
3806 |
* @return obj Measurement values
|
3807 |
*/
|
3808 |
get_measurement_default: function(attr) {
|
3809 |
-
//Validate
|
3810 |
if ( !this.util.is_string(attr) ) {
|
3811 |
return null;
|
3812 |
}
|
3813 |
-
//Find default handler
|
3814 |
attr = this.util.format('get_%s_default', attr);
|
3815 |
if ( this.util.in_obj(this, attr) ) {
|
3816 |
attr = this[attr];
|
3817 |
if ( this.util.is_func(attr) ) {
|
3818 |
-
//Execute default handler
|
3819 |
attr = attr.call(this);
|
3820 |
}
|
3821 |
} else {
|
@@ -3840,37 +3807,37 @@ var Theme = {
|
|
3840 |
var offset = { 'width': 0, 'height': 0 };
|
3841 |
var v = this.get_viewer();
|
3842 |
var vn = v.dom_get();
|
3843 |
-
//Clone viewer
|
3844 |
var vc = vn
|
3845 |
.clone()
|
3846 |
.attr('id', '')
|
3847 |
.css({'visibility': 'hidden', 'position': 'absolute', 'top': ''})
|
3848 |
.removeClass('loading')
|
3849 |
.appendTo(vn.parent());
|
3850 |
-
//Get offset from layout node
|
3851 |
var l = vc.find(v.dom_get_selector('layout'));
|
3852 |
if ( l.length ) {
|
3853 |
-
//Clear inline styles
|
3854 |
l.find('*').css({
|
3855 |
'width': '',
|
3856 |
'height': '',
|
3857 |
'display': ''
|
3858 |
});
|
3859 |
-
//Resize content nodes
|
3860 |
var tags = this.get_tags('item', 'content');
|
3861 |
if ( tags.length ) {
|
3862 |
var offset_item = v.get_item().get_dimensions();
|
3863 |
-
//Set content dimensions
|
3864 |
tags = $(l.find(tags[0].get_selector('full')).get(0)).css({'width': offset_item.width, 'height': offset_item.height});
|
3865 |
$.each(offset_item, function(key, val) {
|
3866 |
offset[key] = -1 * val;
|
3867 |
});
|
3868 |
}
|
3869 |
|
3870 |
-
//Set offset
|
3871 |
offset.width += l.width();
|
3872 |
offset.height += l.height();
|
3873 |
-
//Normalize
|
3874 |
$.each(offset, function(key, val) {
|
3875 |
if ( val < 0 ) {
|
3876 |
offset[key] = 0;
|
@@ -3898,7 +3865,7 @@ var Theme = {
|
|
3898 |
var v = this.get_viewer();
|
3899 |
var dims = v.get_item().get_dimensions();
|
3900 |
if ( v.get_attribute('autofit', false) ) {
|
3901 |
-
//Get maximum dimensions
|
3902 |
var margin = this.get_margin();
|
3903 |
var offset = this.get_offset();
|
3904 |
offset.height += margin.height;
|
@@ -3910,11 +3877,11 @@ var Theme = {
|
|
3910 |
if ( max.height > offset.height ) {
|
3911 |
max.height -= offset.height;
|
3912 |
}
|
3913 |
-
//Get resize factor
|
3914 |
var factor = Math.min(max.width / dims.width, max.height / dims.height);
|
3915 |
-
//Resize dimensions
|
3916 |
if ( factor < 1 ) {
|
3917 |
-
$.each(dims, function(key
|
3918 |
dims[key] = Math.round(dims[key] * factor);
|
3919 |
});
|
3920 |
}
|
@@ -3929,12 +3896,36 @@ var Theme = {
|
|
3929 |
get_dimensions: function() {
|
3930 |
var dims = this.get_item_dimensions();
|
3931 |
var offset = this.get_offset();
|
3932 |
-
$.each(dims, function(key
|
3933 |
dims[key] += offset[key];
|
3934 |
});
|
3935 |
return dims;
|
3936 |
},
|
3937 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3938 |
/* Output */
|
3939 |
|
3940 |
/**
|
@@ -3948,7 +3939,7 @@ var Theme = {
|
|
3948 |
var st = 'events_render';
|
3949 |
if ( !this.get_status(st) ) {
|
3950 |
this.set_status(st);
|
3951 |
-
//Register events
|
3952 |
tpl.on([
|
3953 |
'render-init',
|
3954 |
'render-loading',
|
@@ -3958,7 +3949,7 @@ var Theme = {
|
|
3958 |
return thm.trigger(ev.type, ev.data);
|
3959 |
});
|
3960 |
}
|
3961 |
-
//Render template
|
3962 |
tpl.render(init);
|
3963 |
},
|
3964 |
|
@@ -3977,12 +3968,12 @@ var Theme = {
|
|
3977 |
el.stop(false, true);
|
3978 |
}
|
3979 |
});
|
3980 |
-
}
|
3981 |
-
//Stop queued animations
|
3982 |
if ( !!clear_queue ) {
|
3983 |
anim_stop();
|
3984 |
}
|
3985 |
-
//Get transition handlers
|
3986 |
var attr_set = [attr, 'set'].join('_');
|
3987 |
var trns;
|
3988 |
if ( !this.get_attribute(attr_set) ) {
|
@@ -3995,19 +3986,19 @@ var Theme = {
|
|
3995 |
trns.push(model[attr]);
|
3996 |
}
|
3997 |
});
|
3998 |
-
//Merge transition handlers into current theme
|
3999 |
trns.push({});
|
4000 |
trns = this.set_attribute(attr, $.extend.apply($, trns.reverse()));
|
4001 |
} else {
|
4002 |
trns = this.get_attribute(attr, {});
|
4003 |
}
|
4004 |
if ( this.util.is_method(trns, event) ) {
|
4005 |
-
//Disable animations if necessary
|
4006 |
if ( !anim_on ) {
|
4007 |
fx_temp = $.fx.off;
|
4008 |
$.fx.off = true;
|
4009 |
}
|
4010 |
-
//Pass control to transition event
|
4011 |
dfr = trns[event].call(this, v, $.Deferred());
|
4012 |
}
|
4013 |
}
|
@@ -4016,7 +4007,7 @@ var Theme = {
|
|
4016 |
dfr.reject();
|
4017 |
}
|
4018 |
dfr.always(function() {
|
4019 |
-
//Restore animation state
|
4020 |
if ( null !== fx_temp ) {
|
4021 |
$.fx.off = fx_temp;
|
4022 |
}
|
@@ -4040,8 +4031,7 @@ var Template = {
|
|
4040 |
_refs: {
|
4041 |
'theme': 'Theme'
|
4042 |
},
|
4043 |
-
|
4044 |
-
|
4045 |
_attr_default: {
|
4046 |
/**
|
4047 |
* URI to layout (raw) file
|
@@ -4084,8 +4074,26 @@ var Template = {
|
|
4084 |
this._super('', attributes);
|
4085 |
},
|
4086 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4087 |
get_theme: function() {
|
4088 |
-
var ret = this.get_component('theme'
|
4089 |
return ret;
|
4090 |
},
|
4091 |
|
@@ -4104,7 +4112,7 @@ var Template = {
|
|
4104 |
if ( !this.util.is_bool(init) ) {
|
4105 |
init = false;
|
4106 |
}
|
4107 |
-
//Populate layout
|
4108 |
if ( !init ) {
|
4109 |
if ( !v.is_active() ) {
|
4110 |
return false;
|
@@ -4114,14 +4122,14 @@ var Template = {
|
|
4114 |
v.close();
|
4115 |
return false;
|
4116 |
}
|
4117 |
-
//Iterate through tags and populate layout
|
4118 |
if ( v.is_active() && this.has_tags() ) {
|
4119 |
var loading_promise = this.trigger('render-loading');
|
4120 |
var tpl = this;
|
4121 |
var tags = this.get_tags(),
|
4122 |
tag_promises = [];
|
4123 |
-
//Render Tag output
|
4124 |
-
loading_promise.done(function() {
|
4125 |
if ( !v.is_active() ) {
|
4126 |
return false;
|
4127 |
}
|
@@ -4136,7 +4144,7 @@ var Template = {
|
|
4136 |
r.tag.dom_get().html(r.output);
|
4137 |
}));
|
4138 |
});
|
4139 |
-
//Fire event when all tags rendered
|
4140 |
if ( !v.is_active() ) {
|
4141 |
return false;
|
4142 |
}
|
@@ -4146,7 +4154,7 @@ var Template = {
|
|
4146 |
});
|
4147 |
}
|
4148 |
} else {
|
4149 |
-
//Get Layout (basic)
|
4150 |
this.trigger('render-init', this.dom_get());
|
4151 |
}
|
4152 |
},
|
@@ -4159,11 +4167,11 @@ var Template = {
|
|
4159 |
* @return string Layout (HTML)
|
4160 |
*/
|
4161 |
get_layout: function(parsed) {
|
4162 |
-
//Validate
|
4163 |
if ( !this.util.is_bool(parsed) ) {
|
4164 |
parsed = true;
|
4165 |
}
|
4166 |
-
//Determine which layout to retrieve (raw/parsed)
|
4167 |
var l = ( parsed ) ? this.parse_layout() : this.get_attribute('layout_raw', '');
|
4168 |
return l;
|
4169 |
},
|
@@ -4176,20 +4184,20 @@ var Template = {
|
|
4176 |
* @return string Parsed layout
|
4177 |
*/
|
4178 |
parse_layout: function() {
|
4179 |
-
//Check for previously-parsed layout
|
4180 |
var a = 'layout_parsed';
|
4181 |
var ret = this.get_attribute(a);
|
4182 |
-
//Return cached layout immediately
|
4183 |
if ( this.util.is_string(ret) ) {
|
4184 |
return ret;
|
4185 |
}
|
4186 |
-
//Parse raw layout
|
4187 |
ret = this.sanitize_layout( this.get_layout(false) );
|
4188 |
ret = this.parse_tags(ret);
|
4189 |
-
//Save parsed layout
|
4190 |
this.set_attribute(a, ret);
|
4191 |
|
4192 |
-
//Return parsed layout
|
4193 |
return ret;
|
4194 |
},
|
4195 |
|
@@ -4199,28 +4207,30 @@ var Template = {
|
|
4199 |
* @return obj|string Sanitized layout (Same data type that was passed to method)
|
4200 |
*/
|
4201 |
sanitize_layout: function(l) {
|
4202 |
-
//Stop processing if invalid value
|
4203 |
if ( this.util.is_empty(l) ) {
|
4204 |
return l;
|
4205 |
}
|
4206 |
-
//Set return type
|
4207 |
var rtype = ( this.util.is_string(l) ) ? 'string' : null;
|
4208 |
/* Quarantine hard-coded tags */
|
4209 |
|
4210 |
-
//Create DOM structure from raw template
|
4211 |
var dom = $(l);
|
4212 |
-
//Find hard-coded tag nodes
|
4213 |
-
var tag_temp =
|
4214 |
var cls = tag_temp.get_class();
|
4215 |
var cls_new = ['x', cls].join('_');
|
4216 |
-
$(tag_temp.get_selector(), dom).each(function(
|
4217 |
-
//Replace matching class name with blocking class
|
4218 |
$(this).removeClass(cls).addClass(cls_new);
|
4219 |
});
|
4220 |
-
//Format return value
|
4221 |
switch ( rtype ) {
|
4222 |
case 'string' :
|
4223 |
dom = dom.wrap('<div />').parent().html();
|
|
|
|
|
4224 |
default :
|
4225 |
l = dom;
|
4226 |
}
|
@@ -4237,18 +4247,18 @@ var Template = {
|
|
4237 |
* @return string Parsed layout
|
4238 |
*/
|
4239 |
parse_tags: function(l) {
|
4240 |
-
//Validate
|
4241 |
if ( !this.util.is_string(l) ) {
|
4242 |
return '';
|
4243 |
}
|
4244 |
-
//Parse tags in layout
|
4245 |
-
//Tag regex
|
4246 |
var re = /\{{2}\s*(\w.*?)\s*\}{2}/gim;
|
4247 |
-
//Tag match results
|
4248 |
var match;
|
4249 |
-
//Iterate through template and find tags
|
4250 |
while ( match = re.exec(l) ) {
|
4251 |
-
//Replace tag in layout with DOM container
|
4252 |
l = l.substring(0, match.index) + this.get_tag_container(match[1]) + l.substring(match.index + match[0].length);
|
4253 |
}
|
4254 |
return l;
|
@@ -4260,13 +4270,13 @@ var Template = {
|
|
4260 |
* @return string DOM element
|
4261 |
*/
|
4262 |
get_tag_container: function(tag) {
|
4263 |
-
//Build element
|
4264 |
var attr = this.get_tag_attribute();
|
4265 |
-
return this.util.format('<span %s="%s"></span>', attr,
|
4266 |
},
|
4267 |
|
4268 |
get_tag_attribute: function() {
|
4269 |
-
return this.
|
4270 |
},
|
4271 |
|
4272 |
/**
|
@@ -4292,43 +4302,54 @@ var Template = {
|
|
4292 |
* Template is parsed if tags not set
|
4293 |
* @param string name (optional) Tag type to retrieve instances of
|
4294 |
* @param string prop (optional) Tag property to retrieve instances of
|
|
|
4295 |
* @return array Template_Tag instances
|
4296 |
*/
|
4297 |
-
get_tags: function(name, prop) {
|
|
|
|
|
|
|
|
|
|
|
4298 |
var a = 'tags';
|
4299 |
var tags = this.get_attribute(a);
|
4300 |
-
//Initialize tags
|
4301 |
if ( !this.util.is_array(tags) ) {
|
4302 |
tags = [];
|
4303 |
-
//Retrieve layout DOM tree
|
4304 |
var d = this.dom_get();
|
4305 |
-
//Select tag nodes
|
4306 |
var attr = this.get_tag_attribute();
|
4307 |
var nodes = $(d).find('[' + attr + ']');
|
4308 |
-
//Build tag instances from nodes
|
4309 |
-
$(nodes).each(function(
|
4310 |
-
//Get tag placeholder
|
4311 |
var el = $(this);
|
4312 |
-
var tag = new View.Template_Tag(
|
4313 |
-
//Populate valid tags
|
4314 |
if ( tag.has_handler() ) {
|
4315 |
-
//Add tag to array
|
4316 |
tags.push(tag);
|
4317 |
-
|
4318 |
-
|
4319 |
-
|
4320 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
4321 |
}
|
4322 |
-
//Clear data attribute
|
4323 |
-
el.removeAttr(attr);
|
4324 |
});
|
4325 |
-
|
4326 |
-
|
|
|
|
|
4327 |
}
|
4328 |
-
|
4329 |
-
//Filter tags by parameters
|
4330 |
if ( !this.util.is_empty(tags) && this.util.is_string(name) ) {
|
4331 |
-
//Normalize
|
4332 |
if ( !this.util.is_string(prop) ) {
|
4333 |
prop = false;
|
4334 |
}
|
@@ -4336,9 +4357,9 @@ var Template = {
|
|
4336 |
var tc = null;
|
4337 |
for ( var x = 0; x < tags.length; x++ ) {
|
4338 |
tc = tags[x];
|
4339 |
-
if ( name
|
4340 |
-
//Check tag property
|
4341 |
-
if ( !prop || prop
|
4342 |
tags_filtered.push(tc);
|
4343 |
}
|
4344 |
}
|
@@ -4356,14 +4377,44 @@ var Template = {
|
|
4356 |
return ( this.get_tags().length > 0 ) ? true : false;
|
4357 |
},
|
4358 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4359 |
/*-** DOM **-*/
|
4360 |
|
4361 |
/**
|
4362 |
* Custom DOM initialization
|
4363 |
*/
|
4364 |
dom_init: function() {
|
4365 |
-
//Create DOM object from parsed layout
|
4366 |
this.dom_set(this.get_layout());
|
|
|
4367 |
},
|
4368 |
|
4369 |
/**
|
@@ -4376,7 +4427,7 @@ var Template = {
|
|
4376 |
var ret = $();
|
4377 |
var tags = this.get_tags(tag, prop);
|
4378 |
if ( tags.length ) {
|
4379 |
-
//Build selector
|
4380 |
var level = null;
|
4381 |
if ( this.util.is_string(tag) ) {
|
4382 |
level = ( this.util.is_string(prop) ) ? 'full' : 'tag';
|
@@ -4424,11 +4475,11 @@ var Template_Tag = {
|
|
4424 |
* @param string tag_match Extracted tag match
|
4425 |
*/
|
4426 |
parse: function(tag_match) {
|
4427 |
-
//Return default value for invalid instances
|
4428 |
if ( !this.util.is_string(tag_match) ) {
|
4429 |
return false;
|
4430 |
}
|
4431 |
-
//Parse instance options
|
4432 |
var parts = tag_match.split('|'),
|
4433 |
part;
|
4434 |
if ( !parts.length ) {
|
@@ -4439,23 +4490,23 @@ var Template_Tag = {
|
|
4439 |
prop: null,
|
4440 |
match: tag_match
|
4441 |
};
|
4442 |
-
//Get tag ID
|
4443 |
attrs.name = parts[0];
|
4444 |
-
//Get main property
|
4445 |
-
if ( attrs.name.indexOf('.')
|
4446 |
attrs.name = attrs.name.split('.', 2);
|
4447 |
attrs.prop = attrs.name[1];
|
4448 |
attrs.name = attrs.name[0];
|
4449 |
}
|
4450 |
-
//Get other attributes
|
4451 |
for ( var x = 1; x < parts.length; x++ ) {
|
4452 |
part = parts[x].split(':', 1);
|
4453 |
if ( part.length > 1 && !( part[0] in attrs ) ) {
|
4454 |
-
//Add key/value pair to attributes
|
4455 |
attrs[part[0]] = part[1];
|
4456 |
}
|
4457 |
}
|
4458 |
-
//Save to instance
|
4459 |
this.set_attributes(attrs, true);
|
4460 |
},
|
4461 |
|
@@ -4464,7 +4515,7 @@ var Template_Tag = {
|
|
4464 |
* @param Content_Item item
|
4465 |
* @return obj jQuery.Promise object that is resolved when tag is rendered
|
4466 |
* Parameters passed to callbacks
|
4467 |
-
* > tag
|
4468 |
* > output string Tag output
|
4469 |
*/
|
4470 |
render: function(item) {
|
@@ -4515,20 +4566,20 @@ var Template_Tag = {
|
|
4515 |
* @return array Class names
|
4516 |
*/
|
4517 |
get_classes: function(rtype) {
|
4518 |
-
//Build array of class names
|
4519 |
var cls = [
|
4520 |
-
//General tag class
|
4521 |
this.get_class(),
|
4522 |
-
//Tag name
|
4523 |
this.get_class('tag'),
|
4524 |
-
//Tag name + property
|
4525 |
this.get_class('full')
|
4526 |
];
|
4527 |
-
//Convert class names array to string
|
4528 |
if ( this.util.is_string(rtype) ) {
|
4529 |
cls = cls.join(rtype);
|
4530 |
}
|
4531 |
-
//Return class names
|
4532 |
return cls;
|
4533 |
},
|
4534 |
|
@@ -4542,21 +4593,27 @@ var Template_Tag = {
|
|
4542 |
*/
|
4543 |
get_class: function(level) {
|
4544 |
var cls = '';
|
|
|
4545 |
switch ( level ) {
|
4546 |
case 'tag' :
|
4547 |
-
//Tag name
|
4548 |
-
cls = this.
|
4549 |
break;
|
4550 |
case 'full' :
|
4551 |
-
//Tag name + property
|
4552 |
-
|
4553 |
-
|
4554 |
-
|
4555 |
-
|
4556 |
-
|
|
|
|
|
|
|
|
|
4557 |
break;
|
4558 |
}
|
4559 |
-
return
|
|
|
4560 |
},
|
4561 |
|
4562 |
/**
|
@@ -4565,7 +4622,15 @@ var Template_Tag = {
|
|
4565 |
* @return string Tag selector
|
4566 |
*/
|
4567 |
get_selector: function(level) {
|
4568 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4569 |
}
|
4570 |
};
|
4571 |
|
@@ -4594,40 +4659,31 @@ var Template_Tag_Handler = {
|
|
4594 |
*/
|
4595 |
render: function(item, instance) {
|
4596 |
var dfr = $.Deferred();
|
4597 |
-
//Pass to attribute method
|
4598 |
-
|
4599 |
-
//
|
4600 |
-
if ( this.util.is_promise(ret) ) {
|
4601 |
-
ret.done(function(output) {
|
4602 |
-
dfr.resolve(output);
|
4603 |
-
});
|
4604 |
-
} else {
|
4605 |
-
//Resolve non-promises immediately
|
4606 |
-
dfr.resolve(ret);
|
4607 |
-
}
|
4608 |
-
//Return promise
|
4609 |
return dfr.promise();
|
4610 |
},
|
4611 |
|
4612 |
add_prop: function(prop, fn) {
|
4613 |
-
//Get attribute
|
4614 |
var a = 'props';
|
4615 |
var props = this.get_attribute(a);
|
4616 |
-
//Validate
|
4617 |
if ( !this.util.is_string(prop) || !this.util.is_func(fn) ) {
|
4618 |
return false;
|
4619 |
}
|
4620 |
if ( !this.util.is_obj(props, false) ) {
|
4621 |
props = {};
|
4622 |
}
|
4623 |
-
//Add property
|
4624 |
props[prop] = fn;
|
4625 |
-
//Save attribute
|
4626 |
this.set_attribute(a, props);
|
4627 |
},
|
4628 |
|
4629 |
handle_prop: function(prop, item, instance) {
|
4630 |
-
//Locate property
|
4631 |
var props = this.get_attribute('props');
|
4632 |
var out = '';
|
4633 |
if ( this.util.is_obj(props) && ( prop in props ) && this.util.is_func(props[prop]) ) {
|
@@ -4642,8 +4698,6 @@ var Template_Tag_Handler = {
|
|
4642 |
View.Template_Tag_Handler = Component.extend(Template_Tag_Handler);
|
4643 |
/* Update References */
|
4644 |
|
4645 |
-
//Attach to global object
|
4646 |
-
SLB.attach('View', View);
|
4647 |
-
|
4648 |
-
View.update_refs();
|
4649 |
-
})(jQuery);
|
4 |
* @subpackage View
|
5 |
* @author Archetyped
|
6 |
*/
|
7 |
+
/* global SLB */
|
8 |
+
if ( !!window.SLB && !!SLB.attach ) { (function ($) {
|
|
|
|
|
|
|
|
|
9 |
|
10 |
/*-** Controller **-*/
|
11 |
|
37 |
*/
|
38 |
loading: [],
|
39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
/**
|
41 |
+
* Cache
|
|
|
|
|
42 |
* @var object
|
43 |
*/
|
44 |
+
cache: {},
|
45 |
|
46 |
/**
|
47 |
* Temporary component instances
|
52 |
component_temps: {},
|
53 |
|
54 |
/* Options */
|
55 |
+
options: {},
|
|
|
|
|
|
|
|
|
|
|
56 |
|
57 |
/* Methods */
|
58 |
|
59 |
/* Init */
|
60 |
|
61 |
+
/**
|
62 |
+
* Instance initialization
|
63 |
+
*/
|
64 |
+
_init: function() {
|
65 |
+
this._super();
|
66 |
+
// Component References
|
67 |
+
this.init_refs();
|
68 |
+
// Components
|
69 |
+
this.init_components();
|
70 |
+
},
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Update component references in component definitions
|
74 |
+
*/
|
75 |
+
init_refs: function() {
|
76 |
var r;
|
77 |
var ref;
|
78 |
+
var prop;
|
79 |
+
for ( prop in this ) {
|
80 |
+
prop = this[prop];
|
81 |
+
// Process only components
|
82 |
+
if ( !this.is_component(prop) ) {
|
83 |
continue;
|
84 |
}
|
85 |
+
// Update component references
|
86 |
+
if ( !this.util.is_empty(prop.prototype._refs) ) {
|
87 |
+
for ( r in prop.prototype._refs ) {
|
88 |
+
ref = prop.prototype._refs[r];
|
|
|
|
|
|
|
|
|
89 |
if ( this.util.is_string(ref) && ref in this ) {
|
90 |
+
ref = prop.prototype._refs[r] = this[ref];
|
91 |
}
|
92 |
+
if ( !this.util.is_class(ref) ) {
|
93 |
+
delete prop.prototype_refs[r];
|
94 |
}
|
95 |
}
|
96 |
}
|
97 |
}
|
|
|
|
|
|
|
98 |
},
|
99 |
|
100 |
/**
|
101 |
+
* Initialize Components
|
102 |
+
*/
|
103 |
+
init_components: function() {
|
104 |
+
this.component_defaults = [
|
105 |
+
this.Viewer
|
106 |
+
];
|
107 |
+
},
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Client Initialization
|
111 |
+
* @param obj options Global options
|
112 |
*/
|
113 |
init: function(options) {
|
114 |
var t = this;
|
115 |
+
// Defer initialization until all components loaded
|
116 |
$.when.apply($, this.loading).always(function() {
|
117 |
+
// Set options
|
118 |
$.extend(true, t.options, options);
|
119 |
+
|
120 |
+
/* Event handlers */
|
121 |
+
|
122 |
+
// History
|
123 |
$(window).on('popstate', function(e) {
|
124 |
var state = e.originalEvent.state;
|
125 |
if ( t.util.in_obj(state, ['item', 'viewer']) ) {
|
131 |
|
132 |
/* Set defaults */
|
133 |
|
134 |
+
// Items
|
135 |
t.init_items();
|
136 |
});
|
137 |
},
|
138 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
139 |
/* Components */
|
140 |
|
141 |
+
/**
|
142 |
+
* Check if default component instance can be created
|
143 |
+
* @uses View.component_defaults
|
144 |
+
* @param func type Component type to check
|
145 |
+
* @return bool TRUE if default component instance creation is allowed
|
146 |
+
*/
|
147 |
+
can_make_default_component: function(type) {
|
148 |
+
return ( -1 !== $.inArray(type, this.component_defaults) );
|
|
|
149 |
},
|
150 |
|
151 |
/**
|
152 |
+
* Check if object is valid component class
|
153 |
+
* @param func comp Component to check
|
154 |
+
* @return bool TRUE if object is valid component class
|
155 |
*/
|
156 |
+
is_component: function(comp) {
|
157 |
+
return ( this.util.is_class(comp, this.Component) );
|
|
|
158 |
},
|
159 |
|
160 |
/**
|
161 |
* Retrieve collection of components of specified type
|
162 |
+
* @param func type Component type
|
163 |
+
* @return object Component collection (Default: Empty object)
|
164 |
*/
|
165 |
get_components: function(type) {
|
166 |
+
var ret = {};
|
167 |
+
if ( this.is_component(type) ) {
|
168 |
+
// Determine collection based on component slug
|
169 |
+
var coll = type.prototype._slug + 's';
|
170 |
+
// Create default collection
|
171 |
+
if ( ! ( coll in this.cache ) ) {
|
172 |
+
this.cache[coll] = {};
|
|
|
173 |
}
|
174 |
+
ret = this.cache[coll];
|
175 |
}
|
176 |
return ret;
|
177 |
},
|
184 |
*/
|
185 |
get_component: function(type, id) {
|
186 |
var ret = null;
|
187 |
+
// Validate parameters
|
188 |
if ( !this.util.is_func(type) ) {
|
189 |
return ret;
|
190 |
}
|
191 |
+
// Sanitize id
|
192 |
if ( !this.util.is_string(id) ) {
|
193 |
id = null;
|
194 |
}
|
195 |
|
196 |
+
// Get component from collection
|
197 |
var coll = this.get_components(type);
|
198 |
if ( this.util.is_obj(coll) ) {
|
199 |
var tid = ( this.util.is_string(id) ) ? id : this.util.add_prefix('default');
|
202 |
}
|
203 |
}
|
204 |
|
205 |
+
// Default: Create default component
|
206 |
if ( this.util.is_empty(ret) ) {
|
207 |
+
if ( this.util.is_string(id) || this.can_make_default_component(type) ) {
|
208 |
ret = this.add_component(type, id);
|
209 |
}
|
210 |
}
|
211 |
+
// Return component
|
212 |
return ret;
|
213 |
},
|
214 |
|
220 |
* @return object|null New component (NULL if invalid)
|
221 |
*/
|
222 |
add_component: function(type, id, options) {
|
223 |
+
// Validate type
|
224 |
if ( !this.util.is_func(type) ) {
|
225 |
return false;
|
226 |
}
|
227 |
+
// Validate request
|
228 |
+
if ( this.util.is_empty(id) && !this.can_make_default_component(type) ) {
|
229 |
return false;
|
230 |
}
|
231 |
+
// Defaults
|
232 |
var ret = null;
|
233 |
if ( this.util.is_empty(id) ) {
|
234 |
id = this.util.add_prefix('default');
|
236 |
if ( !this.util.is_obj(options) ) {
|
237 |
options = {};
|
238 |
}
|
239 |
+
// Check if specialized method exists for component type
|
240 |
+
var m = ( 'component' !== type.prototype._slug ) ? 'add_' + type.prototype._slug : null;
|
241 |
if ( !this.util.is_empty(m) && ( m in this ) && this.util.is_func(this[m]) ) {
|
242 |
ret = this[m](id, options);
|
243 |
}
|
244 |
+
// Default process
|
245 |
else {
|
246 |
ret = new type(id, options);
|
247 |
}
|
248 |
|
249 |
+
// Add new component to collection
|
250 |
if ( this.util.is_type(ret, type) ) {
|
251 |
+
// Get collection
|
252 |
var coll = this.get_components(type);
|
253 |
+
// Add to collection
|
254 |
switch ( $.type(coll) ) {
|
255 |
case 'object' :
|
256 |
coll[id] = ret;
|
262 |
} else {
|
263 |
ret = null;
|
264 |
}
|
265 |
+
// Return new component
|
266 |
return ret;
|
267 |
},
|
268 |
|
273 |
*/
|
274 |
add_component_temp: function(type) {
|
275 |
var ret = null;
|
276 |
+
if ( this.is_component(type) ) {
|
277 |
+
// Create new instance
|
278 |
ret = new type('');
|
279 |
+
// Save to collection
|
280 |
this.component_temps[ret._slug] = ret;
|
281 |
}
|
282 |
return ret;
|
298 |
* @return bool TRUE if temp instance exists, FALSE otherwise
|
299 |
*/
|
300 |
has_component_temp: function(type) {
|
301 |
+
return ( this.is_component(type) && ( type.prototype._slug in this.component_temps ) ) ? true : false;
|
302 |
},
|
303 |
|
304 |
/* Properties */
|
310 |
*/
|
311 |
get_options: function(opts) {
|
312 |
var ret = {};
|
313 |
+
// Validate
|
314 |
if ( this.util.is_string(opts) ) {
|
315 |
opts = [opts];
|
316 |
}
|
317 |
if ( !this.util.is_array(opts) ) {
|
318 |
return ret;
|
319 |
}
|
320 |
+
// Get specified options
|
321 |
for ( var x = 0; x < opts.length; x++ ) {
|
322 |
+
// Skip if option not set
|
323 |
if ( !( opts[x] in this.options ) ) {
|
324 |
continue;
|
325 |
}
|
351 |
* Add viewer instance to collection
|
352 |
* @param string id Viewer ID
|
353 |
* @param obj options Viewer options
|
354 |
+
* @return Viewer New viewer instance
|
355 |
*/
|
356 |
add_viewer: function(id, options) {
|
357 |
+
// Create viewer
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
358 |
var v = new this.Viewer(id, options);
|
359 |
+
// Save viewer
|
360 |
+
this.get_viewers()[v.get_id()] = v;
|
361 |
+
// Return viewer
|
362 |
return v;
|
363 |
},
|
364 |
|
367 |
* @return obj Viewer instances
|
368 |
*/
|
369 |
get_viewers: function() {
|
370 |
+
return this.get_components(this.Viewer);
|
371 |
},
|
372 |
|
373 |
/**
|
387 |
* @return Viewer Viewer instance
|
388 |
*/
|
389 |
get_viewer: function(v) {
|
390 |
+
// Retrieve default viewer if specified viewer not set
|
391 |
if ( !this.has_viewer(v) ) {
|
392 |
v = this.util.add_prefix('default');
|
393 |
+
// Create default viewer if necessary
|
394 |
if ( !this.has_viewer(v) ) {
|
395 |
+
v = this.add_viewer(v);
|
396 |
+
v = v.get_id();
|
397 |
}
|
398 |
}
|
399 |
return this.get_viewers()[v];
|
405 |
* Set event handlers
|
406 |
*/
|
407 |
init_items: function() {
|
408 |
+
// Define handler
|
409 |
var t = this;
|
410 |
var handler = function() {
|
411 |
var ret = t.show_item(this);
|
415 |
return !ret;
|
416 |
};
|
417 |
|
418 |
+
// Get activated links
|
419 |
var sel = this.util.format('a[href][%s="%s"]', this.util.get_attribute('active'), 1);
|
420 |
+
// Add event handler
|
421 |
+
$(document).on('click', sel, null, handler);
|
422 |
},
|
423 |
|
424 |
+
/**
|
425 |
+
* Retrieve cached items
|
426 |
+
* @return obj Items collection
|
427 |
+
*/
|
428 |
get_items: function() {
|
429 |
return this.get_components(this.Content_Item);
|
430 |
},
|
438 |
* @return Content_Item Item instance for DOM node
|
439 |
*/
|
440 |
get_item: function(ref) {
|
441 |
+
// Evaluate reference type
|
442 |
|
443 |
+
// Content Item instance
|
444 |
if ( this.util.is_type(ref, this.Content_Item) ) {
|
445 |
return ref;
|
446 |
}
|
447 |
+
// Retrieve item instance
|
448 |
var item = null;
|
449 |
|
450 |
+
// DOM element
|
451 |
if ( this.util.in_obj(ref, 'nodeType') ) {
|
452 |
+
// Check if item instance attached to element
|
453 |
var key = this.get_component_temp(this.Content_Item).get_data_key();
|
454 |
item = $(ref).data(key);
|
455 |
}
|
456 |
+
// Cached item (index)
|
457 |
+
else if ( this.util.is_string(ref, false) ) {
|
458 |
var items = this.get_items();
|
459 |
+
if ( ref in items ) {
|
460 |
item = items[ref];
|
461 |
}
|
462 |
}
|
463 |
+
// Create default item instance
|
464 |
+
if ( !this.util.is_instance(item, this.Content_Item) ) {
|
465 |
item = this.add_item(ref);
|
466 |
}
|
467 |
return item;
|
473 |
* @return Content_Item New item instance
|
474 |
*/
|
475 |
add_item: function(el) {
|
476 |
+
return ( new this.Content_Item(el) );
|
|
|
477 |
},
|
478 |
|
479 |
/**
|
480 |
* Display item in viewer
|
481 |
* @param obj el DOM element representing item
|
482 |
+
* @return bool Display result (TRUE if item displayed without issues)
|
483 |
*/
|
484 |
show_item: function(el) {
|
485 |
+
return this.get_item(el).show();
|
|
|
486 |
},
|
487 |
|
488 |
/**
|
489 |
* Cache item instance
|
490 |
+
* @uses View.get_items() to retrieve item cache
|
491 |
* @param Content_Item item Item to cache
|
492 |
+
* @return Content_item Item instance
|
493 |
*/
|
494 |
save_item: function(item) {
|
495 |
+
if ( !this.util.is_instance(item, this.Content_Item) ) {
|
496 |
+
return item;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
497 |
}
|
498 |
+
// Save item
|
499 |
+
this.get_items()[item.get_id()] = item;
|
500 |
+
// Return item instance
|
501 |
+
return item;
|
502 |
},
|
503 |
|
504 |
/* Content Handler */
|
505 |
|
506 |
+
/**
|
507 |
+
* Retrieve content handlers
|
508 |
+
* @return object Content handlers
|
509 |
+
*/
|
510 |
get_content_handlers: function() {
|
511 |
return this.get_components(this.Content_Handler);
|
512 |
},
|
517 |
* @return Content_Handler|null Matching content handler (NULL if no matching handler found)
|
518 |
*/
|
519 |
get_content_handler: function(item) {
|
520 |
+
// Determine handler to retrieve
|
521 |
+
var type = ( this.util.is_instance(item, this.Content_Item) ) ? item.get_attribute('type', '') : item.toString();
|
522 |
+
// Retrieve handler
|
523 |
var types = this.get_content_handlers();
|
524 |
return ( type in types ) ? types[type] : null;
|
525 |
},
|
526 |
|
527 |
/**
|
528 |
+
* Add/Update Content Handler
|
529 |
* @param string id Handler ID
|
530 |
+
* @param obj attr Handler attributes
|
531 |
+
* @return obj|null Handler instance (NULL on failure)
|
532 |
*/
|
533 |
+
extend_content_handler: function(id, attr) {
|
534 |
+
var hdl = null;
|
535 |
+
if ( !this.util.is_string(id) || !this.util.is_obj(attr) ) {
|
536 |
+
return hdl;
|
537 |
}
|
538 |
+
hdl = this.get_content_handler(id);
|
539 |
+
// Add new content handler
|
540 |
+
if ( null === hdl ) {
|
541 |
+
var hdls = this.get_content_handlers();
|
542 |
+
hdls[id] = hdl = new this.Content_Handler(id, attr);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
543 |
}
|
544 |
+
// Update existing handler
|
545 |
+
else {
|
546 |
+
hdl.set_attributes(attr);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
547 |
}
|
548 |
+
// Load styles
|
549 |
+
if ( this.util.in_obj(attr, 'styles') ) {
|
550 |
+
this.load_styles(attr.styles);
|
|
|
551 |
}
|
552 |
+
return hdl;
|
|
|
553 |
},
|
554 |
|
555 |
/* Group */
|
559 |
* @param string g Group ID
|
560 |
* > If group with same ID already set, new group replaces existing one
|
561 |
* @param object attrs (optional) Group attributes
|
562 |
+
* @return Group New group
|
563 |
*/
|
564 |
add_group: function(g, attrs) {
|
565 |
+
// Create new group
|
566 |
g = new this.Group(g, attrs);
|
567 |
+
// Cache group
|
568 |
+
this.get_groups()[g.get_id()] = g;
|
569 |
+
|
570 |
+
return g;
|
571 |
},
|
572 |
|
573 |
/**
|
576 |
* @return object Registered groups
|
577 |
*/
|
578 |
get_groups: function() {
|
579 |
+
return this.get_components(this.Group);
|
580 |
},
|
581 |
|
582 |
/**
|
583 |
* Retrieve specified group
|
584 |
+
* New group created if not yet set
|
585 |
+
* @uses View.has_group()
|
586 |
+
* @uses View.add_group()
|
587 |
+
* @uses View.get_groups()
|
588 |
* @param string g Group ID
|
589 |
+
* @return Group Group instance
|
590 |
*/
|
591 |
get_group: function(g) {
|
592 |
+
return ( !this.has_group(g) ) ? this.add_group(g) : this.get_groups()[g];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
593 |
},
|
594 |
|
595 |
/**
|
598 |
* @return bool TRUE if group exists, FALSE otherwise
|
599 |
*/
|
600 |
has_group: function(g) {
|
601 |
+
return ( this.util.is_string(g) && ( g in this.get_groups() ) );
|
602 |
},
|
603 |
|
604 |
/* Theme */
|
605 |
|
606 |
/**
|
607 |
+
* Add/Update theme
|
608 |
* @param string name Theme name
|
609 |
+
* @param obj attr (optional) Theme options
|
610 |
+
* @return obj|bool Theme model
|
|
|
611 |
*/
|
612 |
+
extend_theme: function(id, attr) {
|
613 |
+
// Validate
|
|
|
614 |
if ( !this.util.is_string(id) ) {
|
615 |
return false;
|
616 |
}
|
617 |
var dfr = $.Deferred();
|
618 |
this.loading.push(dfr);
|
619 |
|
620 |
+
// Get model if it already exists
|
621 |
+
var model = this.get_theme_model(id);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
622 |
|
623 |
+
// Create default attributes for new theme
|
624 |
+
if ( this.util.is_empty(model) ) {
|
625 |
+
// Save default model
|
626 |
+
model = this.save_theme_model( {'parent': null, 'id': id} );
|
627 |
}
|
628 |
|
629 |
+
// Add custom attributes
|
630 |
+
if ( this.util.is_obj(attr) ) {
|
631 |
+
// Sanitize
|
632 |
+
if ( 'id' in attr ) {
|
633 |
+
delete(attr['id']);
|
634 |
+
}
|
635 |
+
$.extend(model, attr);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
636 |
}
|
637 |
|
638 |
+
// Load styles
|
639 |
+
if ( this.util.in_obj(attr, 'styles') ) {
|
640 |
+
this.load_styles(attr.styles);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
641 |
}
|
642 |
|
643 |
+
// Link parent model
|
644 |
+
if ( !this.util.is_obj(model.parent) ) {
|
645 |
+
model.parent = this.get_theme_model(model.parent);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
646 |
}
|
647 |
|
648 |
+
// Complete loading when all components loaded
|
649 |
+
dfr.resolve();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
650 |
return model;
|
651 |
},
|
652 |
|
655 |
* @return obj Theme models
|
656 |
*/
|
657 |
get_theme_models: function() {
|
658 |
+
// Retrieve matching theme model
|
659 |
return this.Theme.prototype._models;
|
660 |
},
|
661 |
|
670 |
},
|
671 |
|
672 |
/**
|
673 |
+
* Save theme model
|
674 |
+
* @uses View.get_theme_models() to retrieve Theme model collection
|
675 |
+
* @param obj Theme model to save
|
676 |
+
* @return obj Saved model
|
677 |
*/
|
678 |
+
save_theme_model: function(model) {
|
679 |
+
if ( this.util.in_obj(model, 'id') && this.util.is_string(model.id) ) {
|
680 |
+
// Save model
|
681 |
+
this.get_theme_models()[model.id] = model;
|
682 |
+
}
|
683 |
+
return model;
|
684 |
+
},
|
685 |
+
|
686 |
+
/**
|
687 |
+
* Add/Update Template Tag Handler
|
688 |
+
* @param string id Handler ID
|
689 |
+
* @param obj attr Handler attributes
|
690 |
+
* @return obj|bool Handler instance (FALSE on failure)
|
691 |
+
*/
|
692 |
+
extend_template_tag_handler: function(id, attr) {
|
693 |
+
if ( !this.util.is_string(id) || !this.util.is_obj(attr) ) {
|
694 |
return false;
|
695 |
}
|
696 |
+
var hdl;
|
697 |
+
var hdls = this.get_template_tag_handlers();
|
698 |
+
if ( this.util.in_obj(hdls, id) ) {
|
699 |
+
// Update existing handler
|
700 |
+
hdl = hdls[id];
|
701 |
+
hdl.set_attributes(attr);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
702 |
} else {
|
703 |
+
// Add new content handler
|
704 |
+
hdl = new this.Template_Tag_Handler(id, attr);
|
705 |
+
hdls[hdl.get_id()] = hdl;
|
706 |
}
|
707 |
+
// Load styles
|
708 |
+
if ( this.util.in_obj(attr, 'styles') ) {
|
709 |
+
this.load_styles(attr.styles);
|
710 |
+
}
|
711 |
+
// Set hooks
|
712 |
+
if ( this.util.in_obj(attr, '_hooks') ) {
|
713 |
+
attr._hooks.call(hdl);
|
714 |
+
}
|
715 |
+
return hdl;
|
716 |
},
|
717 |
|
718 |
/**
|
726 |
/**
|
727 |
* Retrieve template tag handler
|
728 |
* @param string id ID of tag handler to retrieve
|
729 |
+
* @return Template_Tag_Handler|null Tag Handler instance (NULL for invalid ID)
|
730 |
*/
|
731 |
get_template_tag_handler: function(id) {
|
732 |
var handlers = this.get_template_tag_handlers();
|
733 |
+
// Retrieve existing handler or return new handler
|
734 |
+
return ( this.util.in_obj(handlers, id) ) ? handlers[id] : null;
|
735 |
+
},
|
736 |
+
|
737 |
+
/**
|
738 |
+
* Load styles
|
739 |
+
* @param array styles Styles to load
|
740 |
+
*/
|
741 |
+
load_styles: function(styles) {
|
742 |
+
if ( this.util.is_array(styles) ) {
|
743 |
+
var out = [];
|
744 |
+
var style;
|
745 |
+
for ( var x = 0; x < styles.length; x++ ) {
|
746 |
+
style = styles[x];
|
747 |
+
if ( !this.util.in_obj(style, 'uri') || !this.util.is_string(style.uri) ) {
|
748 |
+
continue;
|
749 |
+
}
|
750 |
+
out.push('<link rel="stylesheet" type="text/css" href="' + style.uri + '" />');
|
751 |
+
}
|
752 |
+
$('head').append(out.join(''));
|
753 |
}
|
|
|
|
|
754 |
}
|
755 |
};
|
756 |
|
766 |
*/
|
767 |
_slug: 'component',
|
768 |
|
769 |
+
/**
|
770 |
+
* Component namespace
|
771 |
+
* @var string
|
772 |
+
*/
|
773 |
+
_ns: null,
|
774 |
+
|
775 |
/**
|
776 |
* Valid component references for current component
|
777 |
+
* @var object
|
778 |
* > Key (string): Property name that stores reference
|
779 |
* > Value (function): Data type of component
|
|
|
780 |
*/
|
781 |
_refs: {},
|
782 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
783 |
/**
|
784 |
* Whether DOM element and component are connected in 1:1 relationship
|
785 |
* Some components will be assigned to different DOM elements depending on usage
|
792 |
* @var DOM Element
|
793 |
*/
|
794 |
_dom: null,
|
795 |
+
|
796 |
+
/**
|
797 |
+
* Component attributes
|
798 |
+
* @var object
|
799 |
+
* > Key: Attribute ID
|
800 |
+
* > Value: Attribute value
|
801 |
+
*/
|
802 |
+
_attributes: false,
|
803 |
|
804 |
/**
|
805 |
* Default attributes
|
808 |
_attr_default: {},
|
809 |
|
810 |
/**
|
811 |
+
* Flag indicates whether default attributes have previously been parsed
|
812 |
+
* @var bool
|
813 |
*/
|
814 |
+
_attr_default_parsed: false,
|
815 |
|
816 |
/**
|
817 |
+
* Attributes passed to constructor
|
818 |
+
* @var obj
|
819 |
*/
|
820 |
+
_attr_init: null,
|
821 |
|
822 |
/**
|
823 |
* Defines how parent properties should be remapped to component properties
|
831 |
* > Key: string Event type
|
832 |
* > Value: array Handlers
|
833 |
*/
|
834 |
+
_events: {},
|
835 |
|
836 |
/**
|
837 |
* Status management
|
841 |
*/
|
842 |
_status: null,
|
843 |
|
|
|
|
|
|
|
|
|
844 |
/**
|
845 |
* Component ID
|
846 |
* @var string
|
847 |
*/
|
848 |
+
_id: '',
|
849 |
|
850 |
/* Init */
|
851 |
|
852 |
+
/**
|
853 |
+
* Constructor
|
854 |
+
* @param string id (optional) Component ID (Default ID will be generated if no valid ID provided)
|
855 |
+
* @param object attributes (optional) Component attributes
|
856 |
+
*/
|
857 |
_c: function(id, attributes) {
|
858 |
+
// Set ID
|
859 |
+
this._set_id(id);
|
860 |
+
// Save init attributes
|
861 |
+
if ( this.util.is_obj(attributes) ) {
|
862 |
+
this._attr_init = attributes;
|
863 |
+
}
|
864 |
+
// Call hooks
|
865 |
+
this._hooks();
|
866 |
},
|
867 |
|
868 |
+
/**
|
869 |
+
* Set Component parent to View module
|
870 |
+
* @uses `_super._set_parent()`
|
871 |
+
*/
|
872 |
_set_parent: function() {
|
873 |
+
this._super(View);
|
|
|
874 |
},
|
875 |
|
876 |
/**
|
877 |
* Register hooks on init
|
878 |
* Placeholder method to be overridden by child classes
|
879 |
*/
|
880 |
+
_hooks: function() {},
|
881 |
|
882 |
/* Methods */
|
883 |
|
884 |
/* Properties */
|
885 |
|
886 |
/**
|
887 |
+
* Set instance ID
|
888 |
+
* Instance ID can only be set once (will not change ID if valid ID already set)
|
889 |
+
* Generates random GUID if no valid ID provided
|
890 |
+
* @uses Utilities.guid()
|
891 |
+
* @param string id Unique ID
|
892 |
+
* @return string Instance ID
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
893 |
*/
|
894 |
+
_set_id: function(id) {
|
895 |
+
// Set ID only once
|
896 |
+
if ( this.util.is_empty(this._id) ) {
|
897 |
+
this._id = ( this.util.is_string(id) ) ? id : this.util.guid();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
898 |
}
|
899 |
+
return this._id;
|
900 |
},
|
901 |
|
902 |
/**
|
907 |
* @return string Instance ID
|
908 |
*/
|
909 |
get_id: function(ns) {
|
910 |
+
// Get raw ID
|
911 |
+
var id = this._id;
|
912 |
+
// Namespace ID
|
|
|
|
|
|
|
913 |
if ( this.util.is_bool(ns) && ns ) {
|
914 |
id = this.add_ns(id);
|
915 |
}
|
917 |
return id;
|
918 |
},
|
919 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
920 |
/**
|
921 |
* Get namespace
|
922 |
* @uses _slug for namespace segment
|
924 |
* @return string Component namespace
|
925 |
*/
|
926 |
get_ns: function() {
|
927 |
+
if ( null === this._ns ) {
|
928 |
+
this._ns = this.util.add_prefix(this._slug);
|
929 |
+
}
|
930 |
+
return this._ns;
|
931 |
},
|
932 |
|
933 |
/**
|
939 |
return ( this.util.is_string(val) ) ? this.get_ns() + '_' + val : '';
|
940 |
},
|
941 |
|
942 |
+
/**
|
943 |
+
* Retrieve status
|
944 |
+
* @param string id Status to retrieve
|
945 |
+
* @param bool raw (optional) Retrieve raw value (Default: FALSE)
|
946 |
+
* @return mixed Status value (Default: bool)
|
947 |
+
*/
|
948 |
+
get_status: function(id, raw) {
|
949 |
+
var ret = false;
|
950 |
+
if ( this.util.in_obj(this._status, id) ) {
|
951 |
+
ret = ( !!raw ) ? this._status[id] : !!this._status[id];
|
952 |
+
}
|
953 |
+
return ret;
|
954 |
+
},
|
955 |
|
956 |
/**
|
957 |
+
* Set status
|
958 |
+
* @param string id Status to retrieve
|
959 |
+
* @param mixed val Status value (Default: TRUE)
|
960 |
+
* @return mixed Status value
|
961 |
*/
|
962 |
+
set_status: function(id, val) {
|
963 |
+
// Validate ID
|
964 |
+
if ( this.util.is_string(id) ) {
|
965 |
+
// Validate value
|
966 |
+
if ( !this.util.is_set(val) ) {
|
967 |
+
val = true;
|
968 |
+
}
|
969 |
+
// Initialize status collection
|
970 |
+
if ( !this.util.is_obj(this._status, false) ) {
|
971 |
+
this._status = {};
|
972 |
+
}
|
973 |
+
// Set status
|
974 |
+
this._status[id] = val;
|
975 |
+
} else if ( !this.util.is_set(val) ) {
|
976 |
+
val = false;
|
977 |
}
|
978 |
+
return val;
|
|
|
979 |
},
|
980 |
|
981 |
/**
|
982 |
+
* Get controller object
|
983 |
+
* @uses get_parent() (alias)
|
984 |
+
* @return object Controller object (SLB.View)
|
985 |
*/
|
986 |
+
get_controller: function() {
|
987 |
+
return this.get_parent();
|
988 |
},
|
989 |
|
990 |
+
/* Components */
|
991 |
+
|
992 |
/**
|
993 |
* Check if reference exists in object
|
994 |
* @param string ref Reference ID
|
1017 |
return ( this.has_reference(ref) ) ? this._refs[ref] : null;
|
1018 |
},
|
1019 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1020 |
/**
|
1021 |
* Retrieve component reference from current object
|
1022 |
* > Procedure:
|
1023 |
+
* > Check if top-level property already set
|
1024 |
* > Check attributes
|
1025 |
+
* > Check parent object (controller)
|
|
|
|
|
1026 |
* @param string cname Component name
|
1027 |
+
* @param object options (optional) Request options
|
1028 |
+
* > check_attr bool Whether or not to check instance attributes for component (Default: TRUE)
|
1029 |
+
* > get_default bool Whether or not to retrieve default object from controller if none exists in current instance (Default: FALSE)
|
1030 |
* @return object|null Component reference (NULL if no component found)
|
1031 |
*/
|
1032 |
+
get_component: function(cname, options) {
|
1033 |
var c = null;
|
1034 |
+
// Validate request
|
1035 |
+
if ( !this.has_reference(cname) ) {
|
1036 |
return c;
|
1037 |
}
|
1038 |
|
1039 |
+
// Initialize options
|
1040 |
+
var opt_defaults = {
|
1041 |
+
check_attr: true,
|
1042 |
+
get_default: false
|
1043 |
+
};
|
1044 |
+
options = $.extend({}, opt_defaults, options);
|
1045 |
+
|
1046 |
+
// Get component type
|
1047 |
+
var ctype = this.get_reference(cname);
|
1048 |
+
|
1049 |
+
// Phase 1: Check if component reference previously set
|
|
|
1050 |
if ( this.util.is_type(this[cname], ctype) ) {
|
1051 |
return this[cname];
|
1052 |
}
|
1053 |
+
// If reference not set, iterate through component hierarchy until reference is found
|
1054 |
c = this[cname] = null;
|
1055 |
|
1056 |
+
// Phase 2: Check attributes
|
1057 |
+
if ( options.check_attr ) {
|
1058 |
c = this.get_attribute(cname);
|
1059 |
+
// Save object-specific component reference
|
1060 |
if ( !this.util.is_empty(c) ) {
|
1061 |
c = this.set_component(cname, c);
|
1062 |
}
|
1063 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1064 |
|
1065 |
+
// Phase 3: From controller (optional)
|
1066 |
+
if ( this.util.is_empty(c) && options.get_default ) {
|
1067 |
+
c = this.get_controller().get_component(ctype);
|
1068 |
}
|
1069 |
return c;
|
1070 |
},
|
1078 |
* @return object Component (NULL if invalid)
|
1079 |
*/
|
1080 |
set_component: function(name, ref, validate) {
|
1081 |
+
var invalid = null;
|
1082 |
+
// Make sure component property exists
|
1083 |
if ( !this.has_reference(name) ) {
|
1084 |
+
return invalid;
|
1085 |
}
|
1086 |
+
|
1087 |
+
// Validate reference
|
1088 |
if ( this.util.is_empty(ref) ) {
|
1089 |
+
ref = invalid;
|
1090 |
+
} else {
|
1091 |
+
var ctype = this.get_reference(name);
|
1092 |
+
|
1093 |
+
// Get component from controller when ID supplied
|
1094 |
+
if ( this.util.is_string(ref, false) ) {
|
1095 |
+
ref = this.get_controller().get_component(ctype, ref);
|
1096 |
+
}
|
1097 |
+
|
1098 |
+
// Validation callback
|
1099 |
+
if ( !this.util.is_type(ref, ctype) || ( this.util.is_func(validate) && !validate.call(this, ref) ) ) {
|
1100 |
+
ref = invalid;
|
1101 |
+
}
|
1102 |
}
|
1103 |
|
1104 |
+
// Set (or clear) component reference
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1105 |
this[name] = ref;
|
1106 |
+
// Return value for confirmation
|
1107 |
return this[name];
|
1108 |
},
|
1109 |
+
|
1110 |
+
|
1111 |
+
/**
|
1112 |
+
* Clear component reference
|
1113 |
+
* @uses set_component() to handle component manipulation
|
1114 |
+
* @param string Component name
|
1115 |
+
*/
|
1116 |
+
clear_component: function(name) {
|
1117 |
+
this.set_component(name, null);
|
1118 |
+
},
|
1119 |
|
1120 |
/* Attributes */
|
1121 |
|
1122 |
/**
|
1123 |
+
* Initialize attributes
|
1124 |
+
* @param bool force (optional) Force full initialization of attributes (Default: FALSE)
|
1125 |
+
* @return void
|
1126 |
*/
|
1127 |
init_attributes: function(force) {
|
1128 |
if ( !this.util.is_bool(force) ) {
|
1129 |
force = false;
|
1130 |
}
|
1131 |
+
if ( force || !this.util.is_obj(this._attributes) ) {
|
1132 |
+
var a = this._attributes = {};
|
1133 |
+
// Default attributes
|
1134 |
+
$.extend(a, this.init_default_attributes());
|
1135 |
+
// Instantiation attributes
|
|
|
|
|
|
|
1136 |
if ( this.util.is_obj(this._attr_init) ) {
|
1137 |
+
$.extend(a, this._attr_init);
|
1138 |
}
|
1139 |
+
// DOM attributes
|
1140 |
+
$.extend(a, this.get_dom_attributes());
|
1141 |
}
|
1142 |
},
|
1143 |
|
1144 |
/**
|
1145 |
* Generate default attributes for component
|
|
|
1146 |
* @uses View.get_options() to get values from controller
|
1147 |
* @uses _attr_map to Remap controller attributes to instance attributes
|
1148 |
* @uses _attr_default to Store default attributes
|
1149 |
+
* @return obj Default attributes
|
1150 |
*/
|
1151 |
init_default_attributes: function() {
|
1152 |
+
// Get options from controller
|
1153 |
+
if ( !this._attr_default_parsed && this.util.is_obj(this._attr_map) ) {
|
1154 |
+
var opts = this.get_controller().get_options(this.util.obj_keys(this._attr_map));
|
1155 |
+
|
1156 |
+
if ( this.util.is_obj(opts) ) {
|
1157 |
+
// Remap
|
1158 |
+
for ( var opt in this._attr_map ) {
|
1159 |
+
if ( opt in opts && null !== this._attr_map[opt]) {
|
1160 |
+
// Move value to new property
|
1161 |
+
opts[this._attr_map[opt]] = opts[opt];
|
1162 |
+
// Delete old property
|
1163 |
+
delete opts[opt];
|
1164 |
+
}
|
1165 |
}
|
1166 |
+
// Merge with default attributes
|
1167 |
+
$.extend(true, this._attr_default, opts);
|
1168 |
}
|
1169 |
+
this._attr_default_parsed = true;
|
|
|
1170 |
}
|
1171 |
return this._attr_default;
|
1172 |
},
|
1173 |
|
1174 |
/**
|
1175 |
* Retrieve DOM attributes
|
1176 |
+
* @return obj DOM Attributes
|
1177 |
*/
|
1178 |
get_dom_attributes: function() {
|
1179 |
var attrs = {};
|
1180 |
+
var el = this.dom_get(null, {'init': false});
|
1181 |
+
if ( el.length > 0 ) {
|
1182 |
+
// Get attributes from element
|
1183 |
+
var attrs_full = $(el).get(0).attributes;
|
1184 |
+
if ( this.util.is_obj(attrs_full) ) {
|
1185 |
var attr_prefix = this.util.get_attribute();
|
1186 |
+
var attr_key;
|
1187 |
+
$.each(attrs_full, function(idx, attr) {
|
1188 |
+
if ( attr.name.indexOf( attr_prefix ) === -1 ) {
|
1189 |
return true;
|
1190 |
}
|
1191 |
+
// Process custom attributes (Strip prefix)
|
1192 |
+
attr_key = attr.name.substr(attr_prefix.length + 1);
|
1193 |
+
attrs[attr_key] = attr.value;
|
|
|
1194 |
});
|
1195 |
}
|
1196 |
}
|
1199 |
|
1200 |
/**
|
1201 |
* Retrieve all instance attributes
|
1202 |
+
* @uses init_attributes() to initialize attributes (if necessary)
|
1203 |
+
* @uses _attributes object
|
1204 |
+
* @return obj Component attributes
|
1205 |
*/
|
1206 |
get_attributes: function() {
|
1207 |
+
// Initilize attributes
|
1208 |
this.init_attributes();
|
1209 |
+
// Return attributes
|
1210 |
+
return this._attributes;
|
1211 |
},
|
1212 |
|
1213 |
/**
|
1220 |
* @return mixed Attribute value (NULL if attribute is not set)
|
1221 |
*/
|
1222 |
get_attribute: function(key, def, enforce_type) {
|
1223 |
+
// Validate
|
1224 |
if ( !this.util.is_set(def) ) {
|
1225 |
def = null;
|
1226 |
}
|
1230 |
if ( !this.util.is_bool(enforce_type) ) {
|
1231 |
enforce_type = true;
|
1232 |
}
|
1233 |
+
|
1234 |
+
// Get attribute value
|
1235 |
var ret = ( this.has_attribute(key) ) ? this.get_attributes()[key] : def;
|
1236 |
+
// Validate type
|
1237 |
if ( enforce_type && ret !== def && null !== def && !this.util.is_type(ret, $.type(def), false) ) {
|
1238 |
+
// Convert type
|
1239 |
+
// Scalar default
|
1240 |
if ( this.util.is_scalar(def, false) ) {
|
|
|
1241 |
if ( !this.util.is_scalar(ret, false) ) {
|
1242 |
+
// Non-scalar attribute
|
1243 |
ret = def;
|
1244 |
} else if ( this.util.is_string(def, false) ) {
|
1245 |
+
// Convert to string
|
1246 |
ret = ret.toString();
|
1247 |
} else if ( this.util.is_num(def, false) && !this.util.is_num(ret, false) ) {
|
1248 |
+
// Convert to number
|
1249 |
ret = ( this.util.is_int(def, false) ) ? parseInt(ret) : parseFloat(ret);
|
1250 |
if ( !this.util.is_num(ret, false) ) {
|
1251 |
ret = def;
|
1252 |
}
|
1253 |
} else if ( this.util.is_bool(def, false) ) {
|
1254 |
+
// Convert to boolean
|
1255 |
ret = ( this.util.is_string(ret) || ( this.util.is_num(ret) ) );
|
1256 |
} else {
|
1257 |
+
// Fallback: Set to default
|
1258 |
ret = def;
|
1259 |
}
|
1260 |
}
|
1261 |
+
// Non-scalar default
|
1262 |
else {
|
1263 |
ret = def;
|
1264 |
}
|
1270 |
* Call attribute as method
|
1271 |
* @param string attr Attribute to call
|
1272 |
* @param arguments (optional) Additional arguments to pass to method
|
1273 |
+
* @return mixed Attribute return value (if attribute is not a function, attribute's value is returned)
|
1274 |
*/
|
1275 |
call_attribute: function(attr, args) {
|
1276 |
attr = this.get_attribute(attr);
|
1277 |
if ( this.util.is_func(attr) ) {
|
1278 |
+
// Get arguments
|
1279 |
+
args = Array.prototype.slice.call(arguments, 1);
|
1280 |
+
// Pass arguments to user-defined method
|
1281 |
attr = attr.apply(this, args);
|
1282 |
}
|
1283 |
return attr;
|
1289 |
* @return bool TRUE if exists, FALSE otherwise
|
1290 |
*/
|
1291 |
has_attribute: function(key) {
|
1292 |
+
return ( this.util.is_string(key) && ( key in this.get_attributes() ) );
|
1293 |
},
|
1294 |
|
1295 |
/**
|
1298 |
* @param bool full (optional) Whether to fully replace or merge component's attributes with new values (Default: Merge)
|
1299 |
*/
|
1300 |
set_attributes: function(attributes, full) {
|
1301 |
+
// Validate
|
1302 |
if ( !this.util.is_bool(full) ) {
|
1303 |
full = false;
|
1304 |
}
|
1305 |
|
1306 |
+
// Initialize attributes
|
1307 |
this.init_attributes(full);
|
1308 |
|
1309 |
+
// Merge new/existing attributes
|
1310 |
if ( this.util.is_obj(attributes) ) {
|
1311 |
+
$.extend(this._attributes, attributes);
|
1312 |
}
|
1313 |
},
|
1314 |
|
1317 |
* @uses get_attributes() to retrieve attributes
|
1318 |
* @param string key Attribute to set
|
1319 |
* @param mixed val Attribute value
|
1320 |
+
* @return mixed Attribute value
|
1321 |
*/
|
1322 |
set_attribute: function(key, val) {
|
1323 |
if ( this.util.is_string(key) && this.util.is_set(val) ) {
|
1349 |
*/
|
1350 |
dom_set: function(el) {
|
1351 |
el = $(el);
|
1352 |
+
// Save instance to DOM object
|
1353 |
el.data(this.get_data_key(), this);
|
1354 |
+
// Save DOM object to instance
|
1355 |
if ( this._reciprocal ) {
|
1356 |
this._dom = el;
|
1357 |
}
|
1362 |
* Retrieve attached DOM element
|
1363 |
* @uses _dom to retrieve attached DOM element
|
1364 |
* @uses dom_put() to insert child element
|
1365 |
+
* @param string element (optional) ID of child element to retrieve (Default: Main element)
|
1366 |
* @param bool put (optional) Whether to insert element if it does not exist (Default: FALSE)
|
1367 |
+
* @param obj options (optional) Runtime options
|
1368 |
* @return obj jQuery DOM element
|
1369 |
*/
|
1370 |
+
dom_get: function(element, options) {
|
1371 |
+
// Build options
|
1372 |
+
var opts_default = {
|
1373 |
+
'init': true,
|
1374 |
+
'put': false
|
1375 |
+
};
|
1376 |
+
options = ( this.util.is_obj(options) ) ? $.extend({}, opts_default, options) : opts_default;
|
1377 |
+
|
1378 |
+
// Init Component DOM
|
1379 |
+
if ( options.init && !this.get_status('dom_init') ) {
|
1380 |
this.set_status('dom_init');
|
1381 |
this.dom_init();
|
1382 |
}
|
1383 |
+
// Check for main DOM element
|
1384 |
var ret = this._dom;
|
1385 |
if ( !!ret && this.util.is_string(element) ) {
|
1386 |
var ch = $(ret).find( this.dom_get_selector(element) );
|
1387 |
+
// Check for child element
|
1388 |
if ( ch.length ) {
|
1389 |
ret = ch;
|
1390 |
+
} else if ( true === options.put || this.util.is_obj(options.put) ) {
|
1391 |
+
// Insert child element
|
1392 |
+
ret = this.dom_put(element, options.put);
|
1393 |
}
|
1394 |
}
|
1395 |
return $(ret);
|
1406 |
* Wrapper element created and added to main DOM element if not yet created
|
1407 |
* @param string element ID for DOM element (Used as class name for wrapper)
|
1408 |
* @param string|jQuery|obj content Content to add to DOM (Object contains element properties)
|
1409 |
+
* > tag : Element tag name
|
1410 |
+
* > content : Element content
|
1411 |
* @return jQuery Inserted element(s)
|
1412 |
*/
|
1413 |
dom_put: function(element, content) {
|
1414 |
var r = null;
|
1415 |
+
// Stop processing if main DOM element not set or element is not valid
|
1416 |
if ( !this.dom_has() || !this.util.is_string(element) ) {
|
1417 |
return $(r);
|
1418 |
}
|
1419 |
+
// Setup options
|
1420 |
+
var strip = ['tag', 'content', 'success'];
|
1421 |
var options = {
|
1422 |
'tag': 'div',
|
1423 |
'content': '',
|
1424 |
'class': this.add_ns(element)
|
1425 |
+
};
|
1426 |
+
// Setup content
|
1427 |
if ( !this.util.is_empty(content) ) {
|
1428 |
if ( this.util.is_type(content, jQuery, false) || this.util.is_string(content, false) ) {
|
1429 |
options.content = content;
|
1436 |
for ( var x = 0; x < strip.length; x++ ) {
|
1437 |
delete attrs[strip[x]];
|
1438 |
}
|
1439 |
+
// Retrieve existing element
|
1440 |
var d = this.dom_get();
|
1441 |
r = $(this.dom_get_selector(element), d);
|
1442 |
+
// Create element (if necessary)
|
1443 |
if ( !r.length ) {
|
1444 |
r = $(this.util.format('<%s />', options.tag), attrs).appendTo(d);
|
1445 |
+
if ( r.length && this.util.is_method(options, 'success') ) {
|
1446 |
+
options['success'].call(r, r);
|
1447 |
}
|
1448 |
}
|
1449 |
+
// Set content
|
1450 |
$(r).append(options.content);
|
1451 |
return $(r);
|
1452 |
},
|
1488 |
* @return obj Component instance (allows chaining)
|
1489 |
*/
|
1490 |
on: function(event, fn, options) {
|
1491 |
+
// Handle request types
|
1492 |
if ( !this.util.is_string(event) || !this.util.is_func(fn) ) {
|
1493 |
var t = this;
|
1494 |
var args = Array.prototype.slice.call(arguments, 1);
|
1495 |
if ( this.util.is_array(event) ) {
|
1496 |
+
// Events array
|
1497 |
$.each(event, function(idx, val) {
|
1498 |
t.on.apply(t, [val].concat(args));
|
1499 |
});
|
1500 |
} else if ( this.util.is_obj(event) ) {
|
1501 |
+
// Events map
|
1502 |
$.each(event, function(ev, hdl) {
|
1503 |
t.on.apply(t, [ev, hdl].concat(args));
|
1504 |
});
|
1506 |
return this;
|
1507 |
}
|
1508 |
|
1509 |
+
// Options
|
1510 |
|
1511 |
+
// Default options
|
1512 |
var options_std = {
|
1513 |
clear: false
|
1514 |
};
|
1515 |
if ( !this.util.is_obj(options, false) ) {
|
1516 |
+
// Reset options
|
1517 |
options = {};
|
1518 |
}
|
1519 |
+
// Build options
|
1520 |
options = $.extend({}, options_std, options);
|
1521 |
+
// Initialize events bucket
|
1522 |
if ( !this.util.is_obj(this._events, false) ) {
|
1523 |
this._events = {};
|
1524 |
}
|
1525 |
+
// Setup event
|
1526 |
var es = this._events;
|
1527 |
if ( !( event in es ) || !this.util.is_obj(es[event], false) || !!options.clear ) {
|
1528 |
es[event] = [];
|
1529 |
}
|
1530 |
+
// Add event handler
|
1531 |
es[event].push(fn);
|
1532 |
return this;
|
1533 |
},
|
1537 |
* Event handlers are executed in the context of the current component instance
|
1538 |
* Event handlers are passed parameters
|
1539 |
* > ev (obj) Event object
|
1540 |
+
* > type (string) Event name
|
1541 |
+
* > data (mixed) Data to pass to handlers (if supplied)
|
1542 |
* > component (obj) Current component instance
|
1543 |
* @param string event Custom event to trigger
|
1544 |
* @param mixed data (optional) Data to pass to event handlers
|
1548 |
var dfr = $.Deferred();
|
1549 |
var dfrs = [];
|
1550 |
var t = this;
|
1551 |
+
// Handle array of events
|
1552 |
if ( this.util.is_array(event) ) {
|
1553 |
$.each(event, function(idx, val) {
|
1554 |
+
// Collect promises from triggered events
|
1555 |
dfrs.push( t.trigger(val, data) );
|
1556 |
});
|
1557 |
+
// Resolve trigger when all events have been resolved
|
1558 |
$.when.apply(t, dfrs).done(function() {
|
1559 |
dfr.resolve();
|
1560 |
});
|
1561 |
return dfr.promise();
|
1562 |
}
|
1563 |
+
// Validate
|
1564 |
if ( !this.util.is_string(event) || !( event in this._events ) ) {
|
1565 |
dfr.resolve();
|
1566 |
return dfr.promise();
|
1567 |
}
|
1568 |
+
// Create event object
|
1569 |
var ev = { 'type': event, 'data': null };
|
1570 |
+
// Add data to event object
|
1571 |
if ( this.util.is_set(data) ) {
|
1572 |
ev.data = data;
|
1573 |
}
|
1574 |
+
// Fire handlers for event
|
1575 |
$.each(this._events[event], function(idx, fn) {
|
1576 |
+
// Call handler (`this` set to current instance)
|
1577 |
+
// Collect promises from event handlers
|
1578 |
dfrs.push( fn.call(t, ev, t) );
|
1579 |
});
|
1580 |
+
// Resolve trigger when all handlers have been resolved
|
1581 |
$.when.apply(this, dfrs).done(function() {
|
1582 |
dfr.resolve();
|
1583 |
});
|
1610 |
autofit: true,
|
1611 |
overlay_enabled: true,
|
1612 |
overlay_opacity: '0.8',
|
1613 |
+
title_default: false,
|
1614 |
container: null,
|
1615 |
slideshow_enabled: true,
|
1616 |
+
slideshow_autostart: false,
|
1617 |
slideshow_duration: 2,
|
1618 |
slideshow_active: false,
|
1619 |
slideshow_timer: null,
|
1628 |
}
|
1629 |
},
|
1630 |
|
|
|
|
|
|
|
|
|
|
|
|
|
1631 |
_attr_map: {
|
1632 |
+
'theme': null,
|
1633 |
'group_loop': 'loop',
|
1634 |
'ui_autofit': 'autofit',
|
1635 |
'ui_animate': 'animate',
|
1636 |
'ui_overlay_opacity': 'overlay_opacity',
|
1637 |
+
'ui_labels': 'labels',
|
1638 |
+
'ui_title_default': 'title_default',
|
1639 |
+
'slideshow_enabled': null,
|
1640 |
+
'slideshow_autostart': null,
|
1641 |
+
'slideshow_duration': null
|
1642 |
},
|
1643 |
|
1644 |
/* References */
|
1674 |
|
1675 |
/* Init */
|
1676 |
|
1677 |
+
_hooks: function() {
|
1678 |
var t = this;
|
1679 |
this
|
1680 |
.on(['item-prev', 'item-next'], function() {
|
1681 |
t.trigger('item-change');
|
1682 |
})
|
1683 |
.on(['close', 'item-change'], function() {
|
1684 |
+
t.unload().done(function() {
|
1685 |
+
t.unlock();
|
1686 |
+
});
|
1687 |
});
|
1688 |
},
|
1689 |
|
1690 |
/* References */
|
1691 |
|
1692 |
+
/**
|
1693 |
+
* Retrieve item instance current attached to viewer
|
1694 |
+
* @return Content_Item|NULL Current item instance
|
1695 |
+
*/
|
1696 |
+
get_item: function() {
|
1697 |
+
return this.get_component('item');
|
1698 |
+
},
|
1699 |
+
|
1700 |
/**
|
1701 |
* Set item reference
|
1702 |
* Validates item before setting
|
1704 |
* @return bool TRUE if valid item set, FALSE otherwise
|
1705 |
*/
|
1706 |
set_item: function(item) {
|
1707 |
+
// Clear existing item
|
1708 |
this.clear_item(false);
|
1709 |
var i = this.set_component('item', item, function(item) {
|
1710 |
return ( item.has_type() );
|
1712 |
return ( !this.util.is_empty(i) );
|
1713 |
},
|
1714 |
|
1715 |
+
/**
|
1716 |
+
* Clear item from viewer
|
1717 |
+
* Resets item state and removes reference (if necessary)
|
1718 |
+
* @param bool full (optional) Fully remove item? (Default: TRUE)
|
1719 |
+
*/
|
1720 |
clear_item: function(full) {
|
1721 |
+
// Validate
|
1722 |
if ( !this.util.is_bool(full) ) {
|
1723 |
full = true;
|
1724 |
}
|
1727 |
item.reset();
|
1728 |
}
|
1729 |
if ( full ) {
|
1730 |
+
this.clear_component('item');
|
1731 |
}
|
1732 |
},
|
1733 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1734 |
/**
|
1735 |
* Retrieve theme reference
|
1736 |
* @return object Theme reference
|
1737 |
*/
|
1738 |
get_theme: function() {
|
1739 |
+
// Get saved theme
|
1740 |
+
var ret = this.get_component('theme', {check_attr: false});
|
1741 |
if ( this.util.is_empty(ret) ) {
|
1742 |
+
// Theme needs to be initialized
|
1743 |
ret = this.set_component('theme', new View.Theme(this));
|
1744 |
}
|
1745 |
return ret;
|
1771 |
* @return jQuery.Promise Resolved when item processing is complete
|
1772 |
*/
|
1773 |
get_lock: function(simple, full) {
|
1774 |
+
// Validate
|
1775 |
if ( !this.util.is_bool(simple) ) {
|
1776 |
simple = false;
|
1777 |
}
|
1779 |
full = false;
|
1780 |
}
|
1781 |
var s = 'item_working';
|
1782 |
+
// Simple status
|
1783 |
if ( simple ) {
|
1784 |
return this.get_status(s);
|
1785 |
}
|
1786 |
+
// Full value
|
1787 |
var r = this.get_status(s, true);
|
1788 |
if ( !this.util.is_promise(r) ) {
|
1789 |
+
// Create default
|
1790 |
r = this.lock();
|
1791 |
}
|
1792 |
return ( full ) ? r : r.promise();
|
1836 |
mode = true;
|
1837 |
}
|
1838 |
this.loading = mode;
|
1839 |
+
// Pause/Resume slideshow
|
1840 |
if ( this.slideshow_active() ) {
|
1841 |
this.slideshow_pause(mode);
|
1842 |
}
|
1843 |
+
// Set CSS class on DOM element
|
1844 |
var m = ( mode ) ? 'addClass' : 'removeClass';
|
1845 |
$(this.dom_get())[m]('loading');
|
1846 |
if ( mode ) {
|
1847 |
+
// Loading transition
|
1848 |
this.get_theme().transition('load').always(function() {
|
1849 |
dfr.resolve();
|
1850 |
});
|
1889 |
show: function(item) {
|
1890 |
this.item_queued = item;
|
1891 |
var fin_set = 'show_deferred';
|
1892 |
+
// Validate theme
|
1893 |
var vt = 'theme_valid';
|
1894 |
var valid = true;
|
1895 |
+
if ( this.has_attribute(vt)) {
|
|
|
|
|
1896 |
valid = this.get_attribute(vt, true);
|
1897 |
+
} else {
|
1898 |
+
valid = ( this.get_theme() && this.get_theme().get_template().get_layout(false) !== "" ) ? true : false;
|
1899 |
+
this.set_attribute(vt, valid);
|
1900 |
}
|
1901 |
|
1902 |
if ( !valid ) {
|
1905 |
}
|
1906 |
var v = this;
|
1907 |
var fin = function() {
|
1908 |
+
// Lock viewer
|
1909 |
v.lock();
|
1910 |
+
// Reset callback flag (for new lock)
|
1911 |
v.set_status(fin_set, false);
|
1912 |
+
// Validate request
|
1913 |
if ( !v.set_item(v.item_queued) ) {
|
1914 |
v.close();
|
1915 |
return false;
|
1916 |
}
|
1917 |
+
// Add item to history stack
|
1918 |
v.history_add();
|
1919 |
+
// Activate
|
1920 |
v.set_active();
|
1921 |
+
// Display
|
1922 |
v.render();
|
1923 |
+
};
|
1924 |
if ( !this.is_locked() ) {
|
1925 |
fin();
|
1926 |
} else if ( !this.get_status(fin_set) ) {
|
1927 |
+
// Set flag to avoid duplicate callbacks
|
1928 |
this.set_status(fin_set);
|
1929 |
this.get_lock().always(function() {
|
1930 |
fin();
|
1936 |
|
1937 |
history_handle: function(e) {
|
1938 |
var state = e.originalEvent.state;
|
1939 |
+
// Load item
|
1940 |
+
if ( this.util.is_string(state.item, false) ) {
|
1941 |
+
this.get_controller().get_item(state.item).show({'event': e});
|
1942 |
this.trigger('item-change');
|
1943 |
} else {
|
1944 |
var count = this.history_get(true);
|
1945 |
+
// Reset count
|
1946 |
this.history_set(0);
|
1947 |
+
// Close viewer
|
1948 |
+
if ( -1 !== count ) {
|
1949 |
this.close();
|
1950 |
}
|
1951 |
}
|
1961 |
if ( !history.pushState ) {
|
1962 |
return false;
|
1963 |
}
|
1964 |
+
// Get display options
|
1965 |
var item = this.get_item();
|
1966 |
var opts = item.get_attribute('options_show');
|
1967 |
+
// Save history state
|
1968 |
var count = ( this.history_get() ) ? this.history_get(true) : 0;
|
1969 |
if ( !this.util.in_obj(opts, 'event') ) {
|
1970 |
+
// Create state
|
1971 |
var state = {
|
1972 |
'viewer': this.get_id(),
|
1973 |
'item': null,
|
1974 |
'count': count
|
1975 |
};
|
1976 |
+
// Init: Save viewer state
|
1977 |
if ( !count ) {
|
1978 |
history.replaceState(state, null);
|
1979 |
}
|
1980 |
+
// Always: Save item state
|
1981 |
+
state.item = this.get_controller().save_item(item).get_id();
|
1982 |
state.count = ++count;
|
1983 |
history.pushState(state, '');
|
1984 |
} else {
|
1987 |
count = e.state.count;
|
1988 |
}
|
1989 |
}
|
1990 |
+
// Save history item count
|
1991 |
this.history_set(count);
|
1992 |
},
|
1993 |
history_reset: function() {
|
1994 |
var count = this.history_get(true);
|
1995 |
if ( count ) {
|
1996 |
+
// Clear history status
|
1997 |
this.history_set(-1);
|
1998 |
+
// Restore history stack
|
1999 |
history.go( -1 * count );
|
2000 |
}
|
2001 |
},
|
2006 |
* @return bool TRUE if viewer is open, FALSE otherwise
|
2007 |
*/
|
2008 |
is_open: function() {
|
2009 |
+
return ( this.dom_get().css('display') === 'none' ) ? false : true;
|
2010 |
},
|
2011 |
|
2012 |
/**
|
2013 |
* Load output into DOM
|
2014 |
*/
|
2015 |
render: function() {
|
2016 |
+
// Get theme output
|
2017 |
var v = this;
|
2018 |
var thm = this.get_theme();
|
2019 |
+
v.dom_prep();
|
2020 |
+
// Register theme event handlers
|
2021 |
if ( !this.get_status('render-events') ) {
|
2022 |
this.set_status('render-events');
|
2023 |
thm
|
2024 |
+
// Loading
|
2025 |
.on('render-loading', function(ev, thm) {
|
2026 |
var dfr = $.Deferred();
|
2027 |
if ( !v.is_active() ) {
|
2029 |
return dfr.promise();
|
2030 |
}
|
2031 |
var set_pos = function() {
|
2032 |
+
// Set position
|
2033 |
v.dom_get().css('top', $(window).scrollTop());
|
2034 |
};
|
2035 |
var always = function() {
|
2036 |
+
// Set loading flag
|
2037 |
v.set_loading().always(function() {
|
2038 |
dfr.resolve();
|
2039 |
});
|
2053 |
v.open = true;
|
2054 |
})
|
2055 |
.fail(function() {
|
2056 |
+
set_pos();
|
2057 |
+
// Fallback open
|
2058 |
v.get_overlay().show();
|
2059 |
v.dom_get().show();
|
2060 |
});
|
2061 |
}
|
2062 |
return dfr.promise();
|
2063 |
})
|
2064 |
+
// Complete
|
2065 |
.on('render-complete', function(ev, thm) {
|
2066 |
+
// Stop if viewer not active
|
2067 |
if ( !v.is_active() ) {
|
2068 |
return false;
|
2069 |
}
|
2070 |
+
// Set classes
|
2071 |
var d = v.dom_get();
|
2072 |
var classes = ['item_single', 'item_multi'];
|
2073 |
var ms = ['addClass', 'removeClass'];
|
2077 |
$.each(ms, function(idx, val) {
|
2078 |
d[val](classes[idx]);
|
2079 |
});
|
2080 |
+
// Bind events
|
2081 |
v.events_complete();
|
2082 |
+
// Transition
|
2083 |
thm.transition('complete')
|
2084 |
.fail(function() {
|
2085 |
+
// Autofit content
|
2086 |
if ( v.get_attribute('autofit', true) ) {
|
2087 |
var dims = $.extend({'display': 'inline-block'}, thm.get_item_dimensions());
|
2088 |
+
thm.dom_get_tag('item', 'content').css(dims);
|
2089 |
}
|
2090 |
})
|
2091 |
.always(function() {
|
2092 |
+
// Unset loading flag
|
2093 |
v.unset_loading();
|
2094 |
+
// Trigger event
|
2095 |
v.trigger('render-complete');
|
2096 |
+
// Set viewer as initialized
|
2097 |
v.init = true;
|
2098 |
});
|
2099 |
});
|
2100 |
}
|
2101 |
+
// Render
|
2102 |
thm.render();
|
2103 |
},
|
2104 |
|
2109 |
*/
|
2110 |
dom_get_container: function() {
|
2111 |
var sel = this.get_attribute('container');
|
2112 |
+
// Set default container
|
2113 |
if ( this.util.is_empty(sel) ) {
|
2114 |
sel = '#' + this.add_ns('wrap');
|
2115 |
}
|
2116 |
+
// Add default container to DOM if not yet present
|
2117 |
var c = $(sel);
|
2118 |
if ( !c.length ) {
|
2119 |
+
// Prepare ID
|
2120 |
var id = ( sel.indexOf('#') === 0 ) ? sel.substr(1) : sel;
|
2121 |
+
// Add element
|
2122 |
c = $('<div />', {'id': id}).appendTo('body');
|
2123 |
}
|
2124 |
return c;
|
2128 |
* Custom Viewer DOM initialization
|
2129 |
*/
|
2130 |
dom_init: function() {
|
2131 |
+
// Create element & add to DOM
|
2132 |
+
// Save element to instance
|
2133 |
var d = this.dom_set($('<div/>', {
|
2134 |
'id': this.get_id(true),
|
2135 |
'class': this.get_ns()
|
2136 |
})).appendTo(this.dom_get_container()).hide();
|
2137 |
+
// Add theme classes
|
2138 |
var thm = this.get_theme();
|
2139 |
d.addClass(thm.get_classes(' '));
|
2140 |
+
// Add theme layout (basic)
|
2141 |
var v = this;
|
2142 |
if ( !this.get_status('render-init') ) {
|
2143 |
this.set_status('render-init');
|
2144 |
thm.on('render-init', function(ev) {
|
2145 |
+
// Add rendered theme layout to viewer DOM
|
2146 |
v.dom_put('layout', ev.data);
|
2147 |
});
|
2148 |
}
|
2149 |
thm.render(true);
|
2150 |
},
|
2151 |
|
2152 |
+
/**
|
2153 |
+
* Prepare DOM for viewer
|
2154 |
+
*/
|
2155 |
+
dom_prep: function(mode) {
|
2156 |
+
var m = ( this.util.is_bool(mode) && !mode ) ? 'removeClass' : 'addClass';
|
2157 |
+
$('html')[m](this.util.add_prefix('overlay'));
|
2158 |
+
},
|
2159 |
+
|
2160 |
/**
|
2161 |
* Restore DOM
|
2162 |
+
* Required after viewer is closed
|
|
|
2163 |
*/
|
2164 |
+
dom_restore: function() {
|
2165 |
+
this.dom_prep(false);
|
2166 |
+
},
|
2167 |
|
2168 |
/* Layout */
|
2169 |
|
2170 |
get_layout: function() {
|
2171 |
+
var ret = this.dom_get('layout', {
|
2172 |
+
'put': {
|
2173 |
+
'success': function() {
|
2174 |
+
$(this).hide();
|
2175 |
+
}
|
2176 |
}
|
2177 |
});
|
2178 |
return ret;
|
2203 |
var o = null;
|
2204 |
var v = this;
|
2205 |
if ( this.overlay_enabled() ) {
|
2206 |
+
o = this.dom_get('overlay', {
|
2207 |
+
'put': {
|
2208 |
+
'success': function() {
|
2209 |
+
$(this).hide().css('opacity', v.get_attribute('overlay_opacity'));
|
2210 |
+
}
|
2211 |
}
|
2212 |
});
|
2213 |
}
|
2214 |
return $(o);
|
2215 |
},
|
2216 |
|
2217 |
+
/**
|
2218 |
+
* Unload viewer
|
2219 |
+
*/
|
2220 |
unload: function() {
|
2221 |
+
var dfr = $.Deferred();
|
2222 |
+
// Unload item data
|
2223 |
+
this.get_theme().dom_get_tag('item').text('');
|
2224 |
+
dfr.resolve();
|
2225 |
+
return dfr.promise();
|
2226 |
},
|
2227 |
|
2228 |
/**
|
2229 |
* Reset viewer
|
2230 |
*/
|
2231 |
reset: function() {
|
2232 |
+
// Hide viewer
|
2233 |
this.dom_get().hide();
|
2234 |
+
// Restore DOM
|
2235 |
this.dom_restore();
|
2236 |
+
// History
|
2237 |
this.history_reset();
|
2238 |
+
// Item
|
2239 |
this.clear_item();
|
2240 |
+
// Reset properties
|
2241 |
this.set_active(false);
|
2242 |
this.set_loading(false);
|
2243 |
this.slideshow_stop();
|
2244 |
this.keys_disable();
|
2245 |
+
// Clear for next item
|
2246 |
+
this.unlock();
|
2247 |
},
|
2248 |
|
2249 |
/* Content */
|
2263 |
* Initialize event handlers upon opening lightbox
|
2264 |
*/
|
2265 |
events_open: function() {
|
2266 |
+
// Keyboard bindings
|
2267 |
this.keys_enable();
|
2268 |
if ( this.open ) {
|
2269 |
return false;
|
2270 |
}
|
2271 |
|
2272 |
+
// Control event bubbling
|
2273 |
var l = this.get_layout();
|
2274 |
l.children().click(function(ev) {
|
2275 |
ev.stopPropagation();
|
2279 |
var v = this;
|
2280 |
var close = function() {
|
2281 |
v.close();
|
2282 |
+
};
|
2283 |
+
// Layout
|
2284 |
l.click(close);
|
2285 |
+
// Overlay
|
2286 |
this.get_overlay().click(close);
|
2287 |
+
// Fire event
|
2288 |
this.trigger('events-open');
|
2289 |
},
|
2290 |
|
2295 |
if ( this.init ) {
|
2296 |
return false;
|
2297 |
}
|
2298 |
+
// Fire event
|
2299 |
this.trigger('events-complete');
|
2300 |
},
|
2301 |
|
2307 |
var v = this;
|
2308 |
var h = function(ev) {
|
2309 |
return v.keys_control(ev);
|
2310 |
+
};
|
2311 |
if ( mode ) {
|
2312 |
$(document).on(e, h);
|
2313 |
} else {
|
2321 |
|
2322 |
keys_control: function(ev) {
|
2323 |
var handlers = {
|
2324 |
+
27: this.close, /* esc */
|
2325 |
+
37: this.item_prev, /* left-arrow */
|
2326 |
+
39: this.item_next, /* right-arrow */
|
2327 |
};
|
2328 |
+
// Swap next/prev keys on RTL pages
|
2329 |
+
if ('rtl' === document.documentElement.getAttribute('dir')) {
|
2330 |
+
handlers[37] = this.item_next; /* left-arrow */
|
2331 |
+
handlers[39] = this.item_prev; /* right-arrow */
|
2332 |
+
}
|
2333 |
if ( ev.which in handlers ) {
|
2334 |
handlers[ev.which].call(this);
|
2335 |
return false;
|
2377 |
}
|
2378 |
this.set_attribute('slideshow_active', true);
|
2379 |
this.dom_get().addClass('slideshow_active');
|
2380 |
+
// Clear residual timers
|
2381 |
this.slideshow_clear_timer();
|
2382 |
+
// Start timer
|
2383 |
var v = this;
|
2384 |
this.slideshow_set_timer(function() {
|
2385 |
+
// Pause slideshow until next item fully loaded
|
2386 |
v.slideshow_pause();
|
2387 |
|
2388 |
+
// Show next item
|
2389 |
v.item_next();
|
2390 |
});
|
2391 |
this.trigger('slideshow-start');
|
2403 |
this.set_attribute('slideshow_active', false);
|
2404 |
this.dom_get().removeClass('slideshow_active');
|
2405 |
}
|
2406 |
+
// Kill timers
|
2407 |
this.slideshow_clear_timer();
|
2408 |
this.trigger('slideshow-stop');
|
2409 |
},
|
2425 |
* @param bool mode (optional) Pause (TRUE) or Resume (FALSE) slideshow (default: TRUE)
|
2426 |
*/
|
2427 |
slideshow_pause: function(mode) {
|
2428 |
+
// Validate
|
2429 |
if ( !this.util.is_bool(mode) ) {
|
2430 |
mode = true;
|
2431 |
}
|
2432 |
+
// Set viewer slideshow properties
|
2433 |
if ( this.slideshow_active() ) {
|
2434 |
if ( !mode ) {
|
2435 |
+
// Slideshow resumed
|
2436 |
this.slideshow_start();
|
2437 |
} else {
|
2438 |
+
// Slideshow paused
|
2439 |
this.slideshow_stop(false);
|
2440 |
}
|
2441 |
}
|
2457 |
var v = this;
|
2458 |
var ev = 'item-next';
|
2459 |
var st = ['events', 'viewer', ev].join('_');
|
2460 |
+
// Setup event handler
|
2461 |
if ( !g.get_status(st) ) {
|
2462 |
g.set_status(st);
|
2463 |
g.on(ev, function(e) {
|
2488 |
* Close viewer
|
2489 |
*/
|
2490 |
close: function() {
|
2491 |
+
// Deactivate
|
2492 |
this.set_active(false);
|
2493 |
var v = this;
|
2494 |
var thm = this.get_theme();
|
2495 |
thm.transition('unload')
|
2496 |
.always(function() {
|
2497 |
thm.transition('close', true).always(function() {
|
2498 |
+
// End processes
|
2499 |
v.reset();
|
2500 |
v.trigger('close');
|
2501 |
});
|
2538 |
|
2539 |
/* Init */
|
2540 |
|
2541 |
+
_hooks: function() {
|
2542 |
var t = this;
|
2543 |
this.on(['item-prev', 'item-next'], function() {
|
2544 |
t.trigger('item-change');
|
2553 |
*/
|
2554 |
get_selector: function() {
|
2555 |
if ( this.util.is_empty(this.selector) ) {
|
2556 |
+
// Build selector
|
2557 |
this.selector = this.util.format('a[%s="%s"]', this.dom_get_attribute(), this.get_id());
|
2558 |
}
|
2559 |
return this.selector;
|
2563 |
* Retrieve group items
|
2564 |
*/
|
2565 |
get_items: function() {
|
2566 |
+
var items = $(this.get_selector());
|
2567 |
+
if ( 0 === items.length && this.has_current() ) {
|
2568 |
+
items = this.get_current().dom_get();
|
2569 |
+
}
|
2570 |
return items;
|
2571 |
},
|
2572 |
|
2577 |
* @return Content_Item Item
|
2578 |
*/
|
2579 |
get_item: function(idx) {
|
2580 |
+
// Validation
|
2581 |
if ( !this.util.is_int(idx) ) {
|
2582 |
idx = 0;
|
2583 |
}
|
2584 |
+
// Retrieve all items
|
2585 |
var items = this.get_items();
|
2586 |
+
// Validate index
|
2587 |
var max = this.get_size() - 1;
|
2588 |
if ( idx > max ) {
|
2589 |
idx = max;
|
2590 |
}
|
2591 |
+
// Return specified item
|
2592 |
return items.get(idx);
|
2593 |
},
|
2594 |
|
2599 |
*/
|
2600 |
get_pos: function(item) {
|
2601 |
if ( this.util.is_empty(item) ) {
|
2602 |
+
// Get current item
|
2603 |
item = this.get_current();
|
2604 |
}
|
2605 |
return ( this.util.is_type(item, View.Content_Item) ) ? this.get_items().index(item.dom_get()) : -1;
|
2606 |
},
|
2607 |
+
|
2608 |
+
/**
|
2609 |
+
* Check if current item set in group
|
2610 |
+
* @return bool TRUE if current item is set
|
2611 |
+
*/
|
2612 |
+
has_current: function() {
|
2613 |
+
// Sanitize
|
2614 |
+
return ( !this.util.is_empty( this.get_current() ) );
|
2615 |
+
},
|
2616 |
|
2617 |
/**
|
2618 |
* Retrieve current item
|
2619 |
+
* @uses Group.current
|
2620 |
+
* @return NULL|Content_Item Current item (NULL if current item not set or invalid)
|
2621 |
*/
|
2622 |
get_current: function() {
|
2623 |
+
// Sanitize
|
2624 |
+
if ( null !== this.current && !this.util.is_type(this.current, View.Content_Item) ) {
|
2625 |
this.current = null;
|
2626 |
}
|
2627 |
return this.current;
|
2632 |
* @param Content_Item item Item to set as current
|
2633 |
*/
|
2634 |
set_current: function(item) {
|
2635 |
+
// Validate
|
2636 |
if ( this.util.is_type(item, View.Content_Item) ) {
|
2637 |
+
// Set current item
|
2638 |
this.current = item;
|
2639 |
}
|
2640 |
},
|
2641 |
|
2642 |
get_next: function(item) {
|
2643 |
+
// Validate
|
2644 |
if ( !this.util.is_type(item, View.Content_Item) ) {
|
2645 |
item = this.get_current();
|
2646 |
}
|
2647 |
+
if ( this.get_size() === 1 ) {
|
2648 |
return item;
|
2649 |
}
|
2650 |
var next = null;
|
2651 |
var pos = this.get_pos(item);
|
2652 |
+
if ( pos !== -1 ) {
|
2653 |
pos = ( pos + 1 < this.get_size() ) ? pos + 1 : 0;
|
2654 |
+
if ( 0 !== pos || item.get_viewer().get_attribute('loop') ) {
|
2655 |
next = this.get_item(pos);
|
2656 |
}
|
2657 |
}
|
2659 |
},
|
2660 |
|
2661 |
get_prev: function(item) {
|
2662 |
+
// Validate
|
2663 |
if ( !this.util.is_type(item, View.Content_Item) ) {
|
2664 |
item = this.get_current();
|
2665 |
}
|
2666 |
+
if ( this.get_size() === 1 ) {
|
2667 |
return item;
|
2668 |
}
|
2669 |
var prev = null;
|
2670 |
var pos = this.get_pos(item);
|
2671 |
+
if ( pos !== -1 && ( 0 !== pos || item.get_viewer().get_attribute('loop') ) ) {
|
2672 |
+
if ( pos === 0 ) {
|
2673 |
pos = this.get_size();
|
2674 |
}
|
2675 |
pos -= 1;
|
2680 |
|
2681 |
show_next: function(item) {
|
2682 |
if ( this.get_size() > 1 ) {
|
2683 |
+
// Retrieve item
|
2684 |
var next = this.get_next(item);
|
2685 |
if ( !next ) {
|
2686 |
if ( !this.util.is_type(item, View.Content_Item) ) {
|
2688 |
}
|
2689 |
item.get_viewer().close();
|
2690 |
}
|
2691 |
+
var i = this.get_controller().get_item(next);
|
2692 |
+
// Update current item
|
2693 |
this.set_current(i);
|
2694 |
+
// Show item
|
2695 |
i.show();
|
2696 |
+
// Fire event
|
2697 |
this.trigger('item-next');
|
2698 |
}
|
2699 |
},
|
2700 |
|
2701 |
show_prev: function(item) {
|
2702 |
if ( this.get_size() > 1 ) {
|
2703 |
+
// Retrieve item
|
2704 |
var prev = this.get_prev(item);
|
2705 |
if ( !prev ) {
|
2706 |
if ( !this.util.is_type(item, View.Content_Item) ) {
|
2708 |
}
|
2709 |
item.get_viewer().close();
|
2710 |
}
|
2711 |
+
var i = this.get_controller().get_item(prev);
|
2712 |
+
// Update current item
|
2713 |
this.set_current(i);
|
2714 |
+
// Show item
|
2715 |
i.show();
|
2716 |
+
// Fire event
|
2717 |
this.trigger('item-prev');
|
2718 |
}
|
2719 |
},
|
2727 |
},
|
2728 |
|
2729 |
is_single: function() {
|
2730 |
+
return ( this.get_size() === 1 );
|
2731 |
}
|
2732 |
};
|
2733 |
|
2778 |
* @return mixed Content_Item if valid item set, NULL otherwise
|
2779 |
*/
|
2780 |
get_item: function() {
|
2781 |
+
return this.get_component('item');
|
2782 |
},
|
2783 |
|
2784 |
/**
|
2789 |
* @return obj|null Item instance if item successfully set, NULL otherwise
|
2790 |
*/
|
2791 |
set_item: function(item) {
|
2792 |
+
// Set reference
|
2793 |
var r = this.set_component('item', item);
|
2794 |
return r;
|
2795 |
},
|
2799 |
* Sets value to NULL
|
2800 |
*/
|
2801 |
clear_item: function() {
|
2802 |
+
this.clear_component('item');
|
2803 |
},
|
2804 |
|
2805 |
/* Evaluation */
|
2810 |
* @return bool TRUE if type matches, FALSE otherwise
|
2811 |
*/
|
2812 |
match: function(item) {
|
2813 |
+
// Validate
|
2814 |
var attr = 'match';
|
2815 |
var m = this.get_attribute(attr);
|
2816 |
+
// Stop processing types with no matching algorithm
|
2817 |
if ( !this.util.is_empty(m) ) {
|
2818 |
+
// Process regex patterns
|
2819 |
|
2820 |
+
// String-based
|
2821 |
if ( this.util.is_string(m) ) {
|
2822 |
+
// Create new regexp object
|
2823 |
m = new RegExp(m, "i");
|
2824 |
this.set_attribute(attr, m);
|
2825 |
}
|
2826 |
+
// RegExp based
|
2827 |
if ( this.util.is_type(m, RegExp) ) {
|
2828 |
return m.test(item.get_uri());
|
2829 |
}
|
2830 |
+
// Process function
|
2831 |
if ( this.util.is_func(m) ) {
|
2832 |
return ( m.call(this, item) ) ? true : false;
|
2833 |
}
|
2834 |
}
|
2835 |
+
// Default
|
2836 |
return false;
|
2837 |
},
|
2838 |
|
2839 |
/* Processing/Output */
|
2840 |
|
2841 |
+
/**
|
2842 |
+
* Loads item data
|
2843 |
+
* @param obj item Content item to load data for
|
2844 |
+
* @return obj Promise that is resolved when item data is loaded
|
2845 |
+
*/
|
2846 |
+
load: function(item) {
|
2847 |
+
var dfr = $.Deferred();
|
2848 |
+
var ret = this.call_attribute('load', item, dfr);
|
2849 |
+
// Handle missing load method
|
2850 |
+
if ( null === ret ) {
|
2851 |
+
dfr.resolve();
|
2852 |
+
}
|
2853 |
+
return dfr.promise();
|
2854 |
+
},
|
2855 |
+
|
2856 |
/**
|
2857 |
* Render output to display item
|
2858 |
* @param Content_Item item Item to render output for
|
2860 |
*/
|
2861 |
render: function(item) {
|
2862 |
var dfr = $.Deferred();
|
2863 |
+
// Validate
|
2864 |
+
this.call_attribute('render', item, dfr);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2865 |
return dfr.promise();
|
2866 |
}
|
2867 |
};
|
2882 |
'group': 'Group',
|
2883 |
'type': 'Content_Handler'
|
2884 |
},
|
|
|
2885 |
|
2886 |
_attr_default: {
|
2887 |
source: null,
|
2902 |
/* Properties */
|
2903 |
|
2904 |
data: null,
|
2905 |
+
loaded: null,
|
2906 |
|
2907 |
/* Init */
|
2908 |
|
2909 |
_c: function(el) {
|
2910 |
+
// Save element to instance
|
2911 |
this.dom_set(el);
|
2912 |
+
// Default initialization
|
2913 |
this._super();
|
2914 |
},
|
2915 |
|
2925 |
*/
|
2926 |
init_default_attributes: function() {
|
2927 |
this._super();
|
2928 |
+
// Add asset properties
|
2929 |
var d = this.dom_get();
|
2930 |
+
var key = d.attr(this.util.get_attribute('asset')) || null;
|
2931 |
+
var assets = this.get_controller().assets || null;
|
2932 |
+
// Merge asset data with default attributes
|
2933 |
if ( this.util.is_string(key) ) {
|
2934 |
+
var attrs = [{}, this._attr_default, {'permalink': d.attr('href')}];
|
2935 |
if ( this.util.is_obj(assets) ) {
|
2936 |
var t = this;
|
2937 |
+
/**
|
2938 |
+
* Retrieve item assets
|
2939 |
+
* Handles variant items as well (Retrieves parent item assets)
|
2940 |
+
* @param string key Item URI
|
2941 |
+
* @return obj Item assets (Empty if no match)
|
2942 |
+
*/
|
2943 |
+
var get_assets = function(key) {
|
2944 |
var ret = {};
|
2945 |
if ( key in assets && t.util.is_obj(assets[key]) ) {
|
2946 |
+
ret = assets[key];
|
|
|
|
|
|
|
|
|
|
|
|
|
2947 |
}
|
2948 |
return ret;
|
2949 |
};
|
2950 |
+
// Save assets
|
2951 |
+
attrs.push(get_assets(key));
|
|
|
|
|
|
|
|
|
|
|
|
|
2952 |
}
|
2953 |
this._attr_default = $.extend.apply(this, attrs);
|
2954 |
}
|
2968 |
*/
|
2969 |
get_output: function() {
|
2970 |
var dfr = $.Deferred();
|
2971 |
+
// Check for cached output
|
2972 |
var ret = this.get_attribute('output');
|
2973 |
if ( this.util.is_string(ret) ) {
|
2974 |
dfr.resolve(ret);
|
2975 |
} else if ( this.has_type() ) {
|
2976 |
+
// Render output from scratch (if necessary)
|
2977 |
+
// Get item type
|
2978 |
var type = this.get_type();
|
2979 |
+
// Render type-based output
|
2980 |
var item = this;
|
2981 |
type.render(this).done(function(output) {
|
2982 |
+
// Cache output
|
2983 |
item.set_output(output);
|
2984 |
dfr.resolve(output);
|
2985 |
});
|
3016 |
* @return string Item URI
|
3017 |
*/
|
3018 |
get_uri: function(mode) {
|
3019 |
+
// Validate
|
3020 |
+
if ( $.inArray(mode ,['source', 'permalink']) === -1 ) {
|
3021 |
mode = 'source';
|
3022 |
}
|
3023 |
+
// Retrieve URI
|
3024 |
var ret = this.get_attribute(mode);
|
3025 |
if ( !this.util.is_string(ret) ) {
|
3026 |
+
ret = ( 'source' === mode ) ? this.get_attribute('permalink') : '';
|
3027 |
}
|
3028 |
+
// Format
|
3029 |
+
ret = ret.replace(/&(#38|amp);/, '&');
|
3030 |
return ret;
|
3031 |
},
|
3032 |
|
3036 |
get_title: function() {
|
3037 |
var prop = 'title';
|
3038 |
var prop_cached = prop + '_cached';
|
3039 |
+
// Check for cached value
|
3040 |
if ( this.has_attribute(prop_cached) ) {
|
3041 |
return this.get_attribute(prop_cached, '');
|
3042 |
}
|
3043 |
|
3044 |
var title = '';
|
3045 |
+
// Generate title from DOM values
|
|
|
3046 |
var dom = this.dom_get();
|
3047 |
|
3048 |
+
// DOM-based caption
|
3049 |
+
if ( dom.length ) {
|
3050 |
+
// Link title (generally must be manually-entered)
|
3051 |
title = dom.attr(prop);
|
3052 |
|
3053 |
+
// Figcaption element
|
3054 |
if ( !title ) {
|
3055 |
+
title = dom.closest('figure').find('figcaption').first().html();
|
3056 |
+
}
|
3057 |
+
|
3058 |
+
// Class Name
|
3059 |
+
if ( !title ) {
|
3060 |
+
title = dom.closest('figure').find('.wp-caption-text').first().html();
|
3061 |
}
|
3062 |
}
|
3063 |
|
3064 |
+
// Saved attributes
|
3065 |
if ( !title ) {
|
3066 |
var props = ['caption', 'title'];
|
3067 |
for ( var x = 0; x < props.length; x++ ) {
|
3072 |
}
|
3073 |
}
|
3074 |
|
3075 |
+
// Fallbacks
|
3076 |
if ( !title && dom.length ) {
|
3077 |
+
// Alt attribute
|
3078 |
title = dom.find('img').first().attr('alt');
|
3079 |
|
3080 |
+
// Element text
|
3081 |
if ( !title ) {
|
3082 |
+
title = dom.get(0).innerText.trim();
|
3083 |
}
|
3084 |
}
|
3085 |
|
3086 |
+
// Validate
|
3087 |
if ( !this.util.is_string(title, false) ) {
|
3088 |
title = '';
|
3089 |
}
|
3090 |
+
// Strip default title
|
3091 |
+
if ( !this.util.is_empty(title) && !this.get_viewer().get_attribute('title_default') ) {
|
3092 |
+
var f = this.get_uri('source');
|
3093 |
+
var i = f.lastIndexOf('/');
|
3094 |
+
if ( -1 !== i ) {
|
3095 |
+
f = f.substr(i + 1);
|
3096 |
+
i = f.lastIndexOf('.');
|
3097 |
+
if ( -1 !== i ) {
|
3098 |
+
f = f.substr(0, i);
|
3099 |
+
}
|
3100 |
+
if ( title === f ) {
|
3101 |
+
title = '';
|
3102 |
+
}
|
3103 |
+
}
|
3104 |
+
}
|
3105 |
+
|
3106 |
|
3107 |
+
// Cache retrieved value
|
3108 |
this.set_attribute(prop_cached, title);
|
3109 |
+
// Return value
|
3110 |
return title;
|
3111 |
},
|
3112 |
|
3127 |
this.data = data;
|
3128 |
},
|
3129 |
|
3130 |
+
get_data: function() {
|
3131 |
+
return this.data;
|
3132 |
+
},
|
3133 |
+
|
3134 |
/**
|
3135 |
* Determine gallery type
|
3136 |
* @return string|null Gallery type ID (NULL if item not in gallery)
|
3159 |
*/
|
3160 |
in_gallery: function(gType) {
|
3161 |
var type = this.gallery_type();
|
3162 |
+
// No gallery
|
3163 |
+
if ( null === type ) {
|
3164 |
return false;
|
3165 |
}
|
3166 |
+
// Boolean check
|
3167 |
if ( !this.util.is_string(gType) ) {
|
3168 |
return true;
|
3169 |
}
|
3170 |
+
// Check for specific gallery type
|
3171 |
+
return ( gType === type ) ? true : false;
|
3172 |
},
|
3173 |
|
3174 |
/*-** Component References **-*/
|
3176 |
/* Viewer */
|
3177 |
|
3178 |
get_viewer: function() {
|
3179 |
+
return this.get_component('viewer', {get_default: true});
|
3180 |
},
|
3181 |
|
3182 |
/**
|
3199 |
*/
|
3200 |
get_group: function(set_current) {
|
3201 |
var prop = 'group';
|
3202 |
+
// Check if group reference already set
|
3203 |
+
var g = this.get_component(prop);
|
3204 |
if ( g ) {
|
3205 |
} else {
|
3206 |
+
// Set empty group if no group exists
|
3207 |
g = this.set_component(prop, new View.Group());
|
3208 |
set_current = true;
|
3209 |
}
|
3221 |
* > Item's group is reset if invalid group provided
|
3222 |
*/
|
3223 |
set_group: function(g) {
|
3224 |
+
// If group ID set, get object reference
|
3225 |
if ( this.util.is_string(g) ) {
|
3226 |
+
g = this.get_controller().get_group(g);
|
3227 |
}
|
3228 |
|
3229 |
+
// Set (or clear) group property
|
3230 |
this.group = ( this.util.is_type(g, View.Group) ) ? g : false;
|
3231 |
},
|
3232 |
|
3239 |
* @return Content_Handler|null Content Handler of item (NULL no valid type exists)
|
3240 |
*/
|
3241 |
get_type: function() {
|
3242 |
+
var t = this.get_component('type', {check_attr: false});
|
3243 |
if ( !t ) {
|
3244 |
+
t = this.set_type(this.get_controller().get_content_handler(this));
|
3245 |
}
|
3246 |
return t;
|
3247 |
},
|
3273 |
* @param obj options (optional) Options
|
3274 |
*/
|
3275 |
show: function(options) {
|
3276 |
+
// Validate content handler
|
3277 |
if ( !this.has_type() ) {
|
3278 |
return false;
|
3279 |
}
|
3280 |
+
// Set display options
|
3281 |
this.set_attribute('options_show', options);
|
3282 |
+
// Retrieve viewer
|
3283 |
var v = this.get_viewer();
|
3284 |
+
// Load item
|
3285 |
+
this.load();
|
3286 |
var ret = v.show(this);
|
3287 |
return ret;
|
3288 |
},
|
3289 |
|
3290 |
+
/**
|
3291 |
+
* Load item data
|
3292 |
+
*
|
3293 |
+
* Retrieves item data from external sources (if necessary)
|
3294 |
+
* @uses this.loaded to save loaded state
|
3295 |
+
* @return obj Promise that is resolved when item data is loaded
|
3296 |
+
*/
|
3297 |
+
load: function() {
|
3298 |
+
if ( !this.util.is_promise(this.loaded) ) {
|
3299 |
+
// Load item data (via content handler)
|
3300 |
+
this.loaded = this.get_type().load(this);
|
3301 |
+
}
|
3302 |
+
return this.loaded.promise();
|
3303 |
+
},
|
3304 |
+
|
3305 |
reset: function() {
|
3306 |
this.set_attribute('options_show', null);
|
3307 |
}
|
3331 |
* @return mixed Attribute value
|
3332 |
*/
|
3333 |
get_attribute: function(key, def, check_model, enforce_type) {
|
3334 |
+
// Validate
|
3335 |
if ( !this.util.is_string(key) ) {
|
3336 |
+
// Invalid requests sent straight to super method
|
3337 |
return this._super(key, def, enforce_type);
|
3338 |
}
|
3339 |
if ( !this.util.is_bool(check_model) ) {
|
3340 |
check_model = true;
|
3341 |
}
|
3342 |
var ret = null;
|
3343 |
+
// Check model for attribute
|
3344 |
if ( check_model ) {
|
3345 |
var m = this.get_ancestor(key, false);
|
3346 |
if ( this.util.in_obj(m, key) ) {
|
3347 |
ret = m[key];
|
3348 |
}
|
3349 |
}
|
3350 |
+
// Check standard attributes as fallback
|
3351 |
+
if ( null === ret ) {
|
3352 |
ret = this._super(key, def, enforce_type);
|
3353 |
}
|
3354 |
return ret;
|
3355 |
},
|
3356 |
+
|
3357 |
+
/**
|
3358 |
+
* Get attribute recursively
|
3359 |
+
* Merges objects from ancestors together
|
3360 |
+
* @see Component.get_attribute() for more information
|
3361 |
+
*/
|
3362 |
+
get_attribute_recursive: function(key, def, enforce_type) {
|
3363 |
+
var ret = this.get_attribute(key, def, true, enforce_type);
|
3364 |
+
if ( this.util.is_obj(ret) ) {
|
3365 |
+
// Merge ancestor objects
|
3366 |
+
var models = this.get_ancestors(false);
|
3367 |
+
ret = [ret];
|
3368 |
+
var t = this;
|
3369 |
+
$.each(models, function(idx, model) {
|
3370 |
+
if ( key in model && t.util.is_obj(model[key]) ) {
|
3371 |
+
ret.push(model[key]);
|
3372 |
+
}
|
3373 |
+
});
|
3374 |
+
// Merge transition handlers into current theme
|
3375 |
+
ret.push({});
|
3376 |
+
ret = $.extend.apply($, ret.reverse());
|
3377 |
+
}
|
3378 |
+
return ret;
|
3379 |
+
},
|
3380 |
|
3381 |
/**
|
3382 |
* Set attribute value
|
3390 |
* @return mixed Attribute value
|
3391 |
*/
|
3392 |
set_attribute: function(key, val, use_model) {
|
3393 |
+
// Validate
|
3394 |
if ( ( !this.util.is_string(key) ) || !this.util.is_set(val) ) {
|
3395 |
return false;
|
3396 |
}
|
3397 |
if ( !this.util.is_bool(use_model) && !this.util.is_obj(use_model) ) {
|
3398 |
use_model = true;
|
3399 |
}
|
3400 |
+
// Determine where to set attribute
|
3401 |
if ( !!use_model ) {
|
3402 |
var model = this.util.is_obj(use_model) ? use_model : this.get_model();
|
3403 |
|
3404 |
+
// Set attribute in model
|
3405 |
model[key] = val;
|
3406 |
} else {
|
3407 |
+
// Set as standard attribute
|
3408 |
this._super(key, val);
|
3409 |
}
|
3410 |
return val;
|
3420 |
get_model: function() {
|
3421 |
var m = this.get_attribute('model', null, false);
|
3422 |
if ( !this.util.is_obj(m) ) {
|
3423 |
+
// Set default value
|
3424 |
m = {};
|
3425 |
this.set_attribute('model', m, false);
|
3426 |
}
|
3459 |
ret.push(m);
|
3460 |
m = ( this.util.in_obj(m, 'parent') && this.util.is_obj(m.parent) ) ? m.parent : null;
|
3461 |
}
|
3462 |
+
// Remove current model from list
|
3463 |
if ( !inc_current ) {
|
3464 |
ret.shift();
|
3465 |
}
|
3474 |
* @return obj Theme ancestor (Default: Current theme model)
|
3475 |
*/
|
3476 |
get_ancestor: function(attr, safe_mode) {
|
3477 |
+
// Validate
|
3478 |
if ( !this.util.is_string(attr) ) {
|
3479 |
return false;
|
3480 |
}
|
3481 |
if ( !this.util.is_bool(safe_mode) ) {
|
3482 |
safe_mode = true;
|
3483 |
}
|
3484 |
+
var mcurr = this.get_model();
|
3485 |
+
var m = mcurr;
|
3486 |
var found = false;
|
3487 |
while ( this.util.is_obj(m) ) {
|
3488 |
+
// Check if attribute exists in model
|
3489 |
if ( this.util.in_obj(m, attr) && !this.util.is_empty(m[attr]) ) {
|
3490 |
found = true;
|
3491 |
break;
|
3492 |
}
|
3493 |
+
// Get next model
|
3494 |
m = ( this.util.in_obj(m, 'parent') ) ? m['parent'] : null;
|
3495 |
}
|
3496 |
if ( !found ) {
|
3497 |
if ( safe_mode ) {
|
3498 |
+
// Use current model as fallback
|
3499 |
if ( this.util.is_empty(m) ) {
|
3500 |
m = mcurr;
|
3501 |
}
|
3502 |
+
// Add attribute to object
|
3503 |
if ( !this.util.in_obj(m, attr) ) {
|
3504 |
m[attr] = null;
|
3505 |
}
|
3528 |
},
|
3529 |
_models: {},
|
3530 |
|
|
|
|
|
3531 |
_attr_default: {
|
3532 |
template: null,
|
3533 |
model: null
|
3545 |
* @see Component._c()
|
3546 |
*/
|
3547 |
_c: function(id, attributes, viewer) {
|
3548 |
+
// Validate
|
3549 |
+
if ( arguments.length === 1 && this.util.is_type(arguments[0], View.Viewer) ) {
|
3550 |
viewer = arguments[0];
|
3551 |
id = null;
|
3552 |
}
|
3553 |
+
// Pass parameters to parent constructor
|
3554 |
this._super(id, attributes);
|
3555 |
|
3556 |
+
// Set viewer instance
|
3557 |
this.set_viewer(viewer);
|
3558 |
|
3559 |
+
// Set theme model
|
3560 |
this.set_model(id);
|
3561 |
},
|
3562 |
|
3563 |
/* Viewer */
|
3564 |
|
3565 |
get_viewer: function() {
|
3566 |
+
return this.get_component('viewer', {check_attr: false, get_default: true});
|
3567 |
},
|
3568 |
|
3569 |
/**
|
3584 |
* @return Template instance
|
3585 |
*/
|
3586 |
get_template: function() {
|
3587 |
+
// Get saved template
|
3588 |
+
var ret = this.get_component('template');
|
3589 |
+
// Template needs to be initialized
|
3590 |
if ( this.util.is_empty(ret) ) {
|
3591 |
+
// Pass model to Template instance
|
3592 |
var attr = { 'theme': this, 'model': this.get_model() };
|
3593 |
ret = this.set_component('template', new View.Template(attr));
|
3594 |
}
|
3595 |
return ret;
|
3596 |
},
|
3597 |
|
3598 |
+
/* Tags */
|
3599 |
+
|
3600 |
/**
|
3601 |
* Retrieve tags from template
|
3602 |
* All tags will be retrieved by default
|
3618 |
return $(this.get_template().dom_get_tag(tag, prop));
|
3619 |
},
|
3620 |
|
3621 |
+
/**
|
3622 |
+
* Retrieve template tag CSS selector
|
3623 |
+
* @uses Template.get_tag_selector()
|
3624 |
+
* @param name string Tag name
|
3625 |
+
* @param prop string Tag Property
|
3626 |
+
* @return string Template tag CSS selector
|
3627 |
+
*/
|
3628 |
+
get_tag_selector: function(name, prop) {
|
3629 |
+
return this.get_template().get_tag_selector(name, prop);
|
3630 |
+
},
|
3631 |
+
|
3632 |
/* Model */
|
3633 |
|
3634 |
/**
|
3647 |
*/
|
3648 |
get_model: function(id) {
|
3649 |
var ret = null;
|
3650 |
+
// Pass request to superclass method
|
3651 |
if ( !this.util.is_set(id) && this.util.is_obj( this.get_attribute('model', null, false) ) ) {
|
3652 |
ret = this._super();
|
3653 |
} else {
|
3654 |
+
// Retrieve matching theme model
|
3655 |
var models = this.get_models();
|
3656 |
if ( !this.util.is_string(id) ) {
|
3657 |
+
id = this.get_controller().get_option('theme_default');
|
3658 |
}
|
3659 |
+
// Select first theme model if specified model is invalid
|
3660 |
if ( !this.util.in_obj(models, id) ) {
|
3661 |
id = $.map(models, function(v, key) { return key; })[0];
|
3662 |
}
|
3671 |
*/
|
3672 |
set_model: function(id) {
|
3673 |
this.set_attribute('model', this.get_model(id), false);
|
3674 |
+
/* @deprecated
|
3675 |
+
// Set ID using model attributes (if necessary)
|
3676 |
+
if ( !this._check_id(true) ) {
|
3677 |
var m = this.get_model();
|
3678 |
if ( 'id' in m ) {
|
3679 |
+
this._set_id(m.id);
|
3680 |
}
|
3681 |
}
|
3682 |
+
*/
|
3683 |
},
|
3684 |
|
3685 |
/* Properties */
|
3694 |
* @return array Class names
|
3695 |
*/
|
3696 |
get_classes: function(rtype) {
|
3697 |
+
// Build array of class names
|
3698 |
var cls = [];
|
3699 |
var thm = this;
|
3700 |
+
// Include theme parent's class name
|
3701 |
var models = this.get_ancestors(true);
|
3702 |
$.each(models, function(idx, model) {
|
3703 |
cls.push(thm.add_ns(model.id));
|
3704 |
});
|
3705 |
+
// Convert class names array to string
|
3706 |
if ( this.util.is_string(rtype) ) {
|
3707 |
cls = cls.join(rtype);
|
3708 |
}
|
3709 |
+
// Return class names
|
3710 |
return cls;
|
3711 |
},
|
3712 |
|
3718 |
*/
|
3719 |
get_measurement: function(attr, def) {
|
3720 |
var meas = null;
|
3721 |
+
// Validate
|
3722 |
if ( !this.util.is_string(attr) ) {
|
3723 |
return meas;
|
3724 |
}
|
3725 |
if ( !this.util.is_obj(def, false) ) {
|
3726 |
def = {};
|
3727 |
}
|
3728 |
+
// Manage cache
|
3729 |
var attr_cache = this.util.format('%s_cache', attr);
|
3730 |
var cache = this.get_attribute(attr_cache, {}, false);
|
3731 |
var status = '_status';
|
3732 |
var item = this.get_viewer().get_item();
|
3733 |
var w = $(window);
|
3734 |
+
// Check cache freshness
|
3735 |
+
if ( !( status in cache ) || !this.util.is_obj(cache[status]) || cache[status].width !== w.width() || cache[status].height !== w.height() ) {
|
3736 |
cache = {};
|
3737 |
}
|
3738 |
if ( this.util.is_empty(cache) ) {
|
3739 |
+
// Set status
|
3740 |
cache[status] = {
|
3741 |
'width': w.width(),
|
3742 |
'height': w.height(),
|
3743 |
'index': []
|
3744 |
};
|
3745 |
}
|
3746 |
+
// Retrieve cached values
|
3747 |
var pos = $.inArray(item, cache[status].index);
|
3748 |
+
if ( pos !== -1 && pos in cache ) {
|
3749 |
meas = cache[pos];
|
3750 |
}
|
3751 |
+
// Generate measurement
|
3752 |
if ( !this.util.is_obj(meas) ) {
|
3753 |
+
// Get custom theme measurement
|
3754 |
meas = this.call_attribute(attr);
|
3755 |
if ( !this.util.is_obj(meas) ) {
|
3756 |
+
// Retrieve fallback value
|
3757 |
meas = this.get_measurement_default(attr);
|
3758 |
}
|
3759 |
}
|
3760 |
+
// Normalize measurement
|
3761 |
meas = ( this.util.is_obj(meas) ) ? $.extend({}, def, meas) : def;
|
3762 |
+
// Cache measurement
|
3763 |
pos = cache[status].index.push(item) - 1;
|
3764 |
cache[pos] = meas;
|
3765 |
this.set_attribute(attr_cache, cache, false);
|
3766 |
+
// Return measurement (copy)
|
3767 |
return $.extend({}, meas);
|
3768 |
},
|
3769 |
|
3773 |
* @return obj Measurement values
|
3774 |
*/
|
3775 |
get_measurement_default: function(attr) {
|
3776 |
+
// Validate
|
3777 |
if ( !this.util.is_string(attr) ) {
|
3778 |
return null;
|
3779 |
}
|
3780 |
+
// Find default handler
|
3781 |
attr = this.util.format('get_%s_default', attr);
|
3782 |
if ( this.util.in_obj(this, attr) ) {
|
3783 |
attr = this[attr];
|
3784 |
if ( this.util.is_func(attr) ) {
|
3785 |
+
// Execute default handler
|
3786 |
attr = attr.call(this);
|
3787 |
}
|
3788 |
} else {
|
3807 |
var offset = { 'width': 0, 'height': 0 };
|
3808 |
var v = this.get_viewer();
|
3809 |
var vn = v.dom_get();
|
3810 |
+
// Clone viewer
|
3811 |
var vc = vn
|
3812 |
.clone()
|
3813 |
.attr('id', '')
|
3814 |
.css({'visibility': 'hidden', 'position': 'absolute', 'top': ''})
|
3815 |
.removeClass('loading')
|
3816 |
.appendTo(vn.parent());
|
3817 |
+
// Get offset from layout node
|
3818 |
var l = vc.find(v.dom_get_selector('layout'));
|
3819 |
if ( l.length ) {
|
3820 |
+
// Clear inline styles
|
3821 |
l.find('*').css({
|
3822 |
'width': '',
|
3823 |
'height': '',
|
3824 |
'display': ''
|
3825 |
});
|
3826 |
+
// Resize content nodes
|
3827 |
var tags = this.get_tags('item', 'content');
|
3828 |
if ( tags.length ) {
|
3829 |
var offset_item = v.get_item().get_dimensions();
|
3830 |
+
// Set content dimensions
|
3831 |
tags = $(l.find(tags[0].get_selector('full')).get(0)).css({'width': offset_item.width, 'height': offset_item.height});
|
3832 |
$.each(offset_item, function(key, val) {
|
3833 |
offset[key] = -1 * val;
|
3834 |
});
|
3835 |
}
|
3836 |
|
3837 |
+
// Set offset
|
3838 |
offset.width += l.width();
|
3839 |
offset.height += l.height();
|
3840 |
+
// Normalize
|
3841 |
$.each(offset, function(key, val) {
|
3842 |
if ( val < 0 ) {
|
3843 |
offset[key] = 0;
|
3865 |
var v = this.get_viewer();
|
3866 |
var dims = v.get_item().get_dimensions();
|
3867 |
if ( v.get_attribute('autofit', false) ) {
|
3868 |
+
// Get maximum dimensions
|
3869 |
var margin = this.get_margin();
|
3870 |
var offset = this.get_offset();
|
3871 |
offset.height += margin.height;
|
3877 |
if ( max.height > offset.height ) {
|
3878 |
max.height -= offset.height;
|
3879 |
}
|
3880 |
+
// Get resize factor
|
3881 |
var factor = Math.min(max.width / dims.width, max.height / dims.height);
|
3882 |
+
// Resize dimensions
|
3883 |
if ( factor < 1 ) {
|
3884 |
+
$.each(dims, function(key) {
|
3885 |
dims[key] = Math.round(dims[key] * factor);
|
3886 |
});
|
3887 |
}
|
3896 |
get_dimensions: function() {
|
3897 |
var dims = this.get_item_dimensions();
|
3898 |
var offset = this.get_offset();
|
3899 |
+
$.each(dims, function(key) {
|
3900 |
dims[key] += offset[key];
|
3901 |
});
|
3902 |
return dims;
|
3903 |
},
|
3904 |
|
3905 |
+
/**
|
3906 |
+
* Retrieve all breakpoints
|
3907 |
+
* @return object Breakpoints
|
3908 |
+
*/
|
3909 |
+
get_breakpoints: function() {
|
3910 |
+
return this.get_attribute_recursive('breakpoints');
|
3911 |
+
},
|
3912 |
+
|
3913 |
+
/**
|
3914 |
+
* Get breakpoint value
|
3915 |
+
* @param string target Breakpoint target
|
3916 |
+
* @return int Breakpoint value (pixels)
|
3917 |
+
*/
|
3918 |
+
get_breakpoint: function(target) {
|
3919 |
+
var ret = 0;
|
3920 |
+
if ( this.util.is_string(target) ) {
|
3921 |
+
var b = this.get_attribute_recursive('breakpoints');
|
3922 |
+
if ( this.util.is_obj(b) && target in b ) {
|
3923 |
+
ret = b[target];
|
3924 |
+
}
|
3925 |
+
}
|
3926 |
+
return ret;
|
3927 |
+
},
|
3928 |
+
|
3929 |
/* Output */
|
3930 |
|
3931 |
/**
|
3939 |
var st = 'events_render';
|
3940 |
if ( !this.get_status(st) ) {
|
3941 |
this.set_status(st);
|
3942 |
+
// Register events
|
3943 |
tpl.on([
|
3944 |
'render-init',
|
3945 |
'render-loading',
|
3949 |
return thm.trigger(ev.type, ev.data);
|
3950 |
});
|
3951 |
}
|
3952 |
+
// Render template
|
3953 |
tpl.render(init);
|
3954 |
},
|
3955 |
|
3968 |
el.stop(false, true);
|
3969 |
}
|
3970 |
});
|
3971 |
+
};
|
3972 |
+
// Stop queued animations
|
3973 |
if ( !!clear_queue ) {
|
3974 |
anim_stop();
|
3975 |
}
|
3976 |
+
// Get transition handlers
|
3977 |
var attr_set = [attr, 'set'].join('_');
|
3978 |
var trns;
|
3979 |
if ( !this.get_attribute(attr_set) ) {
|
3986 |
trns.push(model[attr]);
|
3987 |
}
|
3988 |
});
|
3989 |
+
// Merge transition handlers into current theme
|
3990 |
trns.push({});
|
3991 |
trns = this.set_attribute(attr, $.extend.apply($, trns.reverse()));
|
3992 |
} else {
|
3993 |
trns = this.get_attribute(attr, {});
|
3994 |
}
|
3995 |
if ( this.util.is_method(trns, event) ) {
|
3996 |
+
// Disable animations if necessary
|
3997 |
if ( !anim_on ) {
|
3998 |
fx_temp = $.fx.off;
|
3999 |
$.fx.off = true;
|
4000 |
}
|
4001 |
+
// Pass control to transition event
|
4002 |
dfr = trns[event].call(this, v, $.Deferred());
|
4003 |
}
|
4004 |
}
|
4007 |
dfr.reject();
|
4008 |
}
|
4009 |
dfr.always(function() {
|
4010 |
+
// Restore animation state
|
4011 |
if ( null !== fx_temp ) {
|
4012 |
$.fx.off = fx_temp;
|
4013 |
}
|
4031 |
_refs: {
|
4032 |
'theme': 'Theme'
|
4033 |
},
|
4034 |
+
|
|
|
4035 |
_attr_default: {
|
4036 |
/**
|
4037 |
* URI to layout (raw) file
|
4074 |
this._super('', attributes);
|
4075 |
},
|
4076 |
|
4077 |
+
_hooks: function() {
|
4078 |
+
// TODO: Refactor to event that can save retrieved tags
|
4079 |
+
// (`dom_init` event called during attribute initialization so tags are not saved)
|
4080 |
+
this.on('dom_init', function(ev) {
|
4081 |
+
// Init tag handlers
|
4082 |
+
var tags = this.get_tags(null, null, true);
|
4083 |
+
var names = [];
|
4084 |
+
var t = this;
|
4085 |
+
$.each(tags, function(idx, tag) {
|
4086 |
+
var name = tag.get_name();
|
4087 |
+
if ( -1 === $.inArray(name, names) ) {
|
4088 |
+
names.push(name);
|
4089 |
+
tag.get_handler().trigger(ev.type, {template: t});
|
4090 |
+
}
|
4091 |
+
});
|
4092 |
+
});
|
4093 |
+
},
|
4094 |
+
|
4095 |
get_theme: function() {
|
4096 |
+
var ret = this.get_component('theme');
|
4097 |
return ret;
|
4098 |
},
|
4099 |
|
4112 |
if ( !this.util.is_bool(init) ) {
|
4113 |
init = false;
|
4114 |
}
|
4115 |
+
// Populate layout
|
4116 |
if ( !init ) {
|
4117 |
if ( !v.is_active() ) {
|
4118 |
return false;
|
4122 |
v.close();
|
4123 |
return false;
|
4124 |
}
|
4125 |
+
// Iterate through tags and populate layout
|
4126 |
if ( v.is_active() && this.has_tags() ) {
|
4127 |
var loading_promise = this.trigger('render-loading');
|
4128 |
var tpl = this;
|
4129 |
var tags = this.get_tags(),
|
4130 |
tag_promises = [];
|
4131 |
+
// Render Tag output
|
4132 |
+
$.when(item.load(), loading_promise).done(function() {
|
4133 |
if ( !v.is_active() ) {
|
4134 |
return false;
|
4135 |
}
|
4144 |
r.tag.dom_get().html(r.output);
|
4145 |
}));
|
4146 |
});
|
4147 |
+
// Fire event when all tags rendered
|
4148 |
if ( !v.is_active() ) {
|
4149 |
return false;
|
4150 |
}
|
4154 |
});
|
4155 |
}
|
4156 |
} else {
|
4157 |
+
// Get Layout (basic)
|
4158 |
this.trigger('render-init', this.dom_get());
|
4159 |
}
|
4160 |
},
|
4167 |
* @return string Layout (HTML)
|
4168 |
*/
|
4169 |
get_layout: function(parsed) {
|
4170 |
+
// Validate
|
4171 |
if ( !this.util.is_bool(parsed) ) {
|
4172 |
parsed = true;
|
4173 |
}
|
4174 |
+
// Determine which layout to retrieve (raw/parsed)
|
4175 |
var l = ( parsed ) ? this.parse_layout() : this.get_attribute('layout_raw', '');
|
4176 |
return l;
|
4177 |
},
|
4184 |
* @return string Parsed layout
|
4185 |
*/
|
4186 |
parse_layout: function() {
|
4187 |
+
// Check for previously-parsed layout
|
4188 |
var a = 'layout_parsed';
|
4189 |
var ret = this.get_attribute(a);
|
4190 |
+
// Return cached layout immediately
|
4191 |
if ( this.util.is_string(ret) ) {
|
4192 |
return ret;
|
4193 |
}
|
4194 |
+
// Parse raw layout
|
4195 |
ret = this.sanitize_layout( this.get_layout(false) );
|
4196 |
ret = this.parse_tags(ret);
|
4197 |
+
// Save parsed layout
|
4198 |
this.set_attribute(a, ret);
|
4199 |
|
4200 |
+
// Return parsed layout
|
4201 |
return ret;
|
4202 |
},
|
4203 |
|
4207 |
* @return obj|string Sanitized layout (Same data type that was passed to method)
|
4208 |
*/
|
4209 |
sanitize_layout: function(l) {
|
4210 |
+
// Stop processing if invalid value
|
4211 |
if ( this.util.is_empty(l) ) {
|
4212 |
return l;
|
4213 |
}
|
4214 |
+
// Set return type
|
4215 |
var rtype = ( this.util.is_string(l) ) ? 'string' : null;
|
4216 |
/* Quarantine hard-coded tags */
|
4217 |
|
4218 |
+
// Create DOM structure from raw template
|
4219 |
var dom = $(l);
|
4220 |
+
// Find hard-coded tag nodes
|
4221 |
+
var tag_temp = this.get_tag_temp();
|
4222 |
var cls = tag_temp.get_class();
|
4223 |
var cls_new = ['x', cls].join('_');
|
4224 |
+
$(tag_temp.get_selector(), dom).each(function() {
|
4225 |
+
// Replace matching class name with blocking class
|
4226 |
$(this).removeClass(cls).addClass(cls_new);
|
4227 |
});
|
4228 |
+
// Format return value
|
4229 |
switch ( rtype ) {
|
4230 |
case 'string' :
|
4231 |
dom = dom.wrap('<div />').parent().html();
|
4232 |
+
l = dom;
|
4233 |
+
break;
|
4234 |
default :
|
4235 |
l = dom;
|
4236 |
}
|
4247 |
* @return string Parsed layout
|
4248 |
*/
|
4249 |
parse_tags: function(l) {
|
4250 |
+
// Validate
|
4251 |
if ( !this.util.is_string(l) ) {
|
4252 |
return '';
|
4253 |
}
|
4254 |
+
// Parse tags in layout
|
4255 |
+
// Tag regex
|
4256 |
var re = /\{{2}\s*(\w.*?)\s*\}{2}/gim;
|
4257 |
+
// Tag match results
|
4258 |
var match;
|
4259 |
+
// Iterate through template and find tags
|
4260 |
while ( match = re.exec(l) ) {
|
4261 |
+
// Replace tag in layout with DOM container
|
4262 |
l = l.substring(0, match.index) + this.get_tag_container(match[1]) + l.substring(match.index + match[0].length);
|
4263 |
}
|
4264 |
return l;
|
4270 |
* @return string DOM element
|
4271 |
*/
|
4272 |
get_tag_container: function(tag) {
|
4273 |
+
// Build element
|
4274 |
var attr = this.get_tag_attribute();
|
4275 |
+
return this.util.format('<span %s="%s"></span>', attr, encodeURI(tag));
|
4276 |
},
|
4277 |
|
4278 |
get_tag_attribute: function() {
|
4279 |
+
return this.get_tag_temp().dom_get_attribute();
|
4280 |
},
|
4281 |
|
4282 |
/**
|
4302 |
* Template is parsed if tags not set
|
4303 |
* @param string name (optional) Tag type to retrieve instances of
|
4304 |
* @param string prop (optional) Tag property to retrieve instances of
|
4305 |
+
* @param bool isolate (optional) Do not save retrieved tags, only fetch and return (Default: TRUE)
|
4306 |
* @return array Template_Tag instances
|
4307 |
*/
|
4308 |
+
get_tags: function(name, prop, isolate) {
|
4309 |
+
// Validate
|
4310 |
+
if ( !this.util.is_bool(isolate) ) {
|
4311 |
+
isolate = false;
|
4312 |
+
}
|
4313 |
+
// Setup
|
4314 |
var a = 'tags';
|
4315 |
var tags = this.get_attribute(a);
|
4316 |
+
// Initialize tags
|
4317 |
if ( !this.util.is_array(tags) ) {
|
4318 |
tags = [];
|
4319 |
+
// Retrieve layout DOM tree
|
4320 |
var d = this.dom_get();
|
4321 |
+
// Select tag nodes
|
4322 |
var attr = this.get_tag_attribute();
|
4323 |
var nodes = $(d).find('[' + attr + ']');
|
4324 |
+
// Build tag instances from nodes
|
4325 |
+
$(nodes).each(function() {
|
4326 |
+
// Get tag placeholder
|
4327 |
var el = $(this);
|
4328 |
+
var tag = new View.Template_Tag(decodeURI(el.attr(attr)));
|
4329 |
+
// Populate valid tags
|
4330 |
if ( tag.has_handler() ) {
|
4331 |
+
// Add tag to array
|
4332 |
tags.push(tag);
|
4333 |
+
if ( !isolate ) {
|
4334 |
+
// Connect tag to DOM node
|
4335 |
+
tag.dom_set(el);
|
4336 |
+
// Set classes
|
4337 |
+
el.addClass(tag.get_classes(' '));
|
4338 |
+
}
|
4339 |
+
}
|
4340 |
+
// Clear data attribute
|
4341 |
+
if ( !isolate ) {
|
4342 |
+
el.removeAttr(attr);
|
4343 |
}
|
|
|
|
|
4344 |
});
|
4345 |
+
if ( !isolate ) {
|
4346 |
+
// Save tags
|
4347 |
+
this.set_attribute(a, tags, false);
|
4348 |
+
}
|
4349 |
}
|
4350 |
+
// Filter tags by parameters
|
|
|
4351 |
if ( !this.util.is_empty(tags) && this.util.is_string(name) ) {
|
4352 |
+
// Normalize
|
4353 |
if ( !this.util.is_string(prop) ) {
|
4354 |
prop = false;
|
4355 |
}
|
4357 |
var tc = null;
|
4358 |
for ( var x = 0; x < tags.length; x++ ) {
|
4359 |
tc = tags[x];
|
4360 |
+
if ( name === tc.get_name() ) {
|
4361 |
+
// Check tag property
|
4362 |
+
if ( !prop || prop === tc.get_prop() ) {
|
4363 |
tags_filtered.push(tc);
|
4364 |
}
|
4365 |
}
|
4377 |
return ( this.get_tags().length > 0 ) ? true : false;
|
4378 |
},
|
4379 |
|
4380 |
+
/**
|
4381 |
+
* Retrieve temporary tag instance
|
4382 |
+
* @return Template_Tag Temporary tag
|
4383 |
+
*/
|
4384 |
+
get_tag_temp: function() {
|
4385 |
+
return this.get_controller().get_component_temp(View.Template_Tag);
|
4386 |
+
},
|
4387 |
+
|
4388 |
+
/**
|
4389 |
+
* Retrieve Template tag CSS selector
|
4390 |
+
* @uses Template.get_tag_temp() to retrieve temporary tag instance
|
4391 |
+
* @uses Template_Tag.get_selector() to retrieve selector
|
4392 |
+
* @param name string Tag name
|
4393 |
+
* @param prop string Tag Property
|
4394 |
+
* @return string Template Tag CSS selector
|
4395 |
+
*/
|
4396 |
+
get_tag_selector: function(name, prop) {
|
4397 |
+
if ( !this.util.is_string(name) ) {
|
4398 |
+
name = '';
|
4399 |
+
}
|
4400 |
+
if ( !this.util.is_string(prop) ) {
|
4401 |
+
prop = '';
|
4402 |
+
}
|
4403 |
+
var tag = this.get_tag_temp();
|
4404 |
+
tag.set_attribute('name', name);
|
4405 |
+
tag.set_attribute('prop', prop);
|
4406 |
+
return tag.get_selector('full');
|
4407 |
+
},
|
4408 |
+
|
4409 |
/*-** DOM **-*/
|
4410 |
|
4411 |
/**
|
4412 |
* Custom DOM initialization
|
4413 |
*/
|
4414 |
dom_init: function() {
|
4415 |
+
// Create DOM object from parsed layout
|
4416 |
this.dom_set(this.get_layout());
|
4417 |
+
this.trigger('dom_init');
|
4418 |
},
|
4419 |
|
4420 |
/**
|
4427 |
var ret = $();
|
4428 |
var tags = this.get_tags(tag, prop);
|
4429 |
if ( tags.length ) {
|
4430 |
+
// Build selector
|
4431 |
var level = null;
|
4432 |
if ( this.util.is_string(tag) ) {
|
4433 |
level = ( this.util.is_string(prop) ) ? 'full' : 'tag';
|
4475 |
* @param string tag_match Extracted tag match
|
4476 |
*/
|
4477 |
parse: function(tag_match) {
|
4478 |
+
// Return default value for invalid instances
|
4479 |
if ( !this.util.is_string(tag_match) ) {
|
4480 |
return false;
|
4481 |
}
|
4482 |
+
// Parse instance options
|
4483 |
var parts = tag_match.split('|'),
|
4484 |
part;
|
4485 |
if ( !parts.length ) {
|
4490 |
prop: null,
|
4491 |
match: tag_match
|
4492 |
};
|
4493 |
+
// Get tag ID
|
4494 |
attrs.name = parts[0];
|
4495 |
+
// Get main property
|
4496 |
+
if ( attrs.name.indexOf('.') !== -1 ) {
|
4497 |
attrs.name = attrs.name.split('.', 2);
|
4498 |
attrs.prop = attrs.name[1];
|
4499 |
attrs.name = attrs.name[0];
|
4500 |
}
|
4501 |
+
// Get other attributes
|
4502 |
for ( var x = 1; x < parts.length; x++ ) {
|
4503 |
part = parts[x].split(':', 1);
|
4504 |
if ( part.length > 1 && !( part[0] in attrs ) ) {
|
4505 |
+
// Add key/value pair to attributes
|
4506 |
attrs[part[0]] = part[1];
|
4507 |
}
|
4508 |
}
|
4509 |
+
// Save to instance
|
4510 |
this.set_attributes(attrs, true);
|
4511 |
},
|
4512 |
|
4515 |
* @param Content_Item item
|
4516 |
* @return obj jQuery.Promise object that is resolved when tag is rendered
|
4517 |
* Parameters passed to callbacks
|
4518 |
+
* > tag obj Current tag instance
|
4519 |
* > output string Tag output
|
4520 |
*/
|
4521 |
render: function(item) {
|
4566 |
* @return array Class names
|
4567 |
*/
|
4568 |
get_classes: function(rtype) {
|
4569 |
+
// Build array of class names
|
4570 |
var cls = [
|
4571 |
+
// General tag class
|
4572 |
this.get_class(),
|
4573 |
+
// Tag name
|
4574 |
this.get_class('tag'),
|
4575 |
+
// Tag name + property
|
4576 |
this.get_class('full')
|
4577 |
];
|
4578 |
+
// Convert class names array to string
|
4579 |
if ( this.util.is_string(rtype) ) {
|
4580 |
cls = cls.join(rtype);
|
4581 |
}
|
4582 |
+
// Return class names
|
4583 |
return cls;
|
4584 |
},
|
4585 |
|
4593 |
*/
|
4594 |
get_class: function(level) {
|
4595 |
var cls = '';
|
4596 |
+
// Build base
|
4597 |
switch ( level ) {
|
4598 |
case 'tag' :
|
4599 |
+
// Tag name
|
4600 |
+
cls = this.get_name();
|
4601 |
break;
|
4602 |
case 'full' :
|
4603 |
+
// Tag name + property
|
4604 |
+
var parts = [this.get_name(), this.get_prop()];
|
4605 |
+
var a = [];
|
4606 |
+
var i;
|
4607 |
+
for ( i = 0; i < parts.length; i++ ) {
|
4608 |
+
if ( this.util.is_string(parts[i]) ) {
|
4609 |
+
a.push(parts[i]);
|
4610 |
+
}
|
4611 |
+
}
|
4612 |
+
cls = a.join('_');
|
4613 |
break;
|
4614 |
}
|
4615 |
+
// Format & return
|
4616 |
+
return ( !this.util.is_string(cls) ) ? this.get_ns() : this.add_ns(cls);
|
4617 |
},
|
4618 |
|
4619 |
/**
|
4622 |
* @return string Tag selector
|
4623 |
*/
|
4624 |
get_selector: function(level) {
|
4625 |
+
// Get base
|
4626 |
+
var ret = this.get_class(level);
|
4627 |
+
// Format
|
4628 |
+
if ( this.util.is_string(ret) ) {
|
4629 |
+
ret = '.' + ret;
|
4630 |
+
} else {
|
4631 |
+
ret = '';
|
4632 |
+
}
|
4633 |
+
return ret;
|
4634 |
}
|
4635 |
};
|
4636 |
|
4659 |
*/
|
4660 |
render: function(item, instance) {
|
4661 |
var dfr = $.Deferred();
|
4662 |
+
// Pass to attribute method
|
4663 |
+
this.call_attribute('render', item, instance, dfr);
|
4664 |
+
// Return promise
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4665 |
return dfr.promise();
|
4666 |
},
|
4667 |
|
4668 |
add_prop: function(prop, fn) {
|
4669 |
+
// Get attribute
|
4670 |
var a = 'props';
|
4671 |
var props = this.get_attribute(a);
|
4672 |
+
// Validate
|
4673 |
if ( !this.util.is_string(prop) || !this.util.is_func(fn) ) {
|
4674 |
return false;
|
4675 |
}
|
4676 |
if ( !this.util.is_obj(props, false) ) {
|
4677 |
props = {};
|
4678 |
}
|
4679 |
+
// Add property
|
4680 |
props[prop] = fn;
|
4681 |
+
// Save attribute
|
4682 |
this.set_attribute(a, props);
|
4683 |
},
|
4684 |
|
4685 |
handle_prop: function(prop, item, instance) {
|
4686 |
+
// Locate property
|
4687 |
var props = this.get_attribute('props');
|
4688 |
var out = '';
|
4689 |
if ( this.util.is_obj(props) && ( prop in props ) && this.util.is_func(props[prop]) ) {
|
4698 |
View.Template_Tag_Handler = Component.extend(Template_Tag_Handler);
|
4699 |
/* Update References */
|
4700 |
|
4701 |
+
// Attach to global object
|
4702 |
+
View = SLB.attach('View', View);
|
4703 |
+
})(jQuery);}
|
|
|
|
client/js/lib.core.js
DELETED
@@ -1,591 +0,0 @@
|
|
1 |
-
/**
|
2 |
-
* Core
|
3 |
-
* @package SLB
|
4 |
-
* @author Archetyped
|
5 |
-
*/
|
6 |
-
|
7 |
-
(function($) {
|
8 |
-
|
9 |
-
/**
|
10 |
-
* Extendible class
|
11 |
-
* Adapted from John Resig
|
12 |
-
* @link http://ejohn.org/blog/simple-javascript-inheritance/
|
13 |
-
*/
|
14 |
-
var c_init = false;
|
15 |
-
var Class = function() {};
|
16 |
-
|
17 |
-
Class.extend = function(members) {
|
18 |
-
var _super = this.prototype;
|
19 |
-
|
20 |
-
//Copy instance to prototype
|
21 |
-
c_init = true;
|
22 |
-
var proto = new this();
|
23 |
-
c_init = false;
|
24 |
-
|
25 |
-
var val;
|
26 |
-
//Scrub prototype objects (Decouple from super class)
|
27 |
-
for ( var name in proto ) {
|
28 |
-
if ( $.isPlainObject(proto[name]) ) {
|
29 |
-
val = $.extend({}, proto[name]);
|
30 |
-
proto[name] = val;
|
31 |
-
}
|
32 |
-
}
|
33 |
-
|
34 |
-
//Copy members
|
35 |
-
for ( var name in members ) {
|
36 |
-
//Evaluate function members (if overwriting super class method)
|
37 |
-
if ( 'function' == typeof members[name] && 'function' == typeof _super[name] ) {
|
38 |
-
proto[name] = (function(name, fn) {
|
39 |
-
return function() {
|
40 |
-
//Cache super variable
|
41 |
-
var tmp = this._super;
|
42 |
-
//Set variable to super class method
|
43 |
-
this._super = _super[name];
|
44 |
-
//Call method
|
45 |
-
var ret = fn.apply(this, arguments);
|
46 |
-
//Restore super variable
|
47 |
-
this._super = tmp;
|
48 |
-
//Return value
|
49 |
-
return ret;
|
50 |
-
}
|
51 |
-
})(name, members[name]);
|
52 |
-
} else {
|
53 |
-
val = members[name];
|
54 |
-
if ( $.isPlainObject(members[name]) ) {
|
55 |
-
val = $.extend({}, members[name]);
|
56 |
-
}
|
57 |
-
proto[name] = val;
|
58 |
-
}
|
59 |
-
}
|
60 |
-
|
61 |
-
//Constructor
|
62 |
-
function Class() {
|
63 |
-
if ( !c_init ) {
|
64 |
-
//Private init
|
65 |
-
if ( this._init ) {
|
66 |
-
this._init.apply(this, arguments);
|
67 |
-
}
|
68 |
-
//Main Constructor
|
69 |
-
if ( this._c ) {
|
70 |
-
this._c.apply(this, arguments);
|
71 |
-
}
|
72 |
-
}
|
73 |
-
}
|
74 |
-
|
75 |
-
|
76 |
-
//Populate new prototype
|
77 |
-
Class.prototype = proto;
|
78 |
-
|
79 |
-
//Set constructor
|
80 |
-
Class.prototype.constructor = Class;
|
81 |
-
|
82 |
-
Class.extend = arguments.callee;
|
83 |
-
|
84 |
-
//Return function
|
85 |
-
return Class;
|
86 |
-
};
|
87 |
-
|
88 |
-
/* Base */
|
89 |
-
var Base = {
|
90 |
-
/* Properties */
|
91 |
-
|
92 |
-
base: false,
|
93 |
-
_parent: null,
|
94 |
-
prefix: 'slb',
|
95 |
-
|
96 |
-
/* Methods */
|
97 |
-
|
98 |
-
/**
|
99 |
-
* Constructor
|
100 |
-
*/
|
101 |
-
_init: function() {
|
102 |
-
this._set_parent();
|
103 |
-
},
|
104 |
-
|
105 |
-
_set_parent: function(p) {
|
106 |
-
if ( typeof p != 'undefined' )
|
107 |
-
this._parent = p;
|
108 |
-
this.util._parent = this;
|
109 |
-
},
|
110 |
-
|
111 |
-
/**
|
112 |
-
* Attach member to object
|
113 |
-
* @param string name Member name
|
114 |
-
* @param mixed Member data
|
115 |
-
* > obj: Member inherits from base object
|
116 |
-
* > other: Simple data object
|
117 |
-
*/
|
118 |
-
attach: function(member, data, simple) {
|
119 |
-
simple = ( typeof simple == undefined ) ? false : !!simple;
|
120 |
-
if ( $.type(member) == 'string' && $.isPlainObject(data) ) {
|
121 |
-
//Add initial member
|
122 |
-
var obj = {};
|
123 |
-
if ( simple ) {
|
124 |
-
//Simple object
|
125 |
-
obj[member] = $.extend({}, data);
|
126 |
-
$.extend(this, obj);
|
127 |
-
} else {
|
128 |
-
//Add new instance object
|
129 |
-
data['_parent'] = this;
|
130 |
-
var c = this.Class.extend(data);
|
131 |
-
this[member] = new c();
|
132 |
-
}
|
133 |
-
}
|
134 |
-
},
|
135 |
-
|
136 |
-
/**
|
137 |
-
* Get parent object
|
138 |
-
* @return obj Parent object
|
139 |
-
*/
|
140 |
-
get_parent: function() {
|
141 |
-
return this._parent;
|
142 |
-
},
|
143 |
-
|
144 |
-
/**
|
145 |
-
* Utility methods
|
146 |
-
*/
|
147 |
-
util: {
|
148 |
-
/* Properties */
|
149 |
-
|
150 |
-
_base: null,
|
151 |
-
_parent: null,
|
152 |
-
|
153 |
-
/* Constants */
|
154 |
-
|
155 |
-
string: 'string',
|
156 |
-
bool: 'boolean',
|
157 |
-
array: 'array',
|
158 |
-
obj: 'object',
|
159 |
-
func: 'function',
|
160 |
-
num: 'number',
|
161 |
-
|
162 |
-
/* Methods */
|
163 |
-
|
164 |
-
get_base: function() {
|
165 |
-
if ( !this._base ) {
|
166 |
-
var p = this.get_parent();
|
167 |
-
var p_last = null;
|
168 |
-
//Iterate through parents
|
169 |
-
while ( !p.base && p_last != p && p._parent ) {
|
170 |
-
p_last = p;
|
171 |
-
p = p._parent;
|
172 |
-
}
|
173 |
-
//Set base
|
174 |
-
this._base = p;
|
175 |
-
}
|
176 |
-
return this._base;
|
177 |
-
},
|
178 |
-
|
179 |
-
get_parent: function() {
|
180 |
-
return this._parent;
|
181 |
-
},
|
182 |
-
|
183 |
-
/**
|
184 |
-
* Retrieve valid separator
|
185 |
-
* If supplied argument is not a valid separator, use default separator
|
186 |
-
* @param string (optional) sep Separator text
|
187 |
-
* @return string Separator text
|
188 |
-
*/
|
189 |
-
get_sep: function(sep) {
|
190 |
-
return ( this.is_string(sep, false) ) ? sep : '_';
|
191 |
-
},
|
192 |
-
|
193 |
-
/**
|
194 |
-
* Retrieve prefix
|
195 |
-
* @return string Prefix
|
196 |
-
*/
|
197 |
-
get_prefix: function() {
|
198 |
-
return ( this.is_string(this.get_parent().prefix) ) ? this.get_parent().prefix : '';
|
199 |
-
},
|
200 |
-
|
201 |
-
/**
|
202 |
-
* Check if string is prefixed
|
203 |
-
*/
|
204 |
-
has_prefix: function(val, sep) {
|
205 |
-
return ( this.is_string(val) && val.indexOf(this.get_prefix() + this.get_sep(sep)) === 0 );
|
206 |
-
},
|
207 |
-
|
208 |
-
/**
|
209 |
-
* Add Prefix to a string
|
210 |
-
* @param string val Value to add prefix to
|
211 |
-
* @param string sep (optional) Separator (Default: `_`)
|
212 |
-
* @param bool (optional) once If text should only be prefixed once (Default: TRUE)
|
213 |
-
*/
|
214 |
-
add_prefix: function(val, sep, once) {
|
215 |
-
//Validate
|
216 |
-
if ( !this.is_string(val) ) {
|
217 |
-
//Return prefix if value to add prefix to is empty
|
218 |
-
return this.get_prefix();
|
219 |
-
}
|
220 |
-
sep = this.get_sep(sep);
|
221 |
-
if ( !this.is_bool(once) ) {
|
222 |
-
once = true;
|
223 |
-
}
|
224 |
-
|
225 |
-
return ( once && this.has_prefix(val, sep) ) ? val : [this.get_prefix(), val].join(sep);
|
226 |
-
},
|
227 |
-
|
228 |
-
/**
|
229 |
-
* Remove Prefix from a string
|
230 |
-
* @param string val Value to add prefix to
|
231 |
-
* @param string sep (optional) Separator (Default: `_`)
|
232 |
-
* @param bool (optional) once If text should only be prefixed once (Default: true)
|
233 |
-
*/
|
234 |
-
remove_prefix: function(val, sep, once) {
|
235 |
-
//Validate parameters
|
236 |
-
if ( !this.is_string(val, true) ) {
|
237 |
-
return val;
|
238 |
-
}
|
239 |
-
//Default values
|
240 |
-
sep = this.get_sep(sep);
|
241 |
-
if ( !this.is_bool(once) ) {
|
242 |
-
once = true;
|
243 |
-
}
|
244 |
-
//Check if string is prefixed
|
245 |
-
if ( this.has_prefix(val, sep) ) {
|
246 |
-
//Remove prefix
|
247 |
-
var prfx = this.get_prefix() + sep;
|
248 |
-
do {
|
249 |
-
val = val.substr(prfx.length);
|
250 |
-
} while ( !once && this.has_prefix(val, sep) );
|
251 |
-
}
|
252 |
-
return val;
|
253 |
-
},
|
254 |
-
|
255 |
-
/*
|
256 |
-
* Get attribute name
|
257 |
-
* @param string val Attribute's base name
|
258 |
-
*/
|
259 |
-
get_attribute: function(val) {
|
260 |
-
//Setup
|
261 |
-
var sep = '-';
|
262 |
-
var top = 'data';
|
263 |
-
//Validate
|
264 |
-
var pre = [top, this.get_prefix()].join(sep);
|
265 |
-
if ( !this.is_string(val, false) ) {
|
266 |
-
return pre;
|
267 |
-
}
|
268 |
-
//Process
|
269 |
-
if ( val.indexOf(pre + sep) == -1 ) {
|
270 |
-
val = [pre, val].join(sep);
|
271 |
-
}
|
272 |
-
return val;
|
273 |
-
},
|
274 |
-
|
275 |
-
/* Request */
|
276 |
-
|
277 |
-
/**
|
278 |
-
* Retrieve valid context
|
279 |
-
* @return array Context
|
280 |
-
*/
|
281 |
-
get_context: function() {
|
282 |
-
//Valid context
|
283 |
-
var b = this.get_base();
|
284 |
-
if ( !$.isArray(b.context) )
|
285 |
-
b.context = [];
|
286 |
-
//Return context
|
287 |
-
return b.context;
|
288 |
-
},
|
289 |
-
|
290 |
-
/**
|
291 |
-
* Check if a context exists in current request
|
292 |
-
* If multiple contexts are supplied, result will be TRUE if at least ONE context exists
|
293 |
-
*
|
294 |
-
* @param string|array ctx Context to check for
|
295 |
-
* @return bool TRUE if context exists, FALSE otherwise
|
296 |
-
*/
|
297 |
-
is_context: function(ctx) {
|
298 |
-
var ret = false;
|
299 |
-
//Validate context
|
300 |
-
if ( typeof ctx == 'string' )
|
301 |
-
ctx = [ctx];
|
302 |
-
if ( $.isArray(ctx) && this.arr_intersect(this.get_context(), ctx).length ) {
|
303 |
-
ret = true;
|
304 |
-
}
|
305 |
-
return ret;
|
306 |
-
},
|
307 |
-
|
308 |
-
/* Helpers */
|
309 |
-
|
310 |
-
is_set: function(value) {
|
311 |
-
return ( $.type(value) != 'undefined' ) ? true : false;
|
312 |
-
},
|
313 |
-
|
314 |
-
is_type: function(value, type, nonempty) {
|
315 |
-
var ret = false;
|
316 |
-
if ( this.is_set(value) && null != value && this.is_set(type) ) {
|
317 |
-
switch ( $.type(type) ) {
|
318 |
-
case this.func:
|
319 |
-
ret = ( value instanceof type ) ? true : false;
|
320 |
-
break;
|
321 |
-
case this.string:
|
322 |
-
ret = ( $.type(value) == type ) ? true : false;
|
323 |
-
break;
|
324 |
-
default:
|
325 |
-
ret = false;
|
326 |
-
break;
|
327 |
-
}
|
328 |
-
}
|
329 |
-
|
330 |
-
//Validate empty values
|
331 |
-
if ( ret && ( $.type(nonempty) != this.bool || nonempty ) ) {
|
332 |
-
ret = !this.is_empty(value);
|
333 |
-
}
|
334 |
-
return ret;
|
335 |
-
},
|
336 |
-
|
337 |
-
is_string: function(value, nonempty) {
|
338 |
-
return this.is_type(value, this.string, nonempty);
|
339 |
-
},
|
340 |
-
|
341 |
-
is_array: function(value, nonempty) {
|
342 |
-
return ( this.is_type(value, this.array, nonempty) );
|
343 |
-
},
|
344 |
-
|
345 |
-
is_bool: function(value) {
|
346 |
-
return this.is_type(value, this.bool, false);
|
347 |
-
},
|
348 |
-
|
349 |
-
is_obj: function(value, nonempty) {
|
350 |
-
return this.is_type(value, this.obj, nonempty);
|
351 |
-
},
|
352 |
-
|
353 |
-
is_func: function(value) {
|
354 |
-
return this.is_type(value, this.func, false);
|
355 |
-
},
|
356 |
-
|
357 |
-
/**
|
358 |
-
* Checks if an object has a method
|
359 |
-
* @param obj Object to check
|
360 |
-
* @param string|array Names of methods to check for
|
361 |
-
* @return bool TRUE if method(s) exist, FALSE otherwise
|
362 |
-
*/
|
363 |
-
is_method: function(obj, value) {
|
364 |
-
var ret = false;
|
365 |
-
if ( this.is_string(value) ) {
|
366 |
-
value = [value];
|
367 |
-
}
|
368 |
-
if ( this.in_obj(obj, value) ) {
|
369 |
-
var t = this;
|
370 |
-
$.each(value, function(idx, val) {
|
371 |
-
ret = ( t.is_func(obj[val]) ) ? true : false;
|
372 |
-
return ret;
|
373 |
-
});
|
374 |
-
}
|
375 |
-
return ret;
|
376 |
-
},
|
377 |
-
|
378 |
-
is_num: function(value, nonempty) {
|
379 |
-
return ( this.is_type(value, this.num, nonempty) && !isNaN(value) );
|
380 |
-
},
|
381 |
-
|
382 |
-
is_int: function(value, nonempty) {
|
383 |
-
return ( this.is_num(value, nonempty) && Math.floor(value) === value );
|
384 |
-
},
|
385 |
-
|
386 |
-
is_scalar: function(value, nonempty) {
|
387 |
-
return ( this.is_num(value, nonempty) || this.is_string(value, nonempty) || this.is_bool(value, nonempty) );
|
388 |
-
},
|
389 |
-
|
390 |
-
/**
|
391 |
-
* Checks if value is empty
|
392 |
-
* @param mixed value Value to check
|
393 |
-
* @param string type (optional) Data type
|
394 |
-
* @return bool TRUE if value is empty, FALSE if not empty
|
395 |
-
*/
|
396 |
-
is_empty: function(value, type) {
|
397 |
-
var ret = false;
|
398 |
-
//Initial check for empty value
|
399 |
-
if ( !this.is_set(value) || null === value || false === value ) {
|
400 |
-
ret = true;
|
401 |
-
} else {
|
402 |
-
//Validate type
|
403 |
-
if ( !this.is_set(type) ) {
|
404 |
-
type = $.type(value);
|
405 |
-
}
|
406 |
-
//Type-based check
|
407 |
-
if ( this.is_type(value, type, false) ) {
|
408 |
-
switch ( type ) {
|
409 |
-
case this.string:
|
410 |
-
case this.array:
|
411 |
-
if ( value.length == 0 ) {
|
412 |
-
ret = true;
|
413 |
-
}
|
414 |
-
break;
|
415 |
-
case this.obj:
|
416 |
-
//Only evaluate literal objects
|
417 |
-
ret = ( $.isPlainObject(value) && !$.map(value, function(v, key) { return key; }).length );
|
418 |
-
break;
|
419 |
-
case this.num:
|
420 |
-
ret = ( value === 0 );
|
421 |
-
break;
|
422 |
-
}
|
423 |
-
} else {
|
424 |
-
ret = true;
|
425 |
-
}
|
426 |
-
}
|
427 |
-
return ret;
|
428 |
-
},
|
429 |
-
|
430 |
-
/**
|
431 |
-
* Check if object is a jQuery.Promise instance
|
432 |
-
* Will also match (but not guarantee) jQuery.Deferred instances
|
433 |
-
* @return bool TRUE if object is Promise/Deferred, FALSE otherwise
|
434 |
-
*/
|
435 |
-
is_promise: function(obj) {
|
436 |
-
return ( this.is_obj(obj) && this.is_method(obj, ['then', 'done', 'always', 'fail', 'pipe']) )
|
437 |
-
},
|
438 |
-
|
439 |
-
/**
|
440 |
-
* Check if object is a jQuery.Deferred instance
|
441 |
-
*/
|
442 |
-
is_deferred: function(obj) {
|
443 |
-
return ( this.is_promise(obj) && this.is_method(obj, ['resolve', 'reject', 'promise']));
|
444 |
-
},
|
445 |
-
|
446 |
-
/**
|
447 |
-
* Validate specified value's data type and return default value if necessary
|
448 |
-
* Data type of default value is used to determine data type
|
449 |
-
* @param mixed val Value to check
|
450 |
-
* @param mixed def Default value
|
451 |
-
* @return mixed Valid value
|
452 |
-
*/
|
453 |
-
validate: function(val, def) {
|
454 |
-
return ( this.is_type(val, def, true) ) ? val : def;
|
455 |
-
},
|
456 |
-
|
457 |
-
/**
|
458 |
-
* Return formatted string
|
459 |
-
*/
|
460 |
-
format: function(fmt, val) {
|
461 |
-
if ( !this.is_string(fmt) ) {
|
462 |
-
return '';
|
463 |
-
}
|
464 |
-
var params = [],
|
465 |
-
ph = '%s';
|
466 |
-
//Stop processing if no replacement values specified or format string contains no placeholders
|
467 |
-
if ( arguments.length < 2 || fmt.indexOf(ph) == -1 ) {
|
468 |
-
return fmt;
|
469 |
-
}
|
470 |
-
//Get replacement values
|
471 |
-
params = Array.prototype.slice.call(arguments, 1);
|
472 |
-
|
473 |
-
//Replace placeholders in string with parameters
|
474 |
-
|
475 |
-
//Replace all placeholders at once if single parameter set
|
476 |
-
if ( params.length == 1 ) {
|
477 |
-
fmt = fmt.replace(ph, params[0].toString());
|
478 |
-
} else {
|
479 |
-
var idx = 0,
|
480 |
-
len = params.length,
|
481 |
-
pos = 0;
|
482 |
-
while ( ( pos = fmt.indexOf(ph) ) && idx < len ) {
|
483 |
-
fmt = fmt.substr(0, pos) + params[idx].toString() + fmt.substr(pos + ph.length);
|
484 |
-
idx++;
|
485 |
-
}
|
486 |
-
//Remove any remaining placeholders
|
487 |
-
fmt = fmt.replace(ph, '');
|
488 |
-
}
|
489 |
-
return fmt;
|
490 |
-
},
|
491 |
-
|
492 |
-
/**
|
493 |
-
* Checks if key(s) exist in an object
|
494 |
-
* @param object obj Object to check
|
495 |
-
* @param string|array key Key(s) to check for in object
|
496 |
-
* @return bool TRUE if key(s) exist in object, FALSE otherwise
|
497 |
-
*/
|
498 |
-
in_obj: function(obj, key, all) {
|
499 |
-
//Validate
|
500 |
-
if ( !this.is_bool(all) ) {
|
501 |
-
all = true;
|
502 |
-
}
|
503 |
-
if ( this.is_string(key) ) {
|
504 |
-
key = [key];
|
505 |
-
}
|
506 |
-
var ret = false;
|
507 |
-
if ( this.is_obj(obj) && this.is_array(key) ) {
|
508 |
-
var val;
|
509 |
-
for ( var x = 0; x < key.length; x++ ) {
|
510 |
-
val = key[x];
|
511 |
-
ret = ( this.is_string(val) && ( val in obj ) ) ? true : false;
|
512 |
-
//Stop processing if conditions have been met
|
513 |
-
if ( ( !all && ret ) || ( all && !ret ) ) {
|
514 |
-
break;
|
515 |
-
}
|
516 |
-
}
|
517 |
-
}
|
518 |
-
return ret;
|
519 |
-
},
|
520 |
-
|
521 |
-
/**
|
522 |
-
* Find common elements of 2 arrays
|
523 |
-
* @param array arr1 First array
|
524 |
-
* @param array arr2 Second array
|
525 |
-
* @return array Elements common to both arrays
|
526 |
-
*/
|
527 |
-
arr_intersect: function(arr1, arr2) {
|
528 |
-
var ret = [];
|
529 |
-
if ( arr1 == arr2 ) {
|
530 |
-
return arr2;
|
531 |
-
}
|
532 |
-
if ( !$.isArray(arr2) || !arr2.length || !arr1.length ) {
|
533 |
-
return ret;
|
534 |
-
}
|
535 |
-
//Compare elements in arrays
|
536 |
-
var a1;
|
537 |
-
var a2;
|
538 |
-
var val;
|
539 |
-
if ( arr1.length < arr2.length ) {
|
540 |
-
a1 = arr1;
|
541 |
-
a2 = arr2;
|
542 |
-
} else {
|
543 |
-
a1 = arr2;
|
544 |
-
a2 = arr1;
|
545 |
-
}
|
546 |
-
|
547 |
-
for ( var x = 0; x < a1.length; x++ ) {
|
548 |
-
//Add mutual elements into intersection array
|
549 |
-
val = a1[x];
|
550 |
-
if ( a2.indexOf(val) != -1 && ret.indexOf(val) == -1 )
|
551 |
-
ret.push(val);
|
552 |
-
}
|
553 |
-
|
554 |
-
//Return intersection results
|
555 |
-
return ret;
|
556 |
-
}
|
557 |
-
}
|
558 |
-
};
|
559 |
-
var SLB_Base = Class.extend(Base);
|
560 |
-
|
561 |
-
//Init global object
|
562 |
-
var Core = {
|
563 |
-
/* Properties */
|
564 |
-
|
565 |
-
base: true,
|
566 |
-
context: [],
|
567 |
-
|
568 |
-
/**
|
569 |
-
* New object initializer
|
570 |
-
* @var obj
|
571 |
-
*/
|
572 |
-
Class: SLB_Base,
|
573 |
-
|
574 |
-
/* Methods */
|
575 |
-
|
576 |
-
/**
|
577 |
-
* Setup client
|
578 |
-
* Set variables, DOM, etc.
|
579 |
-
*/
|
580 |
-
setup_client: function() {
|
581 |
-
/* Quick Hide */
|
582 |
-
$('html').addClass(this.util.get_prefix());
|
583 |
-
}
|
584 |
-
};
|
585 |
-
var SLB_Core = SLB_Base.extend(Core);
|
586 |
-
|
587 |
-
this.SLB = new SLB_Core();
|
588 |
-
|
589 |
-
SLB.setup_client();
|
590 |
-
|
591 |
-
})(jQuery);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
client/js/prod/lib.admin.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
window.SLB&&SLB.attach&&!function($){SLB.attach("Admin",{init:function(){postboxes&&postboxes.add_postbox_toggles(pagenow)}}),$(document).ready(function(){SLB.Admin.init()})}(jQuery);
|
client/js/prod/lib.core.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
window.jQuery&&!function($){"use strict";var c_init=!1,Class=function(){};Class.extend=function(members){function Class(){c_init||("function"==typeof this._init&&this._init.apply(this,arguments),"function"==typeof this._c&&this._c.apply(this,arguments))}var _super=this.prototype;c_init=!0;var proto=new this;c_init=!1;var val,name;for(name in proto)$.isPlainObject(proto[name])&&(val=$.extend({},proto[name]),proto[name]=val);var make_handler=function(nm,fn){return function(){var tmp=this._super;this._super=_super[nm];var ret=fn.apply(this,arguments);return this._super=tmp,ret}};for(name in members)"function"==typeof members[name]&&"function"==typeof _super[name]?proto[name]=make_handler(name,members[name]):proto[name]=$.isPlainObject(members[name])?$.extend({},members[name]):members[name];return Class.prototype=proto,Class.prototype.constructor=Class,Class.extend=this.extend,Class};var Base={base:!1,_parent:null,prefix:"slb",_init:function(){this._set_parent()},_set_parent:function(p){this.util.is_set(p)&&(this._parent=p),this.util._parent=this},attach:function(member,data,simple){var ret=data;return simple="undefined"!=typeof simple&&!!simple,"string"===$.type(member)&&($.isPlainObject(data)&&!simple&&(data._parent=this,data=this.Class.extend(data)),this[member]="function"===$.type(data)?new data:data,ret=this[member]),ret},has_child:function(child){if(!this.util.is_string(child))return!1;var children=child.split(".");child=null;var x,o=this;for(x=0;x<children.length;x++)if(child=children[x],""!==child){if(!this.util.is_obj(o)||!o[child])return!1;o=o[child]}return!0},is_base:function(){return!!this.base},get_parent:function(){var p=this._parent;return p||(this._parent={}),this._parent}},Utilities={_base:null,_parent:null,get_base:function(){if(!this._base){for(var p=this.get_parent(),p_prev=null,methods=["is_base","get_parent"];p_prev!==p&&this.is_method(p,methods)&&!p.is_base();)p_prev=p,p=p.get_parent();this._base=p}return this._base},get_parent:function(prop){var ret=this._parent;return ret||(ret=this._parent={}),this.is_string(prop)&&(ret=this.in_obj(ret,prop)?ret[prop]:null),ret},get_sep:function(sep){var sep_default="_";return this.is_string(sep,!1)?sep:sep_default},get_prefix:function(){var p=this.get_parent("prefix");return this.is_string(p,!1)?p:""},has_prefix:function(val,sep){return this.is_string(val)&&0===val.indexOf(this.get_prefix()+this.get_sep(sep))},add_prefix:function(val,sep,once){return this.is_string(val)?(sep=this.get_sep(sep),this.is_bool(once)||(once=!0),once&&this.has_prefix(val,sep)?val:[this.get_prefix(),val].join(sep)):this.get_prefix()},remove_prefix:function(val,sep,once){if(!this.is_string(val,!0))return"";if(sep=this.get_sep(sep),this.is_bool(once)||(once=!0),this.has_prefix(val,sep)){var prfx=this.get_prefix()+sep;do val=val.substr(prfx.length);while(!once&&this.has_prefix(val,sep))}return val},get_attribute:function(attr_base){var sep="-",top="data",attr=[top,this.get_prefix()].join(sep);return this.is_string(attr_base)&&0!==attr_base.indexOf(attr+sep)&&(attr=[attr,attr_base].join(sep)),attr},get_context:function(){var b=this.get_base();return $.isArray(b.context)||(b.context=[]),b.context},is_context:function(ctx){return this.is_string(ctx)&&(ctx=[ctx]),this.is_array(ctx)&&this.arr_intersect(this.get_context(),ctx).length>0},is_set:function(val){return"undefined"!=typeof val},is_type:function(val,type,nonempty){var ret=!1;if(this.is_set(val)&&null!==val&&this.is_set(type))switch($.type(type)){case"function":ret=val instanceof type;break;case"string":ret=$.type(val)===type;break;default:ret=!1}return!ret||this.is_set(nonempty)&&!nonempty||(ret=!this.is_empty(val)),ret},is_string:function(value,nonempty){return this.is_type(value,"string",nonempty)},is_array:function(value,nonempty){return this.is_type(value,"array",nonempty)},is_bool:function(value){return this.is_type(value,"boolean",!1)},is_obj:function(value,nonempty){return this.is_type(value,"object",nonempty)},is_func:function(value){return this.is_type(value,"function",!1)},is_method:function(obj,key){var ret=!1;if(this.is_string(key)&&(key=[key]),this.in_obj(obj,key)){ret=!0;for(var x=0;ret&&x<key.length;)ret=this.is_func(obj[key[x]]),x++}return ret},is_instance:function(obj,parent){return!!this.is_func(parent)&&(this.is_obj(obj)&&obj instanceof parent)},is_class:function(cls,parent){var ret=this.is_func(cls)&&"prototype"in cls;return ret&&this.is_set(parent)&&(ret=this.is_instance(cls.prototype,parent)),ret},is_num:function(value,nonempty){var f={nan:Number.isNaN?Number.isNaN:isNaN,finite:Number.isFinite?Number.isFinite:isFinite};return this.is_type(value,"number",nonempty)&&!f.nan(value)&&f.finite(value)},is_int:function(value,nonempty){return this.is_num(value,nonempty)&&Math.floor(value)===value},is_scalar:function(value,nonempty){return this.is_num(value,nonempty)||this.is_string(value,nonempty)||this.is_bool(value)},is_empty:function(value,type){var ret=!1;if(this.is_set(value))for(var empties=[null,"",!1,0],x=0;!ret&&x<empties.length;)ret=empties[x]===value,x++;else ret=!0;if(!ret)if(this.is_set(type)||(type=$.type(value)),this.is_type(value,type,!1))switch(type){case"string":case"array":ret=0===value.length;break;case"number":ret=0==value;break;case"object":if($.isPlainObject(value)){if(Object.getOwnPropertyNames)ret=0===Object.getOwnPropertyNames(value).length;else if(value.hasOwnProperty){ret=!0;for(var key in value)if(value.hasOwnProperty(key)){ret=!1;break}}}else ret=!1}else ret=!0;return ret},is_promise:function(obj){return this.is_method(obj,["then","done","always","fail","pipe"])},format:function(fmt,val){if(!this.is_string(fmt))return"";var params=[],ph="%s",strip=function(txt){return txt.indexOf(ph)!==-1?txt.replace(ph,""):txt};if(arguments.length<2||fmt.indexOf(ph)===-1)return strip(fmt);params=Array.prototype.slice.call(arguments,1),val=null;for(var x=0;x<params.length;x++)this.is_scalar(params[x],!1)||(params[x]="");if(1===params.length)fmt=fmt.replace(ph,params[0].toString());else{for(var idx=0,len=params.length,rlen=ph.length,pos=0;(pos=fmt.indexOf(ph))&&pos!==-1&&idx<len;)fmt=fmt.substr(0,pos)+params[idx].toString()+fmt.substr(pos+rlen),idx++;fmt=strip(fmt)}return fmt},in_obj:function(obj,key,all){this.is_bool(all)||(all=!0),this.is_string(key)&&(key=[key]);var ret=!1;if(this.is_obj(obj)&&this.is_array(key))for(var val,x=0;x<key.length&&(val=key[x],ret=!!(this.is_string(val)&&val in obj),!(!all&&ret||all&&!ret));x++);return ret},obj_keys:function(obj){var keys=[];if(!this.is_obj(obj))return keys;if(Object.keys)keys=Object.keys(obj);else{var prop;for(prop in obj)obj.hasOwnProperty(prop)&&keys.push(prop)}return keys},arr_intersect:function(arr1,arr2){var x,ret=[],params=Array.prototype.slice.call(arguments),arrs=[];for(x=0;x<params.length;x++)this.is_array(params[x],!1)&&arrs.push(params[x]);if(arrs.length<2)return ret;params=arr1=arr2=null;var add,sub,base=arrs.shift();for(x=0;x<base.length;x++){for(add=!0,sub=0;sub<arrs.length;sub++)if(arrs[sub].indexOf(base[x])===-1){add=!1;break}add&&ret.push(base[x])}return ret},guid:function(){function _p8(s){var p=(Math.random().toString(16)+"000000000").substr(2,8);return s?"-"+p.substr(0,4)+"-"+p.substr(4,4):p}return _p8()+_p8(!0)+_p8(!0)+_p8()},parse_uri:function(uri){return $('<a href="'+uri+'"/>').get(0)},parse_query:function(uri){var delim={vars:"&",val:"="},query={raw:[],parsed:{},string:""};if(uri=this.parse_uri(uri),0===uri.search.indexOf("?")){query.raw=uri.search.substr(1).split(delim.vars);var i,temp,key,val;for(i=0;i<query.raw.length;i++)temp=query.raw[i].split(delim.val),key=temp.shift(),val=temp.length>0?temp.join(delim.val):null,query.parsed[key]=val}return query.parsed},build_query:function(query){var val,q=[],delim={vars:"&",val:"="};for(var key in query)val=null!==query[key]?delim.val+query[key]:"",q.push(key+val);return q.join(delim.vars)}};Base.attach("util",Utilities,!0);var SLB_Base=Class.extend(Base),Core={base:!0,context:[],Class:SLB_Base,_init:function(){this._super(),$("html").addClass(this.util.get_prefix())}},SLB_Core=SLB_Base.extend(Core);window.SLB=new SLB_Core}(jQuery);
|
client/js/prod/lib.view.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
window.SLB&&SLB.attach&&function($){var View={assets:{},component_defaults:[],loading:[],cache:{},component_temps:{},options:{},_init:function(){this._super(),this.init_refs(),this.init_components()},init_refs:function(){var r,ref,prop;for(prop in this)if(prop=this[prop],this.is_component(prop)&&!this.util.is_empty(prop.prototype._refs))for(r in prop.prototype._refs)ref=prop.prototype._refs[r],this.util.is_string(ref)&&ref in this&&(ref=prop.prototype._refs[r]=this[ref]),this.util.is_class(ref)||delete prop.prototype_refs[r]},init_components:function(){this.component_defaults=[this.Viewer]},init:function(options){var t=this;$.when.apply($,this.loading).always(function(){$.extend(!0,t.options,options),$(window).on("popstate",function(e){var state=e.originalEvent.state;if(t.util.in_obj(state,["item","viewer"]))return t.get_viewer(state.viewer).history_handle(e),e.preventDefault()}),t.init_items()})},can_make_default_component:function(type){return-1!==$.inArray(type,this.component_defaults)},is_component:function(comp){return this.util.is_class(comp,this.Component)},get_components:function(type){var ret={};if(this.is_component(type)){var coll=type.prototype._slug+"s";coll in this.cache||(this.cache[coll]={}),ret=this.cache[coll]}return ret},get_component:function(type,id){var ret=null;if(!this.util.is_func(type))return ret;this.util.is_string(id)||(id=null);var coll=this.get_components(type);if(this.util.is_obj(coll)){var tid=this.util.is_string(id)?id:this.util.add_prefix("default");tid in coll&&(ret=coll[tid])}return this.util.is_empty(ret)&&(this.util.is_string(id)||this.can_make_default_component(type))&&(ret=this.add_component(type,id)),ret},add_component:function(type,id,options){if(!this.util.is_func(type))return!1;if(this.util.is_empty(id)&&!this.can_make_default_component(type))return!1;var ret=null;this.util.is_empty(id)&&(id=this.util.add_prefix("default")),this.util.is_obj(options)||(options={});var m="component"!==type.prototype._slug?"add_"+type.prototype._slug:null;if(ret=!this.util.is_empty(m)&&m in this&&this.util.is_func(this[m])?this[m](id,options):new type(id,options),this.util.is_type(ret,type)){var coll=this.get_components(type);switch($.type(coll)){case"object":coll[id]=ret;break;case"array":coll.push(ret)}}else ret=null;return ret},add_component_temp:function(type){var ret=null;return this.is_component(type)&&(ret=new type(""),this.component_temps[ret._slug]=ret),ret},get_component_temp:function(type){return this.has_component_temp(type)?this.component_temps[type.prototype._slug]:this.add_component_temp(type)},has_component_temp:function(type){return!!(this.is_component(type)&&type.prototype._slug in this.component_temps)},get_options:function(opts){var ret={};if(this.util.is_string(opts)&&(opts=[opts]),!this.util.is_array(opts))return ret;for(var x=0;x<opts.length;x++)opts[x]in this.options&&(ret[opts[x]]=this.options[opts[x]]);return ret},get_option:function(opt,def){var ret=this.get_options(opt);return ret=this.util.is_obj(ret)&&opt in ret?ret[opt]:this.util.is_set(def)?def:null},add_viewer:function(id,options){var v=new this.Viewer(id,options);return this.get_viewers()[v.get_id()]=v},get_viewers:function(){return this.get_components(this.Viewer)},has_viewer:function(v){return!!(this.util.is_string(v)&&v in this.get_viewers())},get_viewer:function(v){return this.has_viewer(v)||(v=this.util.add_prefix("default"),this.has_viewer(v)||(v=(v=this.add_viewer(v)).get_id())),this.get_viewers()[v]},init_items:function(){var t=this,sel=this.util.format('a[href][%s="%s"]',this.util.get_attribute("active"),1);$(document).on("click",sel,null,function(){var ret=t.show_item(this);return t.util.is_bool(ret)||(ret=!0),!ret})},get_items:function(){return this.get_components(this.Content_Item)},get_item:function(ref){if(this.util.is_type(ref,this.Content_Item))return ref;var item=null;if(this.util.in_obj(ref,"nodeType")){var key=this.get_component_temp(this.Content_Item).get_data_key();item=$(ref).data(key)}else if(this.util.is_string(ref,!1)){var items=this.get_items();ref in items&&(item=items[ref])}return this.util.is_instance(item,this.Content_Item)||(item=this.add_item(ref)),item},add_item:function(el){return new this.Content_Item(el)},show_item:function(el){return this.get_item(el).show()},save_item:function(item){return this.util.is_instance(item,this.Content_Item)?this.get_items()[item.get_id()]=item:item},get_content_handlers:function(){return this.get_components(this.Content_Handler)},get_content_handler:function(item){var type=this.util.is_instance(item,this.Content_Item)?item.get_attribute("type",""):item.toString(),types=this.get_content_handlers();return type in types?types[type]:null},extend_content_handler:function(id,attr){var hdl=null;if(!this.util.is_string(id)||!this.util.is_obj(attr))return hdl;null===(hdl=this.get_content_handler(id))?this.get_content_handlers()[id]=hdl=new this.Content_Handler(id,attr):hdl.set_attributes(attr);return this.util.in_obj(attr,"styles")&&this.load_styles(attr.styles),hdl},add_group:function(g,attrs){return g=new this.Group(g,attrs),this.get_groups()[g.get_id()]=g},get_groups:function(){return this.get_components(this.Group)},get_group:function(g){return this.has_group(g)?this.get_groups()[g]:this.add_group(g)},has_group:function(g){return this.util.is_string(g)&&g in this.get_groups()},extend_theme:function(id,attr){if(!this.util.is_string(id))return!1;var dfr=$.Deferred();this.loading.push(dfr);var model=this.get_theme_model(id);return this.util.is_empty(model)&&(model=this.save_theme_model({parent:null,id:id})),this.util.is_obj(attr)&&("id"in attr&&delete attr.id,$.extend(model,attr)),this.util.in_obj(attr,"styles")&&this.load_styles(attr.styles),this.util.is_obj(model.parent)||(model.parent=this.get_theme_model(model.parent)),dfr.resolve(),model},get_theme_models:function(){return this.Theme.prototype._models},get_theme_model:function(id){var ms=this.get_theme_models();return this.util.in_obj(ms,id)?ms[id]:{}},save_theme_model:function(model){return this.util.in_obj(model,"id")&&this.util.is_string(model.id)&&(this.get_theme_models()[model.id]=model),model},extend_template_tag_handler:function(id,attr){if(!this.util.is_string(id)||!this.util.is_obj(attr))return!1;var hdl,hdls=this.get_template_tag_handlers();return this.util.in_obj(hdls,id)?(hdl=hdls[id]).set_attributes(attr):hdls[(hdl=new this.Template_Tag_Handler(id,attr)).get_id()]=hdl,this.util.in_obj(attr,"styles")&&this.load_styles(attr.styles),this.util.in_obj(attr,"_hooks")&&attr._hooks.call(hdl),hdl},get_template_tag_handlers:function(){return this.Template_Tag.prototype.handlers},get_template_tag_handler:function(id){var handlers=this.get_template_tag_handlers();return this.util.in_obj(handlers,id)?handlers[id]:null},load_styles:function(styles){if(this.util.is_array(styles)){for(var style,out=[],x=0;x<styles.length;x++)style=styles[x],this.util.in_obj(style,"uri")&&this.util.is_string(style.uri)&&out.push('<link rel="stylesheet" type="text/css" href="'+style.uri+'" />');$("head").append(out.join(""))}}},Component={_slug:"component",_ns:null,_refs:{},_reciprocal:!1,_dom:null,_attributes:!1,_attr_default:{},_attr_default_parsed:!1,_attr_init:null,_attr_map:{},_events:{},_status:null,_id:"",_c:function(id,attributes){this._set_id(id),this.util.is_obj(attributes)&&(this._attr_init=attributes),this._hooks()},_set_parent:function(){this._super(View)},_hooks:function(){},_set_id:function(id){return this.util.is_empty(this._id)&&(this._id=this.util.is_string(id)?id:this.util.guid()),this._id},get_id:function(ns){var id=this._id;return this.util.is_bool(ns)&&ns&&(id=this.add_ns(id)),id},get_ns:function(){return null===this._ns&&(this._ns=this.util.add_prefix(this._slug)),this._ns},add_ns:function(val){return this.util.is_string(val)?this.get_ns()+"_"+val:""},get_status:function(id,raw){var ret=!1;return this.util.in_obj(this._status,id)&&(ret=raw?this._status[id]:!!this._status[id]),ret},set_status:function(id,val){return this.util.is_string(id)?(this.util.is_set(val)||(val=!0),this.util.is_obj(this._status,!1)||(this._status={}),this._status[id]=val):this.util.is_set(val)||(val=!1),val},get_controller:function(){return this.get_parent()},has_reference:function(ref){return!!(this.util.is_string(ref)&&ref in this&&ref in this.get_references())},get_references:function(){return this._refs},get_reference:function(ref){return this.has_reference(ref)?this._refs[ref]:null},get_component:function(cname,options){var c=null;if(!this.has_reference(cname))return c;options=$.extend({},{check_attr:!0,get_default:!1},options);var ctype=this.get_reference(cname);return this.util.is_type(this[cname],ctype)?this[cname]:(c=this[cname]=null,options.check_attr&&(c=this.get_attribute(cname),this.util.is_empty(c)||(c=this.set_component(cname,c))),this.util.is_empty(c)&&options.get_default&&(c=this.get_controller().get_component(ctype)),c)},set_component:function(name,ref,validate){if(!this.has_reference(name))return null;if(this.util.is_empty(ref))ref=null;else{var ctype=this.get_reference(name);this.util.is_string(ref,!1)&&(ref=this.get_controller().get_component(ctype,ref)),(!this.util.is_type(ref,ctype)||this.util.is_func(validate)&&!validate.call(this,ref))&&(ref=null)}return this[name]=ref,this[name]},clear_component:function(name){this.set_component(name,null)},init_attributes:function(force){if(this.util.is_bool(force)||(force=!1),force||!this.util.is_obj(this._attributes)){var a=this._attributes={};$.extend(a,this.init_default_attributes()),this.util.is_obj(this._attr_init)&&$.extend(a,this._attr_init),$.extend(a,this.get_dom_attributes())}},init_default_attributes:function(){if(!this._attr_default_parsed&&this.util.is_obj(this._attr_map)){var opts=this.get_controller().get_options(this.util.obj_keys(this._attr_map));if(this.util.is_obj(opts)){for(var opt in this._attr_map)opt in opts&&null!==this._attr_map[opt]&&(opts[this._attr_map[opt]]=opts[opt],delete opts[opt]);$.extend(!0,this._attr_default,opts)}this._attr_default_parsed=!0}return this._attr_default},get_dom_attributes:function(){var attrs={},el=this.dom_get(null,{init:!1});if(0<el.length){var attrs_full=$(el).get(0).attributes;if(this.util.is_obj(attrs_full)){var attr_key,attr_prefix=this.util.get_attribute();$.each(attrs_full,function(idx,attr){if(-1===attr.name.indexOf(attr_prefix))return!0;attr_key=attr.name.substr(attr_prefix.length+1),attrs[attr_key]=attr.value})}}return attrs},get_attributes:function(){return this.init_attributes(),this._attributes},get_attribute:function(key,def,enforce_type){if(this.util.is_set(def)||(def=null),!this.util.is_string(key))return def;this.util.is_bool(enforce_type)||(enforce_type=!0);var ret=this.has_attribute(key)?this.get_attributes()[key]:def;return enforce_type&&ret!==def&&null!==def&&!this.util.is_type(ret,$.type(def),!1)&&(this.util.is_scalar(def,!1)&&this.util.is_scalar(ret,!1)?this.util.is_string(def,!1)?ret=ret.toString():this.util.is_num(def,!1)&&!this.util.is_num(ret,!1)?(ret=this.util.is_int(def,!1)?parseInt(ret):parseFloat(ret),this.util.is_num(ret,!1)||(ret=def)):ret=this.util.is_bool(def,!1)?this.util.is_string(ret)||this.util.is_num(ret):def:ret=def),ret},call_attribute:function(attr,args){return attr=this.get_attribute(attr),this.util.is_func(attr)&&(args=Array.prototype.slice.call(arguments,1),attr=attr.apply(this,args)),attr},has_attribute:function(key){return this.util.is_string(key)&&key in this.get_attributes()},set_attributes:function(attributes,full){this.util.is_bool(full)||(full=!1),this.init_attributes(full),this.util.is_obj(attributes)&&$.extend(this._attributes,attributes)},set_attribute:function(key,val){return this.util.is_string(key)&&this.util.is_set(val)&&(this.get_attributes()[key]=val),val},dom_get_selector:function(element){return this.util.is_string(element)?"."+this.add_ns(element):""},dom_get_attribute:function(){return this.util.get_attribute(this._slug)},dom_set:function(el){return(el=$(el)).data(this.get_data_key(),this),this._reciprocal&&(this._dom=el),el},dom_get:function(element,options){var opts_default={init:!0,put:!1};(options=this.util.is_obj(options)?$.extend({},opts_default,options):opts_default).init&&!this.get_status("dom_init")&&(this.set_status("dom_init"),this.dom_init());var ret=this._dom;if(ret&&this.util.is_string(element)){var ch=$(ret).find(this.dom_get_selector(element));ch.length?ret=ch:(!0===options.put||this.util.is_obj(options.put))&&(ret=this.dom_put(element,options.put))}return $(ret)},dom_init:function(){},dom_put:function(element,content){var r=null;if(!this.dom_has()||!this.util.is_string(element))return $(r);var strip=["tag","content","success"],options={tag:"div",content:"",class:this.add_ns(element)};this.util.is_empty(content)||(this.util.is_type(content,jQuery,!1)||this.util.is_string(content,!1)?options.content=content:this.util.is_obj(content,!1)&&$.extend(options,content));for(var attrs=$.extend({},options),x=0;x<strip.length;x++)delete attrs[strip[x]];var d=this.dom_get();return(r=$(this.dom_get_selector(element),d)).length||(r=$(this.util.format("<%s />",options.tag),attrs).appendTo(d)).length&&this.util.is_method(options,"success")&&options.success.call(r,r),$(r).append(options.content),$(r)},dom_has:function(){return!!this.dom_get().length},get_data_key:function(){return this.get_ns()},on:function(event,fn,options){if(!this.util.is_string(event)||!this.util.is_func(fn)){var t=this,args=Array.prototype.slice.call(arguments,1);return this.util.is_array(event)?$.each(event,function(idx,val){t.on.apply(t,[val].concat(args))}):this.util.is_obj(event)&&$.each(event,function(ev,hdl){t.on.apply(t,[ev,hdl].concat(args))}),this}this.util.is_obj(options,!1)||(options={}),options=$.extend({},{clear:!1},options),this.util.is_obj(this._events,!1)||(this._events={});var es=this._events;return event in es&&this.util.is_obj(es[event],!1)&&!options.clear||(es[event]=[]),es[event].push(fn),this},trigger:function(event,data){var dfr=$.Deferred(),dfrs=[],t=this;if(this.util.is_array(event))return $.each(event,function(idx,val){dfrs.push(t.trigger(val,data))}),$.when.apply(t,dfrs).done(function(){dfr.resolve()}),dfr.promise();if(!(this.util.is_string(event)&&event in this._events))return dfr.resolve(),dfr.promise();var ev={type:event,data:null};return this.util.is_set(data)&&(ev.data=data),$.each(this._events[event],function(idx,fn){dfrs.push(fn.call(t,ev,t))}),$.when.apply(this,dfrs).done(function(){dfr.resolve()}),dfr.promise()}};View.Component=Component=SLB.Class.extend(Component);var Viewer={_slug:"viewer",_refs:{item:"Content_Item",theme:"Theme"},_reciprocal:!0,_attr_default:{loop:!0,animate:!0,autofit:!0,overlay_enabled:!0,overlay_opacity:"0.8",title_default:!1,container:null,slideshow_enabled:!0,slideshow_autostart:!1,slideshow_duration:2,slideshow_active:!1,slideshow_timer:null,labels:{close:"close",nav_prev:"« prev",nav_next:"next »",slideshow_start:"start slideshow",slideshow_stop:"stop slideshow",group_status:"Image %current% of %total%",loading:"loading"}},_attr_map:{theme:null,group_loop:"loop",ui_autofit:"autofit",ui_animate:"animate",ui_overlay_opacity:"overlay_opacity",ui_labels:"labels",ui_title_default:"title_default",slideshow_enabled:null,slideshow_autostart:null,slideshow_duration:null},item:null,item_queued:null,theme:null,item_working:null,active:!1,init:!1,open:!1,loading:!1,_hooks:function(){var t=this;this.on(["item-prev","item-next"],function(){t.trigger("item-change")}).on(["close","item-change"],function(){t.unload().done(function(){t.unlock()})})},get_item:function(){return this.get_component("item")},set_item:function(item){this.clear_item(!1);var i=this.set_component("item",item,function(item){return item.has_type()});return!this.util.is_empty(i)},clear_item:function(full){this.util.is_bool(full)||(full=!0);var item=this.get_item();item&&item.reset(),full&&this.clear_component("item")},get_theme:function(){var ret=this.get_component("theme",{check_attr:!1});return this.util.is_empty(ret)&&(ret=this.set_component("theme",new View.Theme(this))),ret},set_theme:function(theme){this.set_component("theme",theme)},lock:function(){return this.set_status("item_working",$.Deferred())},get_lock:function(simple,full){this.util.is_bool(simple)||(simple=!1),this.util.is_bool(full)||(full=!1);var s="item_working";if(simple)return this.get_status(s);var r=this.get_status(s,!0);return this.util.is_promise(r)||(r=this.lock()),full?r:r.promise()},is_locked:function(){return this.get_lock(!0)},unlock:function(){return this.get_lock(!1,!0).resolve()},set_active:function(mode){return this.util.is_bool(mode)||(mode=!0),this.set_status("active",mode)},is_active:function(){return this.get_status("active")},set_loading:function(mode){var dfr=$.Deferred();this.util.is_bool(mode)||(mode=!0),this.loading=mode,this.slideshow_active()&&this.slideshow_pause(mode);var m=mode?"addClass":"removeClass";return $(this.dom_get())[m]("loading"),mode?this.get_theme().transition("load").always(function(){dfr.resolve()}):dfr.resolve(),dfr.promise()},unset_loading:function(){return this.set_loading(!1)},get_loading:function(){return!!this.util.is_bool(this.loading)&&this.loading},is_loading:function(){return this.get_loading()},show:function(item){this.item_queued=item;var vt="theme_valid",valid=!0;if(this.has_attribute(vt)?valid=this.get_attribute(vt,!0):(valid=!(!this.get_theme()||""===this.get_theme().get_template().get_layout(!1)),this.set_attribute(vt,valid)),!valid)return this.close(),!1;var v=this,fin=function(){if(v.lock(),v.set_status("show_deferred",!1),!v.set_item(v.item_queued))return v.close(),!1;v.history_add(),v.set_active(),v.render()};this.is_locked()?this.get_status("show_deferred")||(this.set_status("show_deferred"),this.get_lock().always(function(){fin()})):fin()},history_handle:function(e){var state=e.originalEvent.state;if(this.util.is_string(state.item,!1))this.get_controller().get_item(state.item).show({event:e}),this.trigger("item-change");else{var count=this.history_get(!0);this.history_set(0),-1!==count&&this.close()}},history_get:function(full){return this.get_status("history_count",full)},history_set:function(val){return this.set_status("history_count",val)},history_add:function(){if(!history.pushState)return!1;var item=this.get_item(),opts=item.get_attribute("options_show"),count=this.history_get()?this.history_get(!0):0;if(this.util.in_obj(opts,"event")){var e=opts.event.originalEvent;this.util.in_obj(e,"state")&&this.util.in_obj(e.state,"count")&&(count=e.state.count)}else{var state={viewer:this.get_id(),item:null,count:count};count||history.replaceState(state,null),state.item=this.get_controller().save_item(item).get_id(),state.count=++count,history.pushState(state,"")}this.history_set(count)},history_reset:function(){var count=this.history_get(!0);count&&(this.history_set(-1),history.go(-1*count))},is_open:function(){return"none"!==this.dom_get().css("display")},render:function(){var v=this,thm=this.get_theme();v.dom_prep(),this.get_status("render-events")||(this.set_status("render-events"),thm.on("render-loading",function(ev,thm){var dfr=$.Deferred();if(!v.is_active())return dfr.reject(),dfr.promise();var set_pos=function(){v.dom_get().css("top",$(window).scrollTop())},always=function(){v.set_loading().always(function(){dfr.resolve()})};return v.is_open()?thm.transition("unload").fail(function(){set_pos(),thm.dom_get_tag("item","content").attr("style","")}).always(always):thm.transition("open").always(function(){always(),v.events_open(),v.open=!0}).fail(function(){set_pos(),v.get_overlay().show(),v.dom_get().show()}),dfr.promise()}).on("render-complete",function(ev,thm){if(!v.is_active())return!1;var d=v.dom_get(),classes=["item_single","item_multi"],ms=["addClass","removeClass"];v.get_item().get_group().is_single()||ms.reverse(),$.each(ms,function(idx,val){d[val](classes[idx])}),v.events_complete(),thm.transition("complete").fail(function(){if(v.get_attribute("autofit",!0)){var dims=$.extend({display:"inline-block"},thm.get_item_dimensions());thm.dom_get_tag("item","content").css(dims)}}).always(function(){v.unset_loading(),v.trigger("render-complete"),v.init=!0})})),thm.render()},dom_get_container:function(){var sel=this.get_attribute("container");this.util.is_empty(sel)&&(sel="#"+this.add_ns("wrap"));var c=$(sel);if(!c.length){var id=0===sel.indexOf("#")?sel.substr(1):sel;c=$("<div />",{id:id}).appendTo("body")}return c},dom_init:function(){var d=this.dom_set($("<div/>",{id:this.get_id(!0),class:this.get_ns()})).appendTo(this.dom_get_container()).hide(),thm=this.get_theme();d.addClass(thm.get_classes(" "));var v=this;this.get_status("render-init")||(this.set_status("render-init"),thm.on("render-init",function(ev){v.dom_put("layout",ev.data)})),thm.render(!0)},dom_prep:function(mode){var m=this.util.is_bool(mode)&&!mode?"removeClass":"addClass";$("html")[m](this.util.add_prefix("overlay"))},dom_restore:function(){this.dom_prep(!1)},get_layout:function(){return this.dom_get("layout",{put:{success:function(){$(this).hide()}}})},animation_enabled:function(){return this.get_attribute("animate",!0)},overlay_enabled:function(){var ov=this.get_attribute("overlay_enabled");return!!this.util.is_bool(ov)&&ov},get_overlay:function(){var o=null,v=this;return this.overlay_enabled()&&(o=this.dom_get("overlay",{put:{success:function(){$(this).hide().css("opacity",v.get_attribute("overlay_opacity"))}}})),$(o)},unload:function(){var dfr=$.Deferred();return this.get_theme().dom_get_tag("item").text(""),dfr.resolve(),dfr.promise()},reset:function(){this.dom_get().hide(),this.dom_restore(),this.history_reset(),this.clear_item(),this.set_active(!1),this.set_loading(!1),this.slideshow_stop(),this.keys_disable(),this.unlock()},get_labels:function(){return this.get_attribute("labels",{})},get_label:function(name){var lbls=this.get_labels();return name in lbls?lbls[name]:""},events_open:function(){if(this.keys_enable(),this.open)return!1;var l=this.get_layout();l.children().click(function(ev){ev.stopPropagation()});var v=this,close=function(){v.close()};l.click(close),this.get_overlay().click(close),this.trigger("events-open")},events_complete:function(){if(this.init)return!1;this.trigger("events-complete")},keys_enable:function(mode){this.util.is_bool(mode)||(mode=!0);var e=["keyup",this.util.get_prefix()].join("."),v=this;mode?$(document).on(e,function(ev){return v.keys_control(ev)}):$(document).off(e)},keys_disable:function(){this.keys_enable(!1)},keys_control:function(ev){var handlers={27:this.close,37:this.item_prev,39:this.item_next};if("rtl"===document.documentElement.getAttribute("dir")&&(handlers[37]=this.item_next,handlers[39]=this.item_prev),ev.which in handlers)return handlers[ev.which].call(this),!1},slideshow_enabled:function(){var o=this.get_attribute("slideshow_enabled");return!(!(this.util.is_bool(o)&&o&&this.get_item())||this.get_item().get_group().is_single())},slideshow_active:function(){return!(!this.slideshow_enabled()||!(this.get_attribute("slideshow_active")||!this.init&&this.get_attribute("slideshow_autostart")))},slideshow_clear_timer:function(){clearInterval(this.get_attribute("slideshow_timer"))},slideshow_set_timer:function(callback){this.set_attribute("slideshow_timer",setInterval(callback,1e3*this.get_attribute("slideshow_duration")))},slideshow_start:function(){if(!this.slideshow_enabled())return!1;this.set_attribute("slideshow_active",!0),this.dom_get().addClass("slideshow_active"),this.slideshow_clear_timer();var v=this;this.slideshow_set_timer(function(){v.slideshow_pause(),v.item_next()}),this.trigger("slideshow-start")},slideshow_stop:function(full){this.util.is_bool(full)||(full=!0),full&&(this.set_attribute("slideshow_active",!1),this.dom_get().removeClass("slideshow_active")),this.slideshow_clear_timer(),this.trigger("slideshow-stop")},slideshow_toggle:function(){if(!this.slideshow_enabled())return!1;this.slideshow_active()?this.slideshow_stop():this.slideshow_start(),this.trigger("slideshow-toggle")},slideshow_pause:function(mode){this.util.is_bool(mode)||(mode=!0),this.slideshow_active()&&(mode?this.slideshow_stop(!1):this.slideshow_start()),this.trigger("slideshow-pause")},slideshow_resume:function(){this.slideshow_pause(!1)},item_next:function(){var g=this.get_item().get_group(!0),v=this,ev="item-next",st=["events","viewer",ev].join("_");g.get_status(st)||(g.set_status(st),g.on(ev,function(e){v.trigger(e.type)})),g.show_next()},item_prev:function(){var g=this.get_item().get_group(!0),v=this,ev="item-prev",st=["events","viewer",ev].join("_");g.get_status(st)||(g.set_status(st),g.on(ev,function(){v.trigger(ev)})),g.show_prev()},close:function(){this.set_active(!1);var v=this,thm=this.get_theme();return thm.transition("unload").always(function(){thm.transition("close",!0).always(function(){v.reset(),v.trigger("close")})}).fail(function(){thm.dom_get_tag("item","content").attr("style","")}),!1}};View.Viewer=Component.extend(Viewer);var Group={_slug:"group",_reciprocal:!0,_refs:{current:"Content_Item"},current:null,selector:null,_hooks:function(){var t=this;this.on(["item-prev","item-next"],function(){t.trigger("item-change")})},get_selector:function(){return this.util.is_empty(this.selector)&&(this.selector=this.util.format('a[%s="%s"]',this.dom_get_attribute(),this.get_id())),this.selector},get_items:function(){var items=$(this.get_selector());return 0===items.length&&this.has_current()&&(items=this.get_current().dom_get()),items},get_item:function(idx){this.util.is_int(idx)||(idx=0);var items=this.get_items(),max=this.get_size()-1;return max<idx&&(idx=max),items.get(idx)},get_pos:function(item){return this.util.is_empty(item)&&(item=this.get_current()),this.util.is_type(item,View.Content_Item)?this.get_items().index(item.dom_get()):-1},has_current:function(){return!this.util.is_empty(this.get_current())},get_current:function(){return null===this.current||this.util.is_type(this.current,View.Content_Item)||(this.current=null),this.current},set_current:function(item){this.util.is_type(item,View.Content_Item)&&(this.current=item)},get_next:function(item){if(this.util.is_type(item,View.Content_Item)||(item=this.get_current()),1===this.get_size())return item;var next=null,pos=this.get_pos(item);return-1!==pos&&(0!==(pos=pos+1<this.get_size()?pos+1:0)||item.get_viewer().get_attribute("loop"))&&(next=this.get_item(pos)),next},get_prev:function(item){if(this.util.is_type(item,View.Content_Item)||(item=this.get_current()),1===this.get_size())return item;var prev=null,pos=this.get_pos(item);return-1===pos||0===pos&&!item.get_viewer().get_attribute("loop")||(0===pos&&(pos=this.get_size()),pos-=1,prev=this.get_item(pos)),prev},show_next:function(item){if(1<this.get_size()){var next=this.get_next(item);next||(this.util.is_type(item,View.Content_Item)||(item=this.get_current()),item.get_viewer().close());var i=this.get_controller().get_item(next);this.set_current(i),i.show(),this.trigger("item-next")}},show_prev:function(item){if(1<this.get_size()){var prev=this.get_prev(item);prev||(this.util.is_type(item,View.Content_Item)||(item=this.get_current()),item.get_viewer().close());var i=this.get_controller().get_item(prev);this.set_current(i),i.show(),this.trigger("item-prev")}},get_size:function(){return this.get_items().length},is_single:function(){return 1===this.get_size()}};View.Group=Component.extend(Group);var Content_Handler={_slug:"content_handler",_refs:{item:"Content_Item"},item:null,template:"",has_item:function(){return!this.util.is_empty(this.get_item())},get_item:function(){return this.get_component("item")},set_item:function(item){return this.set_component("item",item)},clear_item:function(){this.clear_component("item")},match:function(item){var m=this.get_attribute("match");if(!this.util.is_empty(m)){if(this.util.is_string(m)&&(m=new RegExp(m,"i"),this.set_attribute("match",m)),this.util.is_type(m,RegExp))return m.test(item.get_uri());if(this.util.is_func(m))return!!m.call(this,item)}return!1},load:function(item){var dfr=$.Deferred();return null===this.call_attribute("load",item,dfr)&&dfr.resolve(),dfr.promise()},render:function(item){var dfr=$.Deferred();return this.call_attribute("render",item,dfr),dfr.promise()}};View.Content_Handler=Component.extend(Content_Handler);var Content_Item={_slug:"content_item",_reciprocal:!0,_refs:{viewer:"Viewer",group:"Group",type:"Content_Handler"},_attr_default:{source:null,permalink:null,dimensions:null,title:"",group:null,internal:!1,output:null},group:null,viewer:null,type:null,data:null,loaded:null,_c:function(el){this.dom_set(el),this._super()},init_default_attributes:function(){this._super();var d=this.dom_get(),key=d.attr(this.util.get_attribute("asset"))||null,assets=this.get_controller().assets||null;if(this.util.is_string(key)){var attrs=[{},this._attr_default,{permalink:d.attr("href")}];if(this.util.is_obj(assets)){var t=this;attrs.push(function(key){var ret={};return key in assets&&t.util.is_obj(assets[key])&&(ret=assets[key]),ret}(key))}this._attr_default=$.extend.apply(this,attrs)}return this._attr_default},get_output:function(){var dfr=$.Deferred(),ret=this.get_attribute("output");if(this.util.is_string(ret))dfr.resolve(ret);else if(this.has_type()){var type=this.get_type(),item=this;type.render(this).done(function(output){item.set_output(output),dfr.resolve(output)})}else dfr.resolve("");return dfr.promise()},set_output:function(out){this.util.is_string(out,!1)&&this.set_attribute("output",out)},get_content:function(){return this.get_output()},get_uri:function(mode){-1===$.inArray(mode,["source","permalink"])&&(mode="source");var ret=this.get_attribute(mode);return this.util.is_string(ret)||(ret="source"===mode?this.get_attribute("permalink"):""),ret=ret.replace(/&(#38|amp);/,"&")},get_title:function(){if(this.has_attribute("title_cached"))return this.get_attribute("title_cached","");var title="",dom=this.dom_get();if(dom.length&&((title=dom.attr("title"))||(title=dom.closest("figure").find("figcaption").first().html()),title||(title=dom.closest("figure").find(".wp-caption-text").first().html())),!title)for(var props=["caption","title"],x=0;x<props.length&&(title=this.get_attribute(props[x],""),this.util.is_empty(title));x++);if(!title&&dom.length&&((title=dom.find("img").first().attr("alt"))||(title=dom.get(0).innerText.trim())),this.util.is_string(title,!1)||(title=""),!this.util.is_empty(title)&&!this.get_viewer().get_attribute("title_default")){var f=this.get_uri("source"),i=f.lastIndexOf("/");-1!==i&&(-1!==(i=(f=f.substr(i+1)).lastIndexOf("."))&&(f=f.substr(0,i)),title===f&&(title=""))}return this.set_attribute("title_cached",title),title},get_dimensions:function(){return $.extend({width:0,height:0},this.get_attribute("dimensions"),{})},set_data:function(data){this.data=data},get_data:function(){return this.data},gallery_type:function(){var ret=null,types={wp:".gallery-icon",ngg:".ngg-gallery-thumbnail"},dom=this.dom_get();for(var type in types)if(0<dom.parent(types[type]).length){ret=type;break}return ret},in_gallery:function(gType){var type=this.gallery_type();return null!==type&&(!this.util.is_string(gType)||gType===type)},get_viewer:function(){return this.get_component("viewer",{get_default:!0})},set_viewer:function(v){return this.set_component("viewer",v)},get_group:function(set_current){var g=this.get_component("group");return g||(g=this.set_component("group",new View.Group),set_current=!0),set_current&&g.set_current(this),g},set_group:function(g){this.util.is_string(g)&&(g=this.get_controller().get_group(g)),this.group=!!this.util.is_type(g,View.Group)&&g},get_type:function(){var t=this.get_component("type",{check_attr:!1});return t||(t=this.set_type(this.get_controller().get_content_handler(this))),t},set_type:function(type){return this.set_component("type",type)},has_type:function(){return!this.util.is_empty(this.get_type())},show:function(options){if(!this.has_type())return!1;this.set_attribute("options_show",options);var v=this.get_viewer();return this.load(),v.show(this)},load:function(){return this.util.is_promise(this.loaded)||(this.loaded=this.get_type().load(this)),this.loaded.promise()},reset:function(){this.set_attribute("options_show",null)}};View.Content_Item=Component.extend(Content_Item);var Modeled_Component={_slug:"modeled_component",get_attribute:function(key,def,check_model,enforce_type){if(!this.util.is_string(key))return this._super(key,def,enforce_type);this.util.is_bool(check_model)||(check_model=!0);var ret=null;if(check_model){var m=this.get_ancestor(key,!1);this.util.in_obj(m,key)&&(ret=m[key])}return null===ret&&(ret=this._super(key,def,enforce_type)),ret},get_attribute_recursive:function(key,def,enforce_type){var ret=this.get_attribute(key,def,!0,enforce_type);if(this.util.is_obj(ret)){var models=this.get_ancestors(!1);ret=[ret];var t=this;$.each(models,function(idx,model){key in model&&t.util.is_obj(model[key])&&ret.push(model[key])}),ret.push({}),ret=$.extend.apply($,ret.reverse())}return ret},set_attribute:function(key,val,use_model){if(!this.util.is_string(key)||!this.util.is_set(val))return!1;(this.util.is_bool(use_model)||this.util.is_obj(use_model)||(use_model=!0),use_model)?(this.util.is_obj(use_model)?use_model:this.get_model())[key]=val:this._super(key,val);return val},get_model:function(){var m=this.get_attribute("model",null,!1);return this.util.is_obj(m)||(m={},this.set_attribute("model",m,!1)),m},has_model:function(){return!this.util.is_empty(this.get_model())},in_model:function(key){return!!this.util.in_obj(this.get_model(),key)},get_ancestors:function(inc_current){for(var ret=[],m=this.get_model();this.util.is_obj(m);)ret.push(m),m=this.util.in_obj(m,"parent")&&this.util.is_obj(m.parent)?m.parent:null;return inc_current||ret.shift(),ret},get_ancestor:function(attr,safe_mode){if(!this.util.is_string(attr))return!1;this.util.is_bool(safe_mode)||(safe_mode=!0);for(var mcurr=this.get_model(),m=mcurr,found=!1;this.util.is_obj(m);){if(this.util.in_obj(m,attr)&&!this.util.is_empty(m[attr])){found=!0;break}m=this.util.in_obj(m,"parent")?m.parent:null}return found||(safe_mode?(this.util.is_empty(m)&&(m=mcurr),this.util.in_obj(m,attr)||(m[attr]=null)):m=null),m}};Modeled_Component=Component.extend(Modeled_Component);var Theme={_slug:"theme",_refs:{viewer:"Viewer",template:"Template"},_models:{},_attr_default:{template:null,model:null},viewer:null,template:null,_c:function(id,attributes,viewer){1===arguments.length&&this.util.is_type(id,View.Viewer)&&(viewer=id,id=null),this._super(id,attributes),this.set_viewer(viewer),this.set_model(id)},get_viewer:function(){return this.get_component("viewer",{check_attr:!1,get_default:!0})},set_viewer:function(v){return this.set_component("viewer",v)},get_template:function(){var ret=this.get_component("template");if(this.util.is_empty(ret)){var attr={theme:this,model:this.get_model()};ret=this.set_component("template",new View.Template(attr))}return ret},get_tags:function(name,prop){return this.get_template().get_tags(name,prop)},dom_get_tag:function(tag,prop){return $(this.get_template().dom_get_tag(tag,prop))},get_tag_selector:function(name,prop){return this.get_template().get_tag_selector(name,prop)},get_models:function(){return this._models},get_model:function(id){var ret=null;if(!this.util.is_set(id)&&this.util.is_obj(this.get_attribute("model",null,!1)))ret=this._super();else{var models=this.get_models();this.util.is_string(id)||(id=this.get_controller().get_option("theme_default")),this.util.in_obj(models,id)||(id=$.map(models,function(v,key){return key})[0]),ret=models[id]}return ret},set_model:function(id){this.set_attribute("model",this.get_model(id),!1)},get_classes:function(rtype){var cls=[],thm=this,models=this.get_ancestors(!0);return $.each(models,function(idx,model){cls.push(thm.add_ns(model.id))}),this.util.is_string(rtype)&&(cls=cls.join(rtype)),cls},get_measurement:function(attr,def){var meas=null;if(!this.util.is_string(attr))return meas;this.util.is_obj(def,!1)||(def={});var attr_cache=this.util.format("%s_cache",attr),cache=this.get_attribute(attr_cache,{},!1),status="_status",item=this.get_viewer().get_item(),w=$(window);status in cache&&this.util.is_obj(cache._status)&&cache._status.width===w.width()&&cache._status.height===w.height()||(cache={}),this.util.is_empty(cache)&&(cache._status={width:w.width(),height:w.height(),index:[]});var pos=$.inArray(item,cache._status.index);return-1!==pos&&pos in cache&&(meas=cache[pos]),this.util.is_obj(meas)||(meas=this.call_attribute(attr),this.util.is_obj(meas)||(meas=this.get_measurement_default(attr))),meas=this.util.is_obj(meas)?$.extend({},def,meas):def,cache[pos=cache._status.index.push(item)-1]=meas,this.set_attribute(attr_cache,cache,!1),$.extend({},meas)},get_measurement_default:function(attr){return this.util.is_string(attr)?(attr=this.util.format("get_%s_default",attr),this.util.in_obj(this,attr)?(attr=this[attr],this.util.is_func(attr)&&(attr=attr.call(this))):attr=null,attr):null},get_offset:function(){return this.get_measurement("offset",{width:0,height:0})},get_offset_default:function(){var offset={width:0,height:0},v=this.get_viewer(),vn=v.dom_get(),vc=vn.clone().attr("id","").css({visibility:"hidden",position:"absolute",top:""}).removeClass("loading").appendTo(vn.parent()),l=vc.find(v.dom_get_selector("layout"));if(l.length){l.find("*").css({width:"",height:"",display:""});var tags=this.get_tags("item","content");if(tags.length){var offset_item=v.get_item().get_dimensions();tags=$(l.find(tags[0].get_selector("full")).get(0)).css({width:offset_item.width,height:offset_item.height}),$.each(offset_item,function(key,val){offset[key]=-1*val})}offset.width+=l.width(),offset.height+=l.height(),$.each(offset,function(key,val){val<0&&(offset[key]=0)})}return vc.empty().remove(),offset},get_margin:function(){return this.get_measurement("margin",{width:0,height:0})},get_item_dimensions:function(){var v=this.get_viewer(),dims=v.get_item().get_dimensions();if(v.get_attribute("autofit",!1)){var margin=this.get_margin(),offset=this.get_offset();offset.height+=margin.height,offset.width+=margin.width;var max={width:$(window).width(),height:$(window).height()};max.width>offset.width&&(max.width-=offset.width),max.height>offset.height&&(max.height-=offset.height);var factor=Math.min(max.width/dims.width,max.height/dims.height);factor<1&&$.each(dims,function(key){dims[key]=Math.round(dims[key]*factor)})}return $.extend({},dims)},get_dimensions:function(){var dims=this.get_item_dimensions(),offset=this.get_offset();return $.each(dims,function(key){dims[key]+=offset[key]}),dims},get_breakpoints:function(){return this.get_attribute_recursive("breakpoints")},get_breakpoint:function(target){var ret=0;if(this.util.is_string(target)){var b=this.get_attribute_recursive("breakpoints");this.util.is_obj(b)&&target in b&&(ret=b[target])}return ret},render:function(init){var thm=this,tpl=this.get_template(),st="events_render";this.get_status(st)||(this.set_status(st),tpl.on(["render-init","render-loading","render-complete"],function(ev){return thm.trigger(ev.type,ev.data)})),tpl.render(init)},transition:function(event,clear_queue){var dfr=null,attr="transition",v=this.get_viewer(),fx_temp=null,anim_on=v.animation_enabled();if(v.get_attribute(attr,!0)&&this.util.is_string(event)){clear_queue&&v.get_layout().find("*").each(function(){for(var el=$(this);el.queue().length;)el.stop(!1,!0)});var trns,attr_set=[attr,"set"].join("_");if(this.get_attribute(attr_set))trns=this.get_attribute(attr,{});else{var models=this.get_ancestors(!0);trns=[],this.set_attribute(attr_set,!0);var thm=this;$.each(models,function(idx,model){attr in model&&thm.util.is_obj(model[attr])&&trns.push(model[attr])}),trns.push({}),trns=this.set_attribute(attr,$.extend.apply($,trns.reverse()))}this.util.is_method(trns,event)&&(anim_on||(fx_temp=$.fx.off,$.fx.off=!0),dfr=trns[event].call(this,v,$.Deferred()))}return this.util.is_promise(dfr)||(dfr=$.Deferred()).reject(),dfr.always(function(){null!==fx_temp&&($.fx.off=fx_temp)}),dfr.promise()}};View.Theme=Modeled_Component.extend(Theme);var Template={_slug:"template",_reciprocal:!0,_refs:{theme:"Theme"},_attr_default:{layout_uri:"",layout_raw:"",layout_parsed:"",tags:null,model:null},theme:null,_c:function(attributes){this._super("",attributes)},_hooks:function(){this.on("dom_init",function(ev){var tags=this.get_tags(null,null,!0),names=[],t=this;$.each(tags,function(idx,tag){var name=tag.get_name();-1===$.inArray(name,names)&&(names.push(name),tag.get_handler().trigger(ev.type,{template:t}))})})},get_theme:function(){return this.get_component("theme")},render:function(init){var v=this.get_theme().get_viewer();if(this.util.is_bool(init)||(init=!1),init)this.trigger("render-init",this.dom_get());else{if(!v.is_active())return!1;var item=v.get_item();if(!this.util.is_type(item,View.Content_Item))return v.close(),!1;if(v.is_active()&&this.has_tags()){var loading_promise=this.trigger("render-loading"),tpl=this,tags=this.get_tags(),tag_promises=[];$.when(item.load(),loading_promise).done(function(){return!!v.is_active()&&($.each(tags,function(idx,tag){if(!v.is_active())return!1;tag_promises.push(tag.render(item).done(function(r){if(!v.is_active())return!1;r.tag.dom_get().html(r.output)}))}),!!v.is_active()&&void $.when.apply($,tag_promises).done(function(){tpl.trigger("render-complete")}))})}}},get_layout:function(parsed){return this.util.is_bool(parsed)||(parsed=!0),parsed?this.parse_layout():this.get_attribute("layout_raw","")},parse_layout:function(){var a="layout_parsed",ret=this.get_attribute(a);return this.util.is_string(ret)||(ret=this.sanitize_layout(this.get_layout(!1)),ret=this.parse_tags(ret),this.set_attribute(a,ret)),ret},sanitize_layout:function(l){if(this.util.is_empty(l))return l;var rtype=this.util.is_string(l)?"string":null,dom=$(l),tag_temp=this.get_tag_temp(),cls=tag_temp.get_class(),cls_new=["x",cls].join("_");switch($(tag_temp.get_selector(),dom).each(function(){$(this).removeClass(cls).addClass(cls_new)}),rtype){case"string":l=dom=dom.wrap("<div />").parent().html();break;default:l=dom}return l},parse_tags:function(l){if(!this.util.is_string(l))return"";for(var match,re=/\{{2}\s*(\w.*?)\s*\}{2}/gim;match=re.exec(l);)l=l.substring(0,match.index)+this.get_tag_container(match[1])+l.substring(match.index+match[0].length);return l},get_tag_container:function(tag){var attr=this.get_tag_attribute();return this.util.format('<span %s="%s"></span>',attr,encodeURI(tag))},get_tag_attribute:function(){return this.get_tag_temp().dom_get_attribute()},get_tag:function(idx){var ret=null;if(this.has_tags()){var tags=this.get_tags();(!this.util.is_int(idx)||idx<0||idx>=tags.length)&&(idx=0),ret=tags[idx]}return ret},get_tags:function(name,prop,isolate){this.util.is_bool(isolate)||(isolate=!1);var a="tags",tags=this.get_attribute(a);if(!this.util.is_array(tags)){tags=[];var d=this.dom_get(),attr=this.get_tag_attribute(),nodes=$(d).find("["+attr+"]");$(nodes).each(function(){var el=$(this),tag=new View.Template_Tag(decodeURI(el.attr(attr)));tag.has_handler()&&(tags.push(tag),isolate||(tag.dom_set(el),el.addClass(tag.get_classes(" ")))),isolate||el.removeAttr(attr)}),isolate||this.set_attribute(a,tags,!1)}if(!this.util.is_empty(tags)&&this.util.is_string(name)){this.util.is_string(prop)||(prop=!1);for(var tags_filtered=[],tc=null,x=0;x<tags.length;x++)name===(tc=tags[x]).get_name()&&(prop&&prop!==tc.get_prop()||tags_filtered.push(tc));tags=tags_filtered}return this.util.is_array(tags,!1)?tags:[]},has_tags:function(){return 0<this.get_tags().length},get_tag_temp:function(){return this.get_controller().get_component_temp(View.Template_Tag)},get_tag_selector:function(name,prop){this.util.is_string(name)||(name=""),this.util.is_string(prop)||(prop="");var tag=this.get_tag_temp();return tag.set_attribute("name",name),tag.set_attribute("prop",prop),tag.get_selector("full")},dom_init:function(){this.dom_set(this.get_layout()),this.trigger("dom_init")},dom_get_tag:function(tag,prop){var ret=$(),tags=this.get_tags(tag,prop);if(tags.length){var level=null;this.util.is_string(tag)&&(level=this.util.is_string(prop)?"full":"tag");var sel="."+tags[0].get_class(level);ret=this.dom_get().find(sel)}return ret}};View.Template=Modeled_Component.extend(Template);var Template_Tag={_slug:"template_tag",_reciprocal:!0,_attr_default:{name:null,prop:null,match:null},handlers:{},_c:function(tag_match){this.parse(tag_match)},parse:function(tag_match){if(!this.util.is_string(tag_match))return!1;var part,parts=tag_match.split("|");if(!parts.length)return null;var attrs={name:null,prop:null,match:tag_match};attrs.name=parts[0],-1!==attrs.name.indexOf(".")&&(attrs.name=attrs.name.split(".",2),attrs.prop=attrs.name[1],attrs.name=attrs.name[0]);for(var x=1;x<parts.length;x++)1<(part=parts[x].split(":",1)).length&&!(part[0]in attrs)&&(attrs[part[0]]=part[1]);this.set_attributes(attrs,!0)},render:function(item){var tag=this;return tag.get_handler().render(item,tag).pipe(function(output){return{tag:tag,output:output}})},get_name:function(){return this.get_attribute("name")},get_prop:function(){return this.get_attribute("prop")},get_handler:function(){return this.has_handler()?this.handlers[this.get_name()]:new View.Template_Tag_Handler("")},has_handler:function(){return this.get_name()in this.handlers},get_classes:function(rtype){var cls=[this.get_class(),this.get_class("tag"),this.get_class("full")];return this.util.is_string(rtype)&&(cls=cls.join(rtype)),cls},get_class:function(level){var cls="";switch(level){case"tag":cls=this.get_name();break;case"full":var i,parts=[this.get_name(),this.get_prop()],a=[];for(i=0;i<parts.length;i++)this.util.is_string(parts[i])&&a.push(parts[i]);cls=a.join("_")}return this.util.is_string(cls)?this.add_ns(cls):this.get_ns()},get_selector:function(level){var ret=this.get_class(level);return ret=this.util.is_string(ret)?"."+ret:""}};View.Template_Tag=Component.extend(Template_Tag);var Template_Tag_Handler={_slug:"template_tag_handler",_attr_default:{supports_modifiers:!1,dynamic:!1,props:{}},render:function(item,instance){var dfr=$.Deferred();return this.call_attribute("render",item,instance,dfr),dfr.promise()},add_prop:function(prop,fn){var a="props",props=this.get_attribute(a);if(!this.util.is_string(prop)||!this.util.is_func(fn))return!1;this.util.is_obj(props,!1)||(props={}),props[prop]=fn,this.set_attribute(a,props)},handle_prop:function(prop,item,instance){var props=this.get_attribute("props");return this.util.is_obj(props)&&prop in props&&this.util.is_func(props[prop])?props[prop].call(this,item,instance):item.get_viewer().get_label(prop)}};View.Template_Tag_Handler=Component.extend(Template_Tag_Handler),View=SLB.attach("View",View)}(jQuery);
|
client/sass/admin.scss
CHANGED
@@ -28,4 +28,27 @@
|
|
28 |
.slb_notice {
|
29 |
color: #f00;
|
30 |
font-weight: bold;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
}
|
28 |
.slb_notice {
|
29 |
color: #f00;
|
30 |
font-weight: bold;
|
31 |
+
}
|
32 |
+
|
33 |
+
.slb {
|
34 |
+
.columns-2 {
|
35 |
+
margin-right: 300px;
|
36 |
+
.postbox-container {
|
37 |
+
float: left;
|
38 |
+
width: 100%;
|
39 |
+
}
|
40 |
+
.content-secondary {
|
41 |
+
margin-right: -300px;
|
42 |
+
width: 280px;
|
43 |
+
float: right;
|
44 |
+
}
|
45 |
+
}
|
46 |
+
}
|
47 |
+
|
48 |
+
.slb_admin_action_reset {
|
49 |
+
color: #a00;
|
50 |
+
&:hover {
|
51 |
+
color: #dc3232;
|
52 |
+
border: none;
|
53 |
+
}
|
54 |
}
|
client/sass/app.scss
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
html.slb_overlay {
|
2 |
+
object,embed,iframe {
|
3 |
+
visibility: hidden;
|
4 |
+
}
|
5 |
+
#slb_viewer_wrap {
|
6 |
+
object,embed,iframe {
|
7 |
+
visibility: visible;
|
8 |
+
}
|
9 |
+
}
|
10 |
+
}
|
content-handlers/image/handler.image.js
DELETED
@@ -1,29 +0,0 @@
|
|
1 |
-
(function($) {
|
2 |
-
return {
|
3 |
-
render: function(item) {
|
4 |
-
var dfr = $.Deferred();
|
5 |
-
//Create image object
|
6 |
-
var img = new Image();
|
7 |
-
var type = this;
|
8 |
-
//Set load event
|
9 |
-
var handler = function(e) {
|
10 |
-
//Save Data
|
11 |
-
item.set_data(img);
|
12 |
-
//Set attributes
|
13 |
-
var dim = {'width': img.width, 'height': img.height};
|
14 |
-
item.set_attribute('dimensions', dim);
|
15 |
-
//Build output
|
16 |
-
var out = $('<img />', {'src': item.get_uri()});
|
17 |
-
//Resolve deferred
|
18 |
-
dfr.resolve(out);
|
19 |
-
};
|
20 |
-
|
21 |
-
//Attach event handler
|
22 |
-
$(img).on('load', function(e) { handler(e); });
|
23 |
-
//Load image
|
24 |
-
img.src = item.get_uri();
|
25 |
-
//Return promise
|
26 |
-
return dfr.promise();
|
27 |
-
}
|
28 |
-
}
|
29 |
-
})(jQuery);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
content-handlers/image/js/dev/handler.image.js
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
if ( !!window.SLB && SLB.has_child('View.extend_content_handler') ) {(function($) {
|
2 |
+
SLB.View.extend_content_handler('image', {
|
3 |
+
/**
|
4 |
+
* Render images
|
5 |
+
* @param obj item Content Item
|
6 |
+
* @param obj dfr Promise for rendering process
|
7 |
+
* @return obj Promise for rendering process (Resolved when content is loaded)
|
8 |
+
*/
|
9 |
+
render: function(item, dfr) {
|
10 |
+
// Create image object
|
11 |
+
var img = new Image();
|
12 |
+
// Set load event
|
13 |
+
var handler = function() {
|
14 |
+
// Save Data
|
15 |
+
item.set_data(img);
|
16 |
+
// Set attributes
|
17 |
+
item.set_attribute('dimensions', {'width': img.width, 'height': img.height});
|
18 |
+
// Build output
|
19 |
+
var out = $('<img />', {'src': item.get_uri()});
|
20 |
+
// Resolve deferred
|
21 |
+
dfr.resolve(out);
|
22 |
+
};
|
23 |
+
|
24 |
+
// Attach event handler
|
25 |
+
$(img).on('load', function(e) { handler(e); });
|
26 |
+
// Load image
|
27 |
+
img.src = item.get_uri();
|
28 |
+
// Return promise
|
29 |
+
return dfr.promise();
|
30 |
+
}
|
31 |
+
});
|
32 |
+
})(jQuery);
|
33 |
+
}
|
content-handlers/image/js/prod/handler.image.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
window.SLB&&SLB.has_child("View.extend_content_handler")&&!function($){SLB.View.extend_content_handler("image",{render:function(item,dfr){var img=new Image,handler=function(){item.set_data(img),item.set_attribute("dimensions",{width:img.width,height:img.height});var out=$("<img />",{src:item.get_uri()});dfr.resolve(out)};return $(img).on("load",function(e){handler(e)}),img.src=item.get_uri(),dfr.promise()}})}(jQuery);
|
controller.php
ADDED
@@ -0,0 +1,1654 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Controller
|
4 |
+
* @package Simple Lightbox
|
5 |
+
* @author Archetyped
|
6 |
+
*/
|
7 |
+
class SLB_Lightbox extends SLB_Base {
|
8 |
+
|
9 |
+
/*-** Properties **-*/
|
10 |
+
|
11 |
+
protected $model = true;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Fields
|
15 |
+
* @var SLB_Fields
|
16 |
+
*/
|
17 |
+
public $fields = null;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Themes collection
|
21 |
+
* @var SLB_Themes
|
22 |
+
*/
|
23 |
+
var $themes = null;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Content types
|
27 |
+
* @var SLB_Content_Handlers
|
28 |
+
*/
|
29 |
+
var $handlers = null;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Template tags
|
33 |
+
* @var SLB_Template_Tags
|
34 |
+
*/
|
35 |
+
var $template_tags = null;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Collection of processed media items for output to client
|
39 |
+
* > Key (string) Attachment URI
|
40 |
+
* > Value (assoc-array) Attachment properties (url, etc.)
|
41 |
+
* > source: Source URL
|
42 |
+
* @var array
|
43 |
+
*/
|
44 |
+
var $media_items = array();
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Collection of unprocessed media items
|
48 |
+
* Multi-dimensional array
|
49 |
+
* > props (array) Media properties indexed by ID
|
50 |
+
* > Key: (string) Unique ID (system-generated)
|
51 |
+
* > Value: (object) Media properties
|
52 |
+
* > type: (string) Item type (Default: null)
|
53 |
+
* > id: (int) WP item ID (Default: null)
|
54 |
+
* > uri (array) Index of cached URIs
|
55 |
+
* > Key: (string) Item URI
|
56 |
+
* > Value: (string) Item ID (pointer to item in `id` array)
|
57 |
+
* @var array
|
58 |
+
*/
|
59 |
+
private $media_items_raw = array( 'props' => array(), 'uri' => array() );
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Manage excluded content
|
63 |
+
* @var object
|
64 |
+
*/
|
65 |
+
private $exclude = null;
|
66 |
+
|
67 |
+
private $groups = array (
|
68 |
+
'auto' => 0,
|
69 |
+
'manual' => array(),
|
70 |
+
);
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Validated URIs
|
74 |
+
* Caches validation of parsed URIs
|
75 |
+
* > Key: URI
|
76 |
+
* > Value: (bool) TRUE if valid
|
77 |
+
* @var array
|
78 |
+
*/
|
79 |
+
private $validated_uris = array();
|
80 |
+
|
81 |
+
/* Widget properties */
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Used to track if widget is currently being processed or not
|
85 |
+
* Set to Widget ID currently being processed
|
86 |
+
* @var bool|string
|
87 |
+
*/
|
88 |
+
private $widget_processing = false;
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Parameters for widget being processed
|
92 |
+
* @param array
|
93 |
+
*/
|
94 |
+
private $widget_processing_params = null;
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Manage nested widget processing
|
98 |
+
* Used to avoid premature widget output
|
99 |
+
* @var int
|
100 |
+
*/
|
101 |
+
private $widget_processing_level = 0;
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Constructor
|
105 |
+
*/
|
106 |
+
public function __construct() {
|
107 |
+
parent::__construct();
|
108 |
+
// Init instances
|
109 |
+
$this->fields = new SLB_Fields();
|
110 |
+
$this->themes = new SLB_Themes($this);
|
111 |
+
if ( !is_admin() ) {
|
112 |
+
$this->template_tags = new SLB_Template_Tags($this);
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
/* Init */
|
117 |
+
|
118 |
+
public function _init() {
|
119 |
+
parent::_init();
|
120 |
+
$this->util->do_action('init');
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Declare client files (scripts, styles)
|
125 |
+
* @uses parent::_client_files()
|
126 |
+
* @return void
|
127 |
+
*/
|
128 |
+
protected function _client_files($files = null) {
|
129 |
+
$js_path = 'client/js/';
|
130 |
+
$js_path .= ( SLB_DEV ) ? 'dev' : 'prod';
|
131 |
+
$files = array (
|
132 |
+
'scripts' => array (
|
133 |
+
'core' => array (
|
134 |
+
'file' => "$js_path/lib.core.js",
|
135 |
+
'deps' => 'jquery',
|
136 |
+
'enqueue' => false,
|
137 |
+
'in_footer' => true,
|
138 |
+
),
|
139 |
+
'view' => array (
|
140 |
+
'file' => "$js_path/lib.view.js",
|
141 |
+
'deps' => array('[core]'),
|
142 |
+
'context' => array( array('public', $this->m('is_request_valid')) ),
|
143 |
+
'in_footer' => true,
|
144 |
+
),
|
145 |
+
),
|
146 |
+
'styles' => array (
|
147 |
+
'core' => array (
|
148 |
+
'file' => 'client/css/app.css',
|
149 |
+
'context' => array('public'),
|
150 |
+
)
|
151 |
+
)
|
152 |
+
);
|
153 |
+
parent::_client_files($files);
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* Register hooks
|
158 |
+
* @uses parent::_hooks()
|
159 |
+
*/
|
160 |
+
protected function _hooks() {
|
161 |
+
parent::_hooks();
|
162 |
+
|
163 |
+
/* Admin */
|
164 |
+
add_action('admin_menu', $this->m('admin_menus'));
|
165 |
+
$this->util->add_filter('admin_plugin_row_meta_support', $this->m('admin_plugin_row_meta_support'));
|
166 |
+
|
167 |
+
/* Init */
|
168 |
+
add_action('wp', $this->m('_hooks_init'));
|
169 |
+
}
|
170 |
+
|
171 |
+
/**
|
172 |
+
* Init Hooks
|
173 |
+
*/
|
174 |
+
public function _hooks_init() {
|
175 |
+
if ( $this->is_enabled() ) {
|
176 |
+
$priority = $this->util->priority('low');
|
177 |
+
|
178 |
+
// Init lightbox
|
179 |
+
add_action('wp_footer', $this->m('client_footer'));
|
180 |
+
$this->util->add_action('footer_script', $this->m('client_init'), 1);
|
181 |
+
$this->util->add_filter('footer_script', $this->m('client_script_media'), 2);
|
182 |
+
// Link activation
|
183 |
+
add_filter('the_content', $this->m('activate_links'), $priority);
|
184 |
+
add_filter('get_post_galleries', $this->m('activate_galleries'), $priority);
|
185 |
+
$this->util->add_filter('post_process_links', $this->m('activate_groups'), 11);
|
186 |
+
$this->util->add_filter('validate_uri_regex', $this->m('validate_uri_regex_default'), 1);
|
187 |
+
// Content exclusion
|
188 |
+
$this->util->add_filter('pre_process_links', $this->m('exclude_content'));
|
189 |
+
$this->util->add_filter('pre_exclude_content', $this->m('exclude_shortcodes'));
|
190 |
+
$this->util->add_filter('post_process_links', $this->m('restore_excluded_content'));
|
191 |
+
|
192 |
+
// Grouping
|
193 |
+
if ( $this->options->get_bool('group_post') ) {
|
194 |
+
$this->util->add_filter('get_group_id', $this->m('post_group_id'), 1);
|
195 |
+
}
|
196 |
+
|
197 |
+
// Shortcode grouping
|
198 |
+
if ( $this->options->get_bool('group_gallery') ) {
|
199 |
+
add_filter('the_content', $this->m('group_shortcodes'), 1);
|
200 |
+
}
|
201 |
+
|
202 |
+
// Widgets
|
203 |
+
if ( $this->options->get_bool('enabled_widget') ) {
|
204 |
+
add_action('dynamic_sidebar_before', $this->m('widget_process_nested'));
|
205 |
+
add_action('dynamic_sidebar', $this->m('widget_process_start'), PHP_INT_MAX);
|
206 |
+
add_filter('dynamic_sidebar_params', $this->m('widget_process_inter'), PHP_INT_MAX);
|
207 |
+
add_action('dynamic_sidebar_after', $this->m('widget_process_finish'), PHP_INT_MAX - 1);
|
208 |
+
add_action('dynamic_sidebar_after', $this->m('widget_process_nested_finish'), PHP_INT_MAX);
|
209 |
+
} else {
|
210 |
+
add_action('dynamic_sidebar_before', $this->m('widget_block_start'));
|
211 |
+
add_action('dynamic_sidebar_after', $this->m('widget_block_finish'));
|
212 |
+
}
|
213 |
+
|
214 |
+
// Menus
|
215 |
+
if ( $this->options->get_bool('enabled_menu') ) {
|
216 |
+
add_filter('wp_nav_menu', $this->m('menu_process'), $priority, 2);
|
217 |
+
}
|
218 |
+
}
|
219 |
+
}
|
220 |
+
|
221 |
+
/**
|
222 |
+
* Add post ID to link group ID
|
223 |
+
* @uses `SLB::get_group_id` filter
|
224 |
+
* @param array $group_segments Group ID segments
|
225 |
+
* @return array Modified group ID segments
|
226 |
+
*/
|
227 |
+
public function post_group_id($group_segments) {
|
228 |
+
if ( in_the_loop() ) {
|
229 |
+
// Prepend post ID to group ID
|
230 |
+
$post = get_post();
|
231 |
+
if ( $post ) {
|
232 |
+
array_unshift($group_segments, $post->ID);
|
233 |
+
}
|
234 |
+
}
|
235 |
+
return $group_segments;
|
236 |
+
}
|
237 |
+
|
238 |
+
/**
|
239 |
+
* Init options
|
240 |
+
*/
|
241 |
+
protected function _options() {
|
242 |
+
// Setup options
|
243 |
+
$opts = array (
|
244 |
+
'groups' => array (
|
245 |
+
'activation' => array ( 'title' => __('Activation', 'simple-lightbox'), 'priority' => 10),
|
246 |
+
'grouping' => array ( 'title' => __('Grouping', 'simple-lightbox'), 'priority' => 20),
|
247 |
+
'ui' => array ( 'title' => __('UI', 'simple-lightbox'), 'priority' => 30),
|
248 |
+
'labels' => array ( 'title' => __('Labels', 'simple-lightbox'), 'priority' => 40),
|
249 |
+
),
|
250 |
+
'items' => array (
|
251 |
+
'enabled' => array('title' => __('Enable Lightbox Functionality', 'simple-lightbox'), 'default' => true, 'group' => array('activation', 10)),
|
252 |
+
'enabled_home' => array('title' => __('Enable on Home page', 'simple-lightbox'), 'default' => true, 'group' => array('activation', 20)),
|
253 |
+
'enabled_post' => array('title' => __('Enable on Single Posts', 'simple-lightbox'), 'default' => true, 'group' => array('activation', 30)),
|
254 |
+
'enabled_page' => array('title' => __('Enable on Pages', 'simple-lightbox'), 'default' => true, 'group' => array('activation', 40)),
|
255 |
+
'enabled_archive' => array('title' => __('Enable on Archive Pages (tags, categories, etc.)', 'simple-lightbox'), 'default' => true, 'group' => array('activation', 50)),
|
256 |
+
'enabled_widget' => array('title' => __('Enable for Widgets', 'simple-lightbox'), 'default' => false, 'group' => array('activation', 60)),
|
257 |
+
'enabled_menu' => array('title' => __('Enable for Menus', 'simple-lightbox'), 'default' => false, 'group' => array('activation', 60)),
|
258 |
+
'group_links' => array('title' => __('Group items (for displaying as a slideshow)', 'simple-lightbox'), 'default' => true, 'group' => array('grouping', 10)),
|
259 |
+
'group_post' => array('title' => __('Group items by Post (e.g. on pages with multiple posts)', 'simple-lightbox'), 'default' => true, 'group' => array('grouping', 20)),
|
260 |
+
'group_gallery' => array('title' => __('Group gallery items separately', 'simple-lightbox'), 'default' => false, 'group' => array('grouping', 30)),
|
261 |
+
'group_widget' => array('title' => __('Group widget items separately', 'simple-lightbox'), 'default' => false, 'group' => array('grouping', 40)),
|
262 |
+
'group_menu' => array('title' => __('Group menu items separately', 'simple-lightbox'), 'default' => false, 'group' => array('grouping', 50)),
|
263 |
+
'ui_autofit' => array('title' => __('Resize lightbox to fit in window', 'simple-lightbox'), 'default' => true, 'group' => array('ui', 10), 'in_client' => true),
|
264 |
+
'ui_animate' => array('title' => __('Enable animations', 'simple-lightbox'), 'default' => true, 'group' => array('ui', 20), 'in_client' => true),
|
265 |
+
'slideshow_autostart' => array('title' => __('Start Slideshow Automatically', 'simple-lightbox'), 'default' => true, 'group' => array('ui', 30), 'in_client' => true),
|
266 |
+
'slideshow_duration' => array('title' => __('Slide Duration (Seconds)', 'simple-lightbox'), 'default' => '6', 'attr' => array('size' => 3, 'maxlength' => 3), 'group' => array('ui', 40), 'in_client' => true),
|
267 |
+
'group_loop' => array('title' => __('Loop through items', 'simple-lightbox'),'default' => true, 'group' => array('ui', 50), 'in_client' => true),
|
268 |
+
'ui_overlay_opacity' => array('title' => __('Overlay Opacity (0 - 1)', 'simple-lightbox'), 'default' => '0.8', 'attr' => array('size' => 3, 'maxlength' => 3), 'group' => array('ui', 60), 'in_client' => true),
|
269 |
+
'ui_title_default' => array('title' => __('Enable default title', 'simple-lightbox'), 'default' => false, 'group' => array('ui', 70), 'in_client' => true),
|
270 |
+
'txt_loading' => array('title' => __('Loading indicator', 'simple-lightbox'), 'default' => 'Loading', 'group' => array('labels', 20)),
|
271 |
+
'txt_close' => array('title' => __('Close button', 'simple-lightbox'), 'default' => 'Close', 'group' => array('labels', 10)),
|
272 |
+
'txt_nav_next' => array('title' => __('Next Item button', 'simple-lightbox'), 'default' => 'Next', 'group' => array('labels', 30)),
|
273 |
+
'txt_nav_prev' => array('title' => __('Previous Item button', 'simple-lightbox'), 'default' => 'Previous', 'group' => array('labels', 40)),
|
274 |
+
'txt_slideshow_start' => array('title' => __('Start Slideshow button', 'simple-lightbox'), 'default' => 'Start slideshow', 'group' => array('labels', 50)),
|
275 |
+
'txt_slideshow_stop' => array('title' => __('Stop Slideshow button', 'simple-lightbox'),'default' => 'Stop slideshow', 'group' => array('labels', 60)),
|
276 |
+
'txt_group_status' => array('title' => __('Slideshow status format', 'simple-lightbox'), 'default' => 'Item %current% of %total%', 'group' => array('labels', 70))
|
277 |
+
),
|
278 |
+
'legacy' => array (
|
279 |
+
'header_activation' => null,
|
280 |
+
'header_enabled' => null,
|
281 |
+
'header_strings' => null,
|
282 |
+
'header_ui' => null,
|
283 |
+
'activate_attachments' => null,
|
284 |
+
'validate_links' => null,
|
285 |
+
'enabled_compat' => null,
|
286 |
+
'enabled_single' => array('enabled_post', 'enabled_page'),
|
287 |
+
'enabled_caption' => null,
|
288 |
+
'enabled_desc' => null,
|
289 |
+
'ui_enabled_caption' => null,
|
290 |
+
'ui_caption_src' => null,
|
291 |
+
'ui_enabled_desc' => null,
|
292 |
+
'caption_src' => null,
|
293 |
+
'animate' => 'ui_animate',
|
294 |
+
'overlay_opacity' => 'ui_overlay_opacity',
|
295 |
+
'loop' => 'group_loop',
|
296 |
+
'autostart' => 'slideshow_autostart',
|
297 |
+
'duration' => 'slideshow_duration',
|
298 |
+
'txt_numDisplayPrefix' => null,
|
299 |
+
'txt_numDisplaySeparator' => null,
|
300 |
+
'txt_closeLink' => 'txt_link_close',
|
301 |
+
'txt_nextLink' => 'txt_link_next',
|
302 |
+
'txt_prevLink' => 'txt_link_prev',
|
303 |
+
'txt_startSlideshow' => 'txt_slideshow_start',
|
304 |
+
'txt_stopSlideshow' => 'txt_slideshow_stop',
|
305 |
+
'txt_loadingMsg' => 'txt_loading',
|
306 |
+
'txt_link_next' => 'txt_nav_next',
|
307 |
+
'txt_link_prev' => 'txt_nav_prev',
|
308 |
+
'txt_link_close' => 'txt_close',
|
309 |
+
)
|
310 |
+
);
|
311 |
+
|
312 |
+
parent::_set_options($opts);
|
313 |
+
}
|
314 |
+
|
315 |
+
/* Methods */
|
316 |
+
|
317 |
+
/*-** Admin **-*/
|
318 |
+
|
319 |
+
/**
|
320 |
+
* Add admin menus
|
321 |
+
* @uses this->admin->add_theme_page
|
322 |
+
*/
|
323 |
+
function admin_menus() {
|
324 |
+
// Build options page
|
325 |
+
$lbls_opts = array(
|
326 |
+
'menu' => __('Lightbox', 'simple-lightbox'),
|
327 |
+
'header' => __('Lightbox Settings', 'simple-lightbox'),
|
328 |
+
'plugin_action' => __('Settings', 'simple-lightbox')
|
329 |
+
);
|
330 |
+
$pg_opts = $this->admin->add_theme_page('options', $lbls_opts)
|
331 |
+
->require_form()
|
332 |
+
->add_content('options', 'Options', $this->options);
|
333 |
+
|
334 |
+
// Add Support information
|
335 |
+
$support = $this->util->get_plugin_info('SupportURI');
|
336 |
+
if ( !empty($support) ) {
|
337 |
+
$pg_opts->add_content('support', __('Feedback & Support', 'simple-lightbox'), $this->m('theme_page_callback_support'), 'secondary');
|
338 |
+
}
|
339 |
+
|
340 |
+
// Add Actions
|
341 |
+
$lbls_reset = array (
|
342 |
+
'title' => __('Reset', 'simple-lightbox'),
|
343 |
+
'confirm' => __('Are you sure you want to reset Simple Lightbox\'s settings?', 'simple-lightbox'),
|
344 |
+
'success' => __('Settings have been reset', 'simple-lightbox'),
|
345 |
+
'failure' => __('Settings were not reset', 'simple-lightbox')
|
346 |
+
);
|
347 |
+
$this->admin->add_action('reset', $lbls_reset, $this->options);
|
348 |
+
}
|
349 |
+
|
350 |
+
/**
|
351 |
+
* Support information
|
352 |
+
*/
|
353 |
+
public function theme_page_callback_support() {
|
354 |
+
// Description
|
355 |
+
$desc = __("<p>Simple Lightbox thrives on your feedback!</p><p>Click the button below to <strong>get help</strong>, <strong>request a feature</strong>, or <strong>provide some feedback</strong>!</p>", 'simple-lightbox');
|
356 |
+
echo $desc;
|
357 |
+
// Link
|
358 |
+
$lnk_uri = $this->util->get_plugin_info('SupportURI');
|
359 |
+
$lnk_txt = __('Get Support & Provide Feedback', 'simple-lightbox');
|
360 |
+
echo $this->util->build_html_link($lnk_uri, $lnk_txt, array('target' => '_blank', 'class' => 'button'));
|
361 |
+
}
|
362 |
+
|
363 |
+
/**
|
364 |
+
* Filter support link text in plugin metadata
|
365 |
+
* @param string $text Original link text
|
366 |
+
* @return string Modified link text
|
367 |
+
*/
|
368 |
+
public function admin_plugin_row_meta_support($text) {
|
369 |
+
return __("Feedback & Support", 'simple-lightbox');
|
370 |
+
}
|
371 |
+
|
372 |
+
/*-** Functionality **-*/
|
373 |
+
|
374 |
+
/**
|
375 |
+
* Checks whether lightbox is currently enabled/disabled
|
376 |
+
* @return bool TRUE if lightbox is currently enabled, FALSE otherwise
|
377 |
+
*/
|
378 |
+
function is_enabled() {
|
379 |
+
static $ret = null;
|
380 |
+
if ( is_null($ret) ) {
|
381 |
+
$ret = ( !is_admin() && $this->options->get_bool('enabled') && !is_feed() ) ? true : false;
|
382 |
+
if ( $ret ) {
|
383 |
+
$opt = '';
|
384 |
+
// Determine option to check
|
385 |
+
if ( is_home() || is_front_page() ) {
|
386 |
+
$opt = 'home';
|
387 |
+
}
|
388 |
+
elseif ( is_singular() ) {
|
389 |
+
$opt = ( is_page() ) ? 'page' : 'post';
|
390 |
+
}
|
391 |
+
elseif ( is_archive() || is_search() ) {
|
392 |
+
$opt = 'archive';
|
393 |
+
}
|
394 |
+
// Check sub-option
|
395 |
+
if ( !empty($opt) && ( $opt = 'enabled_' . $opt ) && $this->options->has($opt) ) {
|
396 |
+
$ret = $this->options->get_bool($opt);
|
397 |
+
}
|
398 |
+
}
|
399 |
+
}
|
400 |
+
// Filter return value
|
401 |
+
if ( !is_admin() ) {
|
402 |
+
$ret = $this->util->apply_filters('is_enabled', $ret);
|
403 |
+
}
|
404 |
+
// Return value (force boolean)
|
405 |
+
return !!$ret;
|
406 |
+
}
|
407 |
+
|
408 |
+
/**
|
409 |
+
* Make sure content is valid for processing/activation
|
410 |
+
*
|
411 |
+
* @param string $content Content to validate
|
412 |
+
* @return bool TRUE if content is valid (FALSE otherwise)
|
413 |
+
*/
|
414 |
+
protected function is_content_valid($content) {
|
415 |
+
// Invalid hooks
|
416 |
+
if ( doing_filter('get_the_excerpt') )
|
417 |
+
return false;
|
418 |
+
|
419 |
+
// Non-string value
|
420 |
+
if ( !is_string($content) )
|
421 |
+
return false;
|
422 |
+
|
423 |
+
// Empty string
|
424 |
+
$content = trim($content);
|
425 |
+
if ( empty($content) )
|
426 |
+
return false;
|
427 |
+
|
428 |
+
// Content is valid
|
429 |
+
return $this->util->apply_filters('is_content_valid', true, $content);
|
430 |
+
}
|
431 |
+
|
432 |
+
/**
|
433 |
+
* Activates galleries extracted from post
|
434 |
+
* @see get_post_galleries()
|
435 |
+
* @param array $galleries A list of galleries in post
|
436 |
+
* @return A list of galleries with links activated
|
437 |
+
*/
|
438 |
+
function activate_galleries($galleries) {
|
439 |
+
// Validate
|
440 |
+
if ( empty($galleries) ) {
|
441 |
+
return $galleries;
|
442 |
+
}
|
443 |
+
// Check galleries for HTML output
|
444 |
+
$gallery = reset($galleries);
|
445 |
+
if ( is_array($gallery) ) {
|
446 |
+
return $galleries;
|
447 |
+
}
|
448 |
+
|
449 |
+
// Activate galleries
|
450 |
+
$group = ( $this->options->get_bool('group_gallery') ) ? true : null;
|
451 |
+
foreach ( $galleries as $key => $val ) {
|
452 |
+
if ( !is_null($group) ) {
|
453 |
+
$group = 'gallery_' . $key;
|
454 |
+
}
|
455 |
+
// Activate links in gallery
|
456 |
+
$gallery = $this->process_links($val, $group);
|
457 |
+
|
458 |
+
// Save modified gallery
|
459 |
+
$galleries[$key] = $gallery;
|
460 |
+
}
|
461 |
+
|
462 |
+
return $galleries;
|
463 |
+
}
|
464 |
+
|
465 |
+
/**
|
466 |
+
* Scans post content for image links and activates them
|
467 |
+
*
|
468 |
+
* Lightbox will not be activated for feeds
|
469 |
+
* @param string $content Content to activate
|
470 |
+
* @param string (optonal) $group Group ID for content
|
471 |
+
* @return string Post content
|
472 |
+
*/
|
473 |
+
public function activate_links($content, $group = null) {
|
474 |
+
// Validate content
|
475 |
+
if ( !$this->is_content_valid($content) ) {
|
476 |
+
return $content;
|
477 |
+
}
|
478 |
+
// Filter content before processing links
|
479 |
+
$content = $this->util->apply_filters('pre_process_links', $content);
|
480 |
+
|
481 |
+
// Process links
|
482 |
+
$content = $this->process_links($content, $group);
|
483 |
+
|
484 |
+
// Filter content after processing links
|
485 |
+
$content = $this->util->apply_filters('post_process_links', $content);
|
486 |
+
|
487 |
+
return $content;
|
488 |
+
}
|
489 |
+
|
490 |
+
/**
|
491 |
+
* Process links in content
|
492 |
+
* @global obj $wpdb DB instance
|
493 |
+
* @global obj $post Current post
|
494 |
+
* @param string $content Text containing links
|
495 |
+
* @param string (optional) $group Group to add links to (Default: none)
|
496 |
+
* @return string Content with processed links
|
497 |
+
*/
|
498 |
+
protected function process_links($content, $group = null) {
|
499 |
+
// Extract links
|
500 |
+
$links = $this->get_links($content, true);
|
501 |
+
// Do not process content without links
|
502 |
+
if ( empty($links) ) {
|
503 |
+
return $content;
|
504 |
+
}
|
505 |
+
// Process links
|
506 |
+
static $protocol = array('http://', 'https://');
|
507 |
+
static $qv_att = 'attachment_id';
|
508 |
+
static $uri_origin = null;
|
509 |
+
if ( !is_array($uri_origin) ) {
|
510 |
+
$uri_parts = array_fill_keys(array('scheme', 'host', 'path'), '');
|
511 |
+
$uri_origin = wp_parse_args(parse_url( strtolower(home_url()) ), $uri_parts);
|
512 |
+
}
|
513 |
+
static $uri_proto = null;
|
514 |
+
if ( empty($uri_proto) ) {
|
515 |
+
$uri_proto = (object) array('raw' => '', 'source' => '', 'parts' => '');
|
516 |
+
}
|
517 |
+
$uri_parts_required = array('host' => '');
|
518 |
+
|
519 |
+
// Setup group properties
|
520 |
+
$g_props = (object) array(
|
521 |
+
'enabled' => $this->options->get_bool('group_links'),
|
522 |
+
'attr' => 'group',
|
523 |
+
'base' => '',
|
524 |
+
'legacy_prefix' => 'lightbox[',
|
525 |
+
'legacy_suffix' => ']'
|
526 |
+
);
|
527 |
+
if ( $g_props->enabled ) {
|
528 |
+
$g_props->base = ( is_scalar($group) ) ? trim(strval($group)) : '';
|
529 |
+
}
|
530 |
+
|
531 |
+
// Initialize content handlers
|
532 |
+
if ( !( $this->handlers instanceof SLB_Content_Handlers ) ) {
|
533 |
+
$this->handlers = new SLB_Content_Handlers($this);
|
534 |
+
}
|
535 |
+
|
536 |
+
// Iterate through and activate supported links
|
537 |
+
|
538 |
+
foreach ( $links as $link ) {
|
539 |
+
// Init vars
|
540 |
+
$pid = 0;
|
541 |
+
$link_new = $link;
|
542 |
+
$uri = clone $uri_proto;
|
543 |
+
$type = false;
|
544 |
+
$props_extra = array();
|
545 |
+
$key = null;
|
546 |
+
$internal = false;
|
547 |
+
|
548 |
+
// Parse link attributes
|
549 |
+
$attrs = $this->util->parse_attribute_string($link_new, array('href' => ''));
|
550 |
+
// Get URI
|
551 |
+
$uri->raw = $attrs['href'];
|
552 |
+
|
553 |
+
// Stop processing invalid links
|
554 |
+
if ( !$this->validate_uri($uri->raw)
|
555 |
+
|| $this->has_attribute($attrs, 'active', false) // Previously-processed
|
556 |
+
) {
|
557 |
+
continue;
|
558 |
+
}
|
559 |
+
|
560 |
+
// Normalize URI (make absolute)
|
561 |
+
$uri->source = WP_HTTP::make_absolute_url($uri->raw, $uri_origin['scheme'] . '://' . $uri_origin['host']);
|
562 |
+
|
563 |
+
// URI cached?
|
564 |
+
$key = $this->get_media_item_id($uri->source);
|
565 |
+
|
566 |
+
// Internal URI? (e.g. attachments)
|
567 |
+
if ( !$key ) {
|
568 |
+
$uri->parts = array_merge( $uri_parts_required, (array) parse_url($uri->source) );
|
569 |
+
$internal = ( $uri->parts['host'] === $uri_origin['host'] ) ? true : false;
|
570 |
+
|
571 |
+
// Attachment?
|
572 |
+
if ( $internal && is_local_attachment($uri->source) ) {
|
573 |
+
$pid = url_to_postid($uri->source);
|
574 |
+
$src = wp_get_attachment_url($pid);
|
575 |
+
if ( !!$src ) {
|
576 |
+
$uri->source = $src;
|
577 |
+
$props_extra['id'] = $pid;
|
578 |
+
// Check cache for attachment source URI
|
579 |
+
$key = $this->get_media_item_id($uri->source);
|
580 |
+
}
|
581 |
+
unset($src);
|
582 |
+
}
|
583 |
+
}
|
584 |
+
|
585 |
+
// Determine content type
|
586 |
+
if ( !$key ) {
|
587 |
+
// Get handler match
|
588 |
+
$hdl_result = $this->handlers->match($uri->source);
|
589 |
+
if ( !!$hdl_result->handler ) {
|
590 |
+
$type = $hdl_result->handler->get_id();
|
591 |
+
$props_extra = $hdl_result->props;
|
592 |
+
// Updated source URI
|
593 |
+
if ( isset($props_extra['uri']) ) {
|
594 |
+
$uri->source = $props_extra['uri'];
|
595 |
+
unset($props_extra['uri']);
|
596 |
+
}
|
597 |
+
}
|
598 |
+
|
599 |
+
// Cache valid item
|
600 |
+
if ( !!$type ) {
|
601 |
+
$key = $this->cache_media_item($uri, $type, $internal, $props_extra);
|
602 |
+
}
|
603 |
+
}
|
604 |
+
|
605 |
+
// Stop processing invalid links
|
606 |
+
if ( !$key ) {
|
607 |
+
// Cache invalid URI
|
608 |
+
$this->validated_uris[$uri->source] = false;
|
609 |
+
if ( $uri->raw !== $uri->source ) {
|
610 |
+
$this->validated_uris[$uri->raw] = false;
|
611 |
+
}
|
612 |
+
continue;
|
613 |
+
}
|
614 |
+
|
615 |
+
// Activate link
|
616 |
+
$this->set_attribute($attrs, 'active');
|
617 |
+
$this->set_attribute($attrs, 'asset', $key);
|
618 |
+
// Mark internal links
|
619 |
+
if ( $internal ) {
|
620 |
+
$this->set_attribute($attrs, 'internal', $pid);
|
621 |
+
}
|
622 |
+
|
623 |
+
// Set group (if enabled)
|
624 |
+
if ( $g_props->enabled ) {
|
625 |
+
$group = array();
|
626 |
+
// Get preset group attribute
|
627 |
+
$g = ( $this->has_attribute($attrs, $g_props->attr) ) ? $this->get_attribute($attrs, $g_props->attr) : '';
|
628 |
+
if ( is_string($g) && ($g = trim($g)) && !empty($g) ) {
|
629 |
+
$group[] = $g;
|
630 |
+
} elseif ( !empty($g_props->base) ) {
|
631 |
+
$group[] = $g_props->base;
|
632 |
+
}
|
633 |
+
|
634 |
+
/**
|
635 |
+
* Filter group ID components
|
636 |
+
*
|
637 |
+
* @see process_links()
|
638 |
+
*
|
639 |
+
* @param array $group Components used to build group ID
|
640 |
+
*/
|
641 |
+
$group = $this->util->apply_filters('get_group_id', $group);
|
642 |
+
|
643 |
+
// Default group
|
644 |
+
if ( empty($group) || !is_array($group) ) {
|
645 |
+
$group = $this->get_prefix();
|
646 |
+
} else {
|
647 |
+
$group = implode('_', $group);
|
648 |
+
}
|
649 |
+
|
650 |
+
// Set group attribute
|
651 |
+
$this->set_attribute($attrs, $g_props->attr, $group);
|
652 |
+
unset($g);
|
653 |
+
}
|
654 |
+
|
655 |
+
// Filter attributes
|
656 |
+
$attrs = $this->util->apply_filters('process_link_attributes', $attrs);
|
657 |
+
|
658 |
+
// Update link in content
|
659 |
+
$link_new = '<a ' . $this->util->build_attribute_string($attrs) . '>';
|
660 |
+
$content = str_replace($link, $link_new, $content);
|
661 |
+
}
|
662 |
+
|
663 |
+
// Handle widget content
|
664 |
+
if ( !!$this->widget_processing && 'the_content' == current_filter() ) {
|
665 |
+
$content = $this->exclude_wrap($content);
|
666 |
+
}
|
667 |
+
|
668 |
+
return $content;
|
669 |
+
}
|
670 |
+
|
671 |
+
/**
|
672 |
+
* Retrieve HTML links in content
|
673 |
+
* @param string $content Content to get links from
|
674 |
+
* @param bool (optional) $unique Remove duplicates from returned links (Default: FALSE)
|
675 |
+
* @return array Links in content
|
676 |
+
*/
|
677 |
+
function get_links($content, $unique = false) {
|
678 |
+
$rgx = "/\<a[^\>]+href=.*?\>/i";
|
679 |
+
$links = array();
|
680 |
+
preg_match_all($rgx, $content, $links);
|
681 |
+
$links = $links[0];
|
682 |
+
if ( $unique )
|
683 |
+
$links = array_unique($links);
|
684 |
+
return $links;
|
685 |
+
}
|
686 |
+
|
687 |
+
/**
|
688 |
+
* Validate URI
|
689 |
+
* Matches specified URI against internal & external regex patterns
|
690 |
+
* URI is **invalid** if it matches a regex
|
691 |
+
*
|
692 |
+
* @param string $uri URI to validate
|
693 |
+
* @return bool TRUE if URI is valid
|
694 |
+
*/
|
695 |
+
protected function validate_uri($uri) {
|
696 |
+
static $patterns = null;
|
697 |
+
// Previously-validated URI
|
698 |
+
if ( isset($this->validated_uris[$uri]) )
|
699 |
+
return $this->validated_uris[$uri];
|
700 |
+
|
701 |
+
$valid = true;
|
702 |
+
// Boilerplate validation
|
703 |
+
if ( empty($uri) // Empty
|
704 |
+
|| 0 === strpos($uri, '#') // Anchor
|
705 |
+
)
|
706 |
+
$valid = false;
|
707 |
+
|
708 |
+
// Regex matching
|
709 |
+
if ( $valid ) {
|
710 |
+
// Get patterns
|
711 |
+
if ( is_null($patterns) ) {
|
712 |
+
$patterns = $this->util->apply_filters('validate_uri_regex', array());
|
713 |
+
}
|
714 |
+
// Iterate through patterns until match found
|
715 |
+
foreach ( $patterns as $pattern ) {
|
716 |
+
if ( 1 === preg_match($pattern, $uri) ) {
|
717 |
+
$valid = false;
|
718 |
+
break;
|
719 |
+
}
|
720 |
+
}
|
721 |
+
}
|
722 |
+
|
723 |
+
// Cache
|
724 |
+
$this->validated_uris[$uri] = $valid;
|
725 |
+
return $valid;
|
726 |
+
}
|
727 |
+
|
728 |
+
/**
|
729 |
+
* Add URI validation regex pattern
|
730 |
+
* @param
|
731 |
+
*/
|
732 |
+
public function validate_uri_regex_default($patterns) {
|
733 |
+
$patterns[] = '@^https?://[^/]*(wikipedia|wikimedia)\.org/wiki/file:.*$@i';
|
734 |
+
return $patterns;
|
735 |
+
}
|
736 |
+
|
737 |
+
/* Client */
|
738 |
+
|
739 |
+
/**
|
740 |
+
* Checks if output should be loaded in current request
|
741 |
+
* @uses `is_enabled()`
|
742 |
+
* @uses `has_cached_media_items()`
|
743 |
+
* @return bool TRUE if output is being loaded into client
|
744 |
+
*/
|
745 |
+
public function is_request_valid() {
|
746 |
+
return ( $this->is_enabled() && $this->has_cached_media_items() ) ? true : false;
|
747 |
+
}
|
748 |
+
|
749 |
+
/**
|
750 |
+
* Sets options/settings to initialize lightbox functionality on page load
|
751 |
+
* @return void
|
752 |
+
*/
|
753 |
+
function client_init($client_script) {
|
754 |
+
// Get options
|
755 |
+
$options = $this->options->build_client_output();
|
756 |
+
|
757 |
+
// Load UI Strings
|
758 |
+
if ( ($labels = $this->build_labels()) && !empty($labels) ) {
|
759 |
+
$options['ui_labels'] = $labels;
|
760 |
+
}
|
761 |
+
|
762 |
+
// Build client output
|
763 |
+
$client_script[] = $this->util->call_client_method('View.init', $options);
|
764 |
+
return $client_script;
|
765 |
+
}
|
766 |
+
|
767 |
+
/**
|
768 |
+
* Output code in footer
|
769 |
+
* > Media attachment URLs
|
770 |
+
* @uses `_wp_attached_file` to match attachment ID to URI
|
771 |
+
* @uses `_wp_attachment_metadata` to retrieve attachment metadata
|
772 |
+
*/
|
773 |
+
function client_footer() {
|
774 |
+
if ( !$this->has_cached_media_items() )
|
775 |
+
return false;
|
776 |
+
|
777 |
+
// Set up hooks
|
778 |
+
add_action('wp_print_footer_scripts', $this->m('client_footer_script'));
|
779 |
+
|
780 |
+
// Build client output
|
781 |
+
$this->util->do_action('footer');
|
782 |
+
}
|
783 |
+
|
784 |
+
/**
|
785 |
+
* Output client footer scripts
|
786 |
+
*/
|
787 |
+
function client_footer_script() {
|
788 |
+
$client_script = $this->util->apply_filters('footer_script', array());
|
789 |
+
if ( !empty($client_script) ) {
|
790 |
+
echo $this->util->build_script_element($client_script, 'footer', true, true);
|
791 |
+
}
|
792 |
+
}
|
793 |
+
|
794 |
+
/**
|
795 |
+
* Add media information to client output
|
796 |
+
*
|
797 |
+
* @param array $commands Client script commands
|
798 |
+
* @return array Modified script commands
|
799 |
+
* TODO Refactor
|
800 |
+
*/
|
801 |
+
function client_script_media($client_script) {
|
802 |
+
global $wpdb;
|
803 |
+
|
804 |
+
// Init variables
|
805 |
+
$this->media_items = array();
|
806 |
+
$props = array('id', 'type', 'description', 'title', 'source', 'caption');
|
807 |
+
$props = (object) array_combine($props, $props);
|
808 |
+
$props_map = array('description' => 'post_content', 'title' => 'post_title', 'caption' => 'post_excerpt');
|
809 |
+
|
810 |
+
// Separate media into buckets by type
|
811 |
+
$m_internals = array();
|
812 |
+
$type = $id = null;
|
813 |
+
|
814 |
+
$m_items = $this->media_items = $this->get_cached_media_items();
|
815 |
+
foreach ( $m_items as $key => $p ) {
|
816 |
+
// Set aside internal links for additional processing
|
817 |
+
if ( $p->internal && !isset($m_internals[$key]) ) {
|
818 |
+
$m_internals[$key] =& $m_items[$key];
|
819 |
+
}
|
820 |
+
}
|
821 |
+
unset($key, $p);
|
822 |
+
|
823 |
+
// Process internal links
|
824 |
+
if ( !empty($m_internals) ) {
|
825 |
+
$uris_base = array();
|
826 |
+
$uri_prefix = wp_upload_dir();
|
827 |
+
$uri_prefix = $this->util->normalize_path($uri_prefix['baseurl'], true);
|
828 |
+
foreach ( $m_internals as $key => $p ) {
|
829 |
+
// Prepare internal links
|
830 |
+
// Create relative URIs for attachment data retrieval
|
831 |
+
if ( !$p->id && strpos($p->source, $uri_prefix) === 0 ) {
|
832 |
+
$uris_base[str_replace($uri_prefix, '', $p->source)] = $key;
|
833 |
+
}
|
834 |
+
}
|
835 |
+
unset($key, $p);
|
836 |
+
|
837 |
+
// Retrieve attachment IDs
|
838 |
+
$uris_flat = "('" . implode("','", array_keys($uris_base)) . "')";
|
839 |
+
$q = $wpdb->prepare("SELECT post_id, meta_value FROM $wpdb->postmeta WHERE `meta_key` = %s AND LOWER(`meta_value`) IN $uris_flat LIMIT %d", '_wp_attached_file', count($uris_base));
|
840 |
+
$pids = $wpdb->get_results($q);
|
841 |
+
// Match IDs to URIs
|
842 |
+
if ( $pids ) {
|
843 |
+
foreach ( $pids as $pd ) {
|
844 |
+
$file =& $pd->meta_value;
|
845 |
+
if ( isset($uris_base[$file]) ) {
|
846 |
+
$m_internals[ $uris_base[$file] ]->{$props->id} = absint($pd->post_id);
|
847 |
+
}
|
848 |
+
}
|
849 |
+
}
|
850 |
+
// Destroy worker vars
|
851 |
+
unset($uris_base, $uris_flat, $q, $pids, $pd, $file);
|
852 |
+
}
|
853 |
+
|
854 |
+
// Process items with attachment IDs
|
855 |
+
$pids = array();
|
856 |
+
foreach ( $m_items as $key => $p ) {
|
857 |
+
// Add post ID to query
|
858 |
+
if ( !!$p->id ) {
|
859 |
+
// Create array for ID (support multiple URIs per ID)
|
860 |
+
if ( !isset($pids[$p->id]) ) {
|
861 |
+
$pids[$p->id] = array();
|
862 |
+
}
|
863 |
+
// Add URI to ID
|
864 |
+
$pids[$p->id][] = $key;
|
865 |
+
}
|
866 |
+
}
|
867 |
+
unset($key, $p);
|
868 |
+
|
869 |
+
// Retrieve attachment properties
|
870 |
+
if ( !empty($pids) ) {
|
871 |
+
$pids_flat = array_keys($pids);
|
872 |
+
// Retrieve attachment post data
|
873 |
+
$atts = get_posts(array('post_type' => 'attachment', 'include' => $pids_flat));
|
874 |
+
|
875 |
+
// Process attachments
|
876 |
+
if ( $atts ) {
|
877 |
+
// Retrieve attachment metadata
|
878 |
+
$pids_flat = "('" . implode("','", $pids_flat) . "')";
|
879 |
+
$atts_meta = $wpdb->get_results($wpdb->prepare("SELECT `post_id`,`meta_value` FROM $wpdb->postmeta WHERE `post_id` IN $pids_flat AND `meta_key` = %s LIMIT %d", '_wp_attachment_metadata', count($atts)));
|
880 |
+
// Restructure metadata array by post ID
|
881 |
+
if ( $atts_meta ) {
|
882 |
+
$meta = array();
|
883 |
+
foreach ( $atts_meta as $att_meta ) {
|
884 |
+
$meta[$att_meta->post_id] = $att_meta->meta_value;
|
885 |
+
}
|
886 |
+
$atts_meta = $meta;
|
887 |
+
unset($meta);
|
888 |
+
} else {
|
889 |
+
$atts_meta = array();
|
890 |
+
}
|
891 |
+
$props_size = array('file', 'width', 'height');
|
892 |
+
$props_exclude = array('hwstring_small');
|
893 |
+
foreach ( $atts as $att ) {
|
894 |
+
// Set post data
|
895 |
+
$m = array();
|
896 |
+
|
897 |
+
// Remap post data to properties
|
898 |
+
foreach ( $props_map as $prop_key => $prop_source ) {
|
899 |
+
$m[$props->{$prop_key}] = $att->{$prop_source};
|
900 |
+
}
|
901 |
+
unset($prop_key, $prop_source);
|
902 |
+
|
903 |
+
// Add metadata
|
904 |
+
if ( isset($atts_meta[$att->ID]) && ($a = unserialize($atts_meta[$att->ID])) && is_array($a) ) {
|
905 |
+
// Move original size into `sizes` array
|
906 |
+
foreach ( $props_size as $d ) {
|
907 |
+
if ( !isset($a[$d]) ) {
|
908 |
+
continue;
|
909 |
+
}
|
910 |
+
$a['sizes']['original'][$d] = $a[$d];
|
911 |
+
unset($a[$d]);
|
912 |
+
}
|
913 |
+
|
914 |
+
// Strip extraneous metadata
|
915 |
+
foreach ( $props_exclude as $d ) {
|
916 |
+
if ( isset($a[$d]) ) {
|
917 |
+
unset($a[$d]);
|
918 |
+
}
|
919 |
+
}
|
920 |
+
|
921 |
+
// Merge post data & meta data
|
922 |
+
$m = array_merge($a, $m);
|
923 |
+
// Destroy worker vars
|
924 |
+
unset($a, $d);
|
925 |
+
}
|
926 |
+
|
927 |
+
// Save attachment data (post & meta) to original object(s)
|
928 |
+
if ( isset($pids[$att->ID]) ) {
|
929 |
+
foreach ( $pids[$att->ID] as $key ) {
|
930 |
+
$this->media_items[$key] = array_merge( (array) $m_items[$key], $m);
|
931 |
+
}
|
932 |
+
}
|
933 |
+
}
|
934 |
+
}
|
935 |
+
unset($atts, $atts_meta, $m, $a, $uri, $pids, $pids_flat);
|
936 |
+
}
|
937 |
+
|
938 |
+
// Filter media item properties
|
939 |
+
foreach ( $this->media_items as $key => $props ) {
|
940 |
+
$this->media_items[$key] = $this->util->apply_filters('media_item_properties', (object) $props);
|
941 |
+
}
|
942 |
+
|
943 |
+
// Build client output
|
944 |
+
$obj = 'View.assets';
|
945 |
+
$client_script[] = $this->util->extend_client_object($obj, $this->media_items);
|
946 |
+
return $client_script;
|
947 |
+
}
|
948 |
+
|
949 |
+
/*-** Media **-*/
|
950 |
+
|
951 |
+
/**
|
952 |
+
* Cache media properties for later processing
|
953 |
+
* @uses array self::$media_items_raw Stores media items for output
|
954 |
+
* @param object $uri URI to cache
|
955 |
+
* Members
|
956 |
+
* > raw: Raw Link URI
|
957 |
+
* > source: Source URI (e.g. for attachment URIs)
|
958 |
+
* @param string $type Media type (image, attachment, etc.)
|
959 |
+
* @param bool $internal TRUE if media is internal (e.g. attachment)
|
960 |
+
* @param array $props (optional) Properties to store for item (Default: NULL)
|
961 |
+
* @return string Unique ID for cached media item
|
962 |
+
*/
|
963 |
+
private function cache_media_item($uri, $type, $internal, $props = null) {
|
964 |
+
// Validate
|
965 |
+
if ( !is_object($uri) || !is_string($type) ) {
|
966 |
+
return false;
|
967 |
+
}
|
968 |
+
// Check if URI already cached
|
969 |
+
$key = $this->get_media_item_id($uri->source);
|
970 |
+
// Cache new item
|
971 |
+
if ( null == $key ) {
|
972 |
+
// Generate Unique ID
|
973 |
+
do {
|
974 |
+
$key = (string) mt_rand();
|
975 |
+
} while ( isset($this->media_items_raw['props'][$key]) );
|
976 |
+
// Build properties object
|
977 |
+
$i = array('id' => null);
|
978 |
+
if ( is_array($props) && !empty($props) ) {
|
979 |
+
$i = array_merge($i, $props);
|
980 |
+
}
|
981 |
+
$i = array_merge($i, array('type' => $type, 'source' => $uri->source, 'internal' => $internal));
|
982 |
+
// Cache item properties
|
983 |
+
$this->media_items_raw['props'][$key] = (object) $i;
|
984 |
+
// Cache Source URI (point to properties object)
|
985 |
+
$this->media_items_raw['uri'][$uri->source] = $key;
|
986 |
+
}
|
987 |
+
return $key;
|
988 |
+
}
|
989 |
+
|
990 |
+
/**
|
991 |
+
* Retrieve ID for media item
|
992 |
+
* @uses self::$media_items_raw
|
993 |
+
* @param string $uri Media item URI
|
994 |
+
* @return string|null Media item ID (Default: NULL if URI doesn't exist in collection)
|
995 |
+
*/
|
996 |
+
private function get_media_item_id($uri) {
|
997 |
+
if ( $this->media_item_cached($uri) ) {
|
998 |
+
return $this->media_items_raw['uri'][$uri];
|
999 |
+
}
|
1000 |
+
return null;
|
1001 |
+
}
|
1002 |
+
|
1003 |
+
/**
|
1004 |
+
* Checks if media item has already been cached
|
1005 |
+
* @param string $uri URI of media item
|
1006 |
+
* @return boolean Whether media item has been cached
|
1007 |
+
*/
|
1008 |
+
private function media_item_cached($uri) {
|
1009 |
+
return ( is_string($uri) && !empty($uri) && isset($this->media_items_raw['uri'][$uri]) ) ? true : false;
|
1010 |
+
}
|
1011 |
+
|
1012 |
+
/**
|
1013 |
+
* Retrieve cached media item
|
1014 |
+
* @param string $uri Media item URI
|
1015 |
+
* @return object|null Media item properties (NULL if not set)
|
1016 |
+
*/
|
1017 |
+
private function get_cached_media_item($uri) {
|
1018 |
+
$key = $this->get_media_item_id($uri);
|
1019 |
+
if ( null != $key ) {
|
1020 |
+
return $this->media_items_raw['props'][$key];
|
1021 |
+
}
|
1022 |
+
return null;
|
1023 |
+
}
|
1024 |
+
|
1025 |
+
/**
|
1026 |
+
* Retrieve cached media items (properties)
|
1027 |
+
* @uses self::$media_items_raw
|
1028 |
+
* @return array Cached media items (objects)
|
1029 |
+
*/
|
1030 |
+
private function &get_cached_media_items() {
|
1031 |
+
return $this->media_items_raw['props'];
|
1032 |
+
}
|
1033 |
+
|
1034 |
+
/**
|
1035 |
+
* Check if media items have been cached
|
1036 |
+
* @return boolean
|
1037 |
+
*/
|
1038 |
+
private function has_cached_media_items() {
|
1039 |
+
return ( empty($this->media_items_raw['props']) ) ? false : true;
|
1040 |
+
}
|
1041 |
+
|
1042 |
+
/*-** Exclusion **-*/
|
1043 |
+
|
1044 |
+
/**
|
1045 |
+
* Retrieve exclude object
|
1046 |
+
* Initialize object properties if necessary
|
1047 |
+
* @return object Exclude properties
|
1048 |
+
*/
|
1049 |
+
private function get_exclude() {
|
1050 |
+
// Initialize exclude data
|
1051 |
+
if ( !is_object($this->exclude) ) {
|
1052 |
+
$this->exclude = (object) array (
|
1053 |
+
'tags' => $this->get_exclude_tags(),
|
1054 |
+
'ph' => $this->get_exclude_placeholder(),
|
1055 |
+
'group_default' => 'default',
|
1056 |
+
'cache' => array(),
|
1057 |
+
);
|
1058 |
+
}
|
1059 |
+
return $this->exclude;
|
1060 |
+
}
|
1061 |
+
|
1062 |
+
/**
|
1063 |
+
* Get exclusion tags (open/close)
|
1064 |
+
* Example: open => [slb_exclude], close => [/slb_exclude]
|
1065 |
+
*
|
1066 |
+
* @return object Exclusion tags
|
1067 |
+
*/
|
1068 |
+
private function get_exclude_tags() {
|
1069 |
+
static $tags = null;
|
1070 |
+
if ( null == $tags ) {
|
1071 |
+
$base = $this->add_prefix('exclude');
|
1072 |
+
$tags = (object) array (
|
1073 |
+
'base' => $base,
|
1074 |
+
'open' => $this->util->add_wrapper($base),
|
1075 |
+
'close' => $this->util->add_wrapper($base, '[/', ']')
|
1076 |
+
);
|
1077 |
+
$tags->search ='#' . preg_quote($tags->open) . '(.*?)' . preg_quote($tags->close) . '#s';
|
1078 |
+
}
|
1079 |
+
return $tags;
|
1080 |
+
}
|
1081 |
+
|
1082 |
+
/**
|
1083 |
+
* Get exclusion tag ("[slb_exclude]")
|
1084 |
+
* @uses `get_exclude_tags()` to retrieve tag
|
1085 |
+
*
|
1086 |
+
* @param string $type (optional) Tag to retrieve (open or close)
|
1087 |
+
* @return string Exclusion tag
|
1088 |
+
*/
|
1089 |
+
private function get_exclude_tag( $type = "open" ) {
|
1090 |
+
// Validate
|
1091 |
+
$tags = $this->get_exclude_tags();
|
1092 |
+
if ( !isset($tags->{$type}) ) {
|
1093 |
+
$type = "open";
|
1094 |
+
}
|
1095 |
+
return $tags->{$type};
|
1096 |
+
}
|
1097 |
+
|
1098 |
+
/**
|
1099 |
+
* Build exclude placeholder
|
1100 |
+
* @return object Exclude placeholder properties
|
1101 |
+
*/
|
1102 |
+
private function get_exclude_placeholder() {
|
1103 |
+
static $ph;
|
1104 |
+
if ( !is_object($ph) ) {
|
1105 |
+
$ph = (object) array (
|
1106 |
+
'base' => $this->add_prefix('exclude_temp'),
|
1107 |
+
'open' => '{{',
|
1108 |
+
'close' => '}}',
|
1109 |
+
'attrs' => array ( 'group' => '', 'key' => '' ),
|
1110 |
+
);
|
1111 |
+
// Search Patterns
|
1112 |
+
$sub = '(.+?)';
|
1113 |
+
$ph->search = '#' . preg_quote($ph->open) . $ph->base . '\s+' . $sub . preg_quote($ph->close) . '#s';
|
1114 |
+
$ph->search_group = str_replace($sub, '(group="%s"\s+.?)', $ph->search);
|
1115 |
+
// Templates
|
1116 |
+
$attr_string = '';
|
1117 |
+
foreach ( $ph->attrs as $attr => $val ) {
|
1118 |
+
$attr_string .= ' ' . $attr . '="%s"';
|
1119 |
+
}
|
1120 |
+
$ph->template = $ph->open . $ph->base . $attr_string . $ph->close;
|
1121 |
+
}
|
1122 |
+
return $ph;
|
1123 |
+
}
|
1124 |
+
|
1125 |
+
/**
|
1126 |
+
* Wrap content in exclusion tags
|
1127 |
+
* @uses `get_exclude_tag()` to wrap content with exclusion tag
|
1128 |
+
* @param string $content Content to exclude
|
1129 |
+
* @return string Content wrapped in exclusion tags
|
1130 |
+
*/
|
1131 |
+
private function exclude_wrap($content) {
|
1132 |
+
// Validate
|
1133 |
+
if ( !is_string($content) ) {
|
1134 |
+
$content = "";
|
1135 |
+
}
|
1136 |
+
// Wrap
|
1137 |
+
$tags = $this->get_exclude_tags();
|
1138 |
+
return $tags->open . $content . $tags->close;
|
1139 |
+
}
|
1140 |
+
|
1141 |
+
/**
|
1142 |
+
* Remove excluded content
|
1143 |
+
* Caches content for restoring later
|
1144 |
+
* @param string $content Content to remove excluded content from
|
1145 |
+
* @return string Updated content
|
1146 |
+
*/
|
1147 |
+
public function exclude_content($content, $group = null) {
|
1148 |
+
$ex = $this->get_exclude();
|
1149 |
+
// Setup cache
|
1150 |
+
if ( !is_string($group) || empty($group) ) {
|
1151 |
+
$group = $ex->group_default;
|
1152 |
+
}
|
1153 |
+
if ( !isset($ex->cache[$group]) ) {
|
1154 |
+
$ex->cache[$group] = array();
|
1155 |
+
}
|
1156 |
+
$cache =& $ex->cache[$group];
|
1157 |
+
|
1158 |
+
$content = $this->util->apply_filters('pre_exclude_content', $content);
|
1159 |
+
|
1160 |
+
// Search content
|
1161 |
+
$matches = null;
|
1162 |
+
if ( false !== strpos($content, $ex->tags->open) && preg_match_all($ex->tags->search, $content, $matches) ) {
|
1163 |
+
// Determine index
|
1164 |
+
$idx = ( !!end($cache) ) ? key($cache) : -1;
|
1165 |
+
$ph = array();
|
1166 |
+
foreach ( $matches[1] as $midx => $match ) {
|
1167 |
+
// Update index
|
1168 |
+
$idx++;
|
1169 |
+
// Cache content
|
1170 |
+
$cache[$idx] = $match;
|
1171 |
+
// Build placeholder
|
1172 |
+
$ph[] = sprintf($ex->ph->template, $group, $idx);
|
1173 |
+
}
|
1174 |
+
unset($midx, $match);
|
1175 |
+
// Replace content with placeholder
|
1176 |
+
$content = str_replace($matches[0], $ph, $content);
|
1177 |
+
|
1178 |
+
// Cleanup
|
1179 |
+
unset($matches, $ph);
|
1180 |
+
}
|
1181 |
+
|
1182 |
+
return $content;
|
1183 |
+
}
|
1184 |
+
|
1185 |
+
/**
|
1186 |
+
* Exclude shortcodes from link activation
|
1187 |
+
* @param string $content Content to exclude shortcodes from
|
1188 |
+
* @return string Content with shortcodes excluded
|
1189 |
+
*/
|
1190 |
+
public function exclude_shortcodes($content) {
|
1191 |
+
// Get shortcodes to exclude
|
1192 |
+
$shortcodes = $this->util->apply_filters('exclude_shortcodes', array( $this->add_prefix('group') ));
|
1193 |
+
// Set callback
|
1194 |
+
$shortcodes = array_fill_keys($shortcodes, $this->m('exclude_shortcodes_handler'));
|
1195 |
+
return $this->util->do_shortcode($content, $shortcodes);
|
1196 |
+
}
|
1197 |
+
|
1198 |
+
/**
|
1199 |
+
* Wrap shortcode in exclude tags
|
1200 |
+
* @uses Util->make_shortcode() to rebuild original shortcode
|
1201 |
+
*
|
1202 |
+
* @param array $attr Shortcode attributes
|
1203 |
+
* @param string $content Content enclosed in shortcode
|
1204 |
+
* @param string $tag Shortcode name
|
1205 |
+
* @return string Excluded shortcode
|
1206 |
+
*/
|
1207 |
+
public function exclude_shortcodes_handler($attr, $content, $tag) {
|
1208 |
+
$code = $this->util->make_shortcode($tag, $attr, $content);
|
1209 |
+
// Exclude shortcode
|
1210 |
+
return $this->exclude_wrap($code);
|
1211 |
+
}
|
1212 |
+
|
1213 |
+
/**
|
1214 |
+
* Restore excluded content
|
1215 |
+
* @param string $content Content to restore excluded content to
|
1216 |
+
* @return string Content with excluded content restored
|
1217 |
+
*/
|
1218 |
+
public function restore_excluded_content($content, $group = null) {
|
1219 |
+
$ex = $this->get_exclude();
|
1220 |
+
// Setup cache
|
1221 |
+
if ( !is_string($group) || empty($group) ) {
|
1222 |
+
$group = $ex->group_default;
|
1223 |
+
}
|
1224 |
+
// Nothing to restore if cache group doesn't exist
|
1225 |
+
if ( !isset($ex->cache[$group]) ) {
|
1226 |
+
return $content;
|
1227 |
+
}
|
1228 |
+
$cache =& $ex->cache[$group];
|
1229 |
+
|
1230 |
+
// Search content for placeholders
|
1231 |
+
$matches = null;
|
1232 |
+
if ( false !== strpos($content, $ex->ph->open . $ex->ph->base) && preg_match_all($ex->ph->search, $content, $matches) ) {
|
1233 |
+
// Restore placeholders
|
1234 |
+
foreach ( $matches[1] as $idx => $ph ) {
|
1235 |
+
// Parse placeholder attributes
|
1236 |
+
$attrs = $this->util->parse_attribute_string($ph, $ex->ph->attrs);
|
1237 |
+
// Validate
|
1238 |
+
if ( $attrs['group'] !== $group ) {
|
1239 |
+
continue;
|
1240 |
+
}
|
1241 |
+
// Restore content
|
1242 |
+
$key = $attrs['key'] = intval($attrs['key']);
|
1243 |
+
if ( isset($cache[$key]) ) {
|
1244 |
+
$content = str_replace($matches[0][$idx], $cache[$key], $content);
|
1245 |
+
}
|
1246 |
+
}
|
1247 |
+
// Cleanup
|
1248 |
+
unset($idx, $ph, $matches, $key);
|
1249 |
+
}
|
1250 |
+
|
1251 |
+
return $content;
|
1252 |
+
}
|
1253 |
+
|
1254 |
+
/*-** Grouping **-*/
|
1255 |
+
|
1256 |
+
/**
|
1257 |
+
* Builds wrapper for grouping
|
1258 |
+
* @return string Format for wrapping content in group
|
1259 |
+
*/
|
1260 |
+
function group_get_wrapper() {
|
1261 |
+
static $fmt = null;
|
1262 |
+
if ( is_null($fmt) ) {
|
1263 |
+
$fmt = $this->util->make_shortcode($this->add_prefix('group'), null, '%s');
|
1264 |
+
}
|
1265 |
+
return $fmt;
|
1266 |
+
}
|
1267 |
+
|
1268 |
+
/**
|
1269 |
+
* Wraps shortcodes for automatic grouping
|
1270 |
+
* @uses `the_content` Filter hook
|
1271 |
+
* @uses group_shortcodes_handler to Wrap shortcodes for grouping
|
1272 |
+
* @param string $content Post content
|
1273 |
+
* @return string Modified post content
|
1274 |
+
*/
|
1275 |
+
function group_shortcodes($content) {
|
1276 |
+
if ( !$this->is_content_valid($content) ) {
|
1277 |
+
return $content;
|
1278 |
+
}
|
1279 |
+
// Setup shortcodes to wrap
|
1280 |
+
$shortcodes = $this->util->apply_filters('group_shortcodes', array( 'gallery', 'nggallery' ));
|
1281 |
+
// Set custom callback
|
1282 |
+
$shortcodes = array_fill_keys($shortcodes, $this->m('group_shortcodes_handler'));
|
1283 |
+
// Process gallery shortcodes
|
1284 |
+
return $this->util->do_shortcode($content, $shortcodes);
|
1285 |
+
}
|
1286 |
+
|
1287 |
+
/**
|
1288 |
+
* Groups shortcodes for later processing
|
1289 |
+
* @param array $attr Shortcode attributes
|
1290 |
+
* @param string $content Content enclosed in shortcode
|
1291 |
+
* @param string $tag Shortcode name
|
1292 |
+
* @return string Grouped shortcode
|
1293 |
+
*/
|
1294 |
+
function group_shortcodes_handler($attr, $content, $tag) {
|
1295 |
+
$code = $this->util->make_shortcode($tag, $attr, $content);
|
1296 |
+
// Wrap shortcode
|
1297 |
+
return sprintf( $this->group_get_wrapper(), $code);
|
1298 |
+
}
|
1299 |
+
|
1300 |
+
/**
|
1301 |
+
* Activate groups in content
|
1302 |
+
* @param string $content Content to activate
|
1303 |
+
* @return string Updated content
|
1304 |
+
*/
|
1305 |
+
public function activate_groups($content) {
|
1306 |
+
return $this->util->do_shortcode($content, array( $this->add_prefix('group') => $this->m('activate_groups_handler') ) );
|
1307 |
+
}
|
1308 |
+
|
1309 |
+
/**
|
1310 |
+
* Groups shortcodes for later processing
|
1311 |
+
* @param array $attr Shortcode attributes
|
1312 |
+
* @param string $content Content enclosed in shortcode
|
1313 |
+
* @param string $tag Shortcode name
|
1314 |
+
* @return string Grouped shortcode
|
1315 |
+
*/
|
1316 |
+
function activate_groups_handler($attr, $content, $tag) {
|
1317 |
+
// Get Group ID
|
1318 |
+
// Custom group
|
1319 |
+
if ( isset($attr['id']) ) {
|
1320 |
+
$group = $attr['id'];
|
1321 |
+
trim($group);
|
1322 |
+
}
|
1323 |
+
// Automatically-generated group
|
1324 |
+
if ( empty($group) ) {
|
1325 |
+
$group = 'auto_' . ++$this->groups['auto'];
|
1326 |
+
}
|
1327 |
+
return $this->process_links($content, $group);
|
1328 |
+
}
|
1329 |
+
|
1330 |
+
/*-** Widgets **-*/
|
1331 |
+
|
1332 |
+
/**
|
1333 |
+
* Set widget up for processing/activation
|
1334 |
+
* Buffers widget output for further processing
|
1335 |
+
* @param array $widget_args Widget arguments
|
1336 |
+
* @return void
|
1337 |
+
*/
|
1338 |
+
public function widget_process_start($widget_args) {
|
1339 |
+
// Do not continue if a widget is currently being processed (avoid nested processing)
|
1340 |
+
if ( 0 < $this->widget_processing_level ) {
|
1341 |
+
return;
|
1342 |
+
}
|
1343 |
+
// Start widget processing
|
1344 |
+
$this->widget_processing = true;
|
1345 |
+
$this->widget_processing_params = $widget_args;
|
1346 |
+
// Enable widget grouping
|
1347 |
+
if ( $this->options->get_bool('group_widget') ) {
|
1348 |
+
$this->util->add_filter('get_group_id', $this->m('widget_group_id'));
|
1349 |
+
}
|
1350 |
+
// Begin output buffer
|
1351 |
+
ob_start();
|
1352 |
+
}
|
1353 |
+
|
1354 |
+
/**
|
1355 |
+
* Handles inter-widget processing
|
1356 |
+
* After widget output generated, Before next widget starts
|
1357 |
+
* @param array $params New widget parameters
|
1358 |
+
*/
|
1359 |
+
public function widget_process_inter( $params ) {
|
1360 |
+
$this->widget_process_finish();
|
1361 |
+
return $params;
|
1362 |
+
}
|
1363 |
+
|
1364 |
+
/**
|
1365 |
+
* Complete widget processing
|
1366 |
+
* Activate widget output
|
1367 |
+
* @uses $widget_processing
|
1368 |
+
* @uses $widget_processing_level
|
1369 |
+
* @uses $widget_processing_params
|
1370 |
+
* @return void
|
1371 |
+
*/
|
1372 |
+
public function widget_process_finish() {
|
1373 |
+
/**
|
1374 |
+
* Stop processing on conditions:
|
1375 |
+
* - No widget is being processed
|
1376 |
+
* - Processing a nested widget
|
1377 |
+
*/
|
1378 |
+
if ( !$this->widget_processing || 0 < $this->widget_processing_level ) {
|
1379 |
+
return;
|
1380 |
+
}
|
1381 |
+
// Activate widget output
|
1382 |
+
$out = $this->activate_links(ob_get_clean());
|
1383 |
+
|
1384 |
+
// Clear grouping callback
|
1385 |
+
if ( $this->options->get_bool('group_widget') ) {
|
1386 |
+
$this->util->remove_filter('get_group_id', $this->m('widget_group_id'));
|
1387 |
+
}
|
1388 |
+
// End widget processing
|
1389 |
+
$this->widget_processing = false;
|
1390 |
+
$this->widget_processing_params = null;
|
1391 |
+
// Output widget
|
1392 |
+
echo $out;
|
1393 |
+
}
|
1394 |
+
|
1395 |
+
/**
|
1396 |
+
* Add widget ID to link group ID
|
1397 |
+
* Widget ID precedes all other group segments
|
1398 |
+
* @uses `SLB::get_group_id` filter
|
1399 |
+
* @param array $group_segments Group ID segments
|
1400 |
+
* @return array Modified group ID segments
|
1401 |
+
*/
|
1402 |
+
public function widget_group_id($group_segments) {
|
1403 |
+
// Add current widget ID to group ID
|
1404 |
+
if ( isset($this->widget_processing_params['id']) ) {
|
1405 |
+
array_unshift($group_segments, $this->widget_processing_params['id']);
|
1406 |
+
}
|
1407 |
+
return $group_segments;
|
1408 |
+
}
|
1409 |
+
|
1410 |
+
/**
|
1411 |
+
* Handles nested activation in widgets
|
1412 |
+
* @uses widget_processing
|
1413 |
+
* @uses $widget_processing_level
|
1414 |
+
* @return void
|
1415 |
+
*/
|
1416 |
+
public function widget_process_nested() {
|
1417 |
+
// Stop if no widget is being processed
|
1418 |
+
if ( !$this->widget_processing ) {
|
1419 |
+
return;
|
1420 |
+
}
|
1421 |
+
|
1422 |
+
// Increment nesting level
|
1423 |
+
$this->widget_processing_level++;
|
1424 |
+
}
|
1425 |
+
|
1426 |
+
/**
|
1427 |
+
* Mark the end of a nested widget
|
1428 |
+
* @uses $widget_processing_level
|
1429 |
+
*/
|
1430 |
+
public function widget_process_nested_finish() {
|
1431 |
+
// Decrement nesting level
|
1432 |
+
if ( 0 < $this->widget_processing_level ) {
|
1433 |
+
$this->widget_processing_level--;
|
1434 |
+
}
|
1435 |
+
}
|
1436 |
+
|
1437 |
+
/**
|
1438 |
+
* Begin blocking widget activation
|
1439 |
+
* @return void
|
1440 |
+
*/
|
1441 |
+
public function widget_block_start() {
|
1442 |
+
$this->util->add_filter('is_content_valid', $this->m('widget_block_handle'));
|
1443 |
+
}
|
1444 |
+
|
1445 |
+
/**
|
1446 |
+
* Stop blocking widget activation
|
1447 |
+
* @return void
|
1448 |
+
*/
|
1449 |
+
public function widget_block_finish() {
|
1450 |
+
$this->util->remove_filter('is_content_valid', $this->m('widget_block_handle'));
|
1451 |
+
}
|
1452 |
+
|
1453 |
+
/**
|
1454 |
+
* Handle widget activation blocking
|
1455 |
+
*/
|
1456 |
+
public function widget_block_handle($is_content_valid) {
|
1457 |
+
return false;
|
1458 |
+
}
|
1459 |
+
|
1460 |
+
/*-** Menus **-*/
|
1461 |
+
|
1462 |
+
/**
|
1463 |
+
* Process navigation menu links
|
1464 |
+
*
|
1465 |
+
* @see wp_nav_menu()/filter: wp_nav_menu
|
1466 |
+
*
|
1467 |
+
* @param string $nav_menu HTML content for navigation menu.
|
1468 |
+
* @param object $args Navigation menu's arguments.
|
1469 |
+
*/
|
1470 |
+
public function menu_process($nav_menu, $args) {
|
1471 |
+
// Grouping
|
1472 |
+
if ( $this->options->get_bool('group_menu') ) {
|
1473 |
+
// Generate group ID for menu
|
1474 |
+
$group = 'menu';
|
1475 |
+
$sep = '_';
|
1476 |
+
if ( !empty( $args->menu_id ) ) {
|
1477 |
+
$group .= $sep . $args->menu_id;
|
1478 |
+
} elseif ( !empty( $args->menu ) ) {
|
1479 |
+
$group .= $sep . ( ( is_object($args->menu) ) ? $args->menu->slug : $args->menu );
|
1480 |
+
}
|
1481 |
+
$group = $this->group_id_unique( $group );
|
1482 |
+
} else {
|
1483 |
+
$group = null;
|
1484 |
+
}
|
1485 |
+
|
1486 |
+
// Process menu
|
1487 |
+
$nav_menu = $this->activate_links($nav_menu, $group);
|
1488 |
+
|
1489 |
+
return $nav_menu;
|
1490 |
+
}
|
1491 |
+
|
1492 |
+
/**
|
1493 |
+
* Generate unique group ID
|
1494 |
+
*
|
1495 |
+
* @param string $group Group ID to check
|
1496 |
+
* @return string Unique group ID
|
1497 |
+
*/
|
1498 |
+
public function group_id_unique($group) {
|
1499 |
+
static $groups = array();
|
1500 |
+
while ( in_array($group, $groups) ) {
|
1501 |
+
$patt = '#-(\d+)$#';
|
1502 |
+
if ( preg_match( $patt, $group, $matches ) )
|
1503 |
+
$group = preg_replace($patt, '-' . ++$matches[1], $group );
|
1504 |
+
else
|
1505 |
+
$group = $group . '-1';
|
1506 |
+
}
|
1507 |
+
return $group;
|
1508 |
+
}
|
1509 |
+
|
1510 |
+
/*-** Helpers **-*/
|
1511 |
+
|
1512 |
+
/**
|
1513 |
+
* Build attribute name
|
1514 |
+
* Makes sure name is only prefixed once
|
1515 |
+
* @param string $name (optional) Attribute base name
|
1516 |
+
* @return string Formatted attribute name
|
1517 |
+
*/
|
1518 |
+
function make_attribute_name($name = '') {
|
1519 |
+
// Validate
|
1520 |
+
if ( !is_string($name) ) {
|
1521 |
+
$name = '';
|
1522 |
+
} else {
|
1523 |
+
$name = trim($name);
|
1524 |
+
}
|
1525 |
+
// Setup
|
1526 |
+
$sep = '-';
|
1527 |
+
$top = 'data';
|
1528 |
+
// Generate valid name
|
1529 |
+
if ( strpos($name, $top . $sep . $this->get_prefix()) !== 0 ) {
|
1530 |
+
$name = $top . $sep . $this->add_prefix($name, $sep);
|
1531 |
+
}
|
1532 |
+
return $name;
|
1533 |
+
}
|
1534 |
+
|
1535 |
+
/**
|
1536 |
+
* Set attribute to array
|
1537 |
+
* Attribute is added to array if it does not exist
|
1538 |
+
* @param array $attrs Array to add attribute to (Passed by reference)
|
1539 |
+
* @param string $name Name of attribute to add
|
1540 |
+
* @param string (optional) $value Attribute value
|
1541 |
+
* @return array Updated attribute array
|
1542 |
+
*/
|
1543 |
+
function set_attribute(&$attrs, $name, $value = true) {
|
1544 |
+
// Validate
|
1545 |
+
$attrs = $this->get_attributes($attrs, false);
|
1546 |
+
if ( !is_string($name) || empty($name) ) {
|
1547 |
+
return $attrs;
|
1548 |
+
}
|
1549 |
+
if ( !is_scalar($value) ) {
|
1550 |
+
$value = true;
|
1551 |
+
}
|
1552 |
+
// Add attribute
|
1553 |
+
$attrs = array_merge($attrs, array( $this->make_attribute_name($name) => strval($value) ));
|
1554 |
+
|
1555 |
+
return $attrs;
|
1556 |
+
}
|
1557 |
+
|
1558 |
+
/**
|
1559 |
+
* Convert attribute string into array
|
1560 |
+
* @param string $attr_string Attribute string
|
1561 |
+
* @param bool (optional) $internal Whether only internal attributes should be evaluated (Default: TRUE)
|
1562 |
+
* @return array Attributes as associative array
|
1563 |
+
*/
|
1564 |
+
function get_attributes($attr_string, $internal = true) {
|
1565 |
+
if ( is_string($attr_string) ) {
|
1566 |
+
$attr_string = $this->util->parse_attribute_string($attr_string);
|
1567 |
+
}
|
1568 |
+
$ret = ( is_array($attr_string) ) ? $attr_string : array();
|
1569 |
+
// Filter out external attributes
|
1570 |
+
if ( !empty($ret) && is_bool($internal) && $internal ) {
|
1571 |
+
$ret_f = array();
|
1572 |
+
foreach ( $ret as $key => $val ) {
|
1573 |
+
if ( strpos($key, $this->make_attribute_name()) == 0 ) {
|
1574 |
+
$ret_f[$key] = $val;
|
1575 |
+
}
|
1576 |
+
}
|
1577 |
+
if ( !empty($ret_f) ) {
|
1578 |
+
$ret = $ret_f;
|
1579 |
+
}
|
1580 |
+
}
|
1581 |
+
|
1582 |
+
return $ret;
|
1583 |
+
}
|
1584 |
+
|
1585 |
+
/**
|
1586 |
+
* Retrieve attribute value
|
1587 |
+
* @param string|array $attrs Attributes to retrieve attribute value from
|
1588 |
+
* @param string $attr Attribute name to retrieve
|
1589 |
+
* @param bool (optional) $internal Whether only internal attributes should be evaluated (Default: TRUE)
|
1590 |
+
* @return string|bool Attribute value (Default: FALSE)
|
1591 |
+
*/
|
1592 |
+
function get_attribute($attrs, $attr, $internal = true) {
|
1593 |
+
$ret = false;
|
1594 |
+
// Validate
|
1595 |
+
$attrs = $this->get_attributes($attrs, $internal);
|
1596 |
+
if ( $internal ) {
|
1597 |
+
$attr = $this->make_attribute_name($attr);
|
1598 |
+
}
|
1599 |
+
if ( isset($attrs[$attr]) ) {
|
1600 |
+
$ret = $attrs[$attr];
|
1601 |
+
}
|
1602 |
+
return $ret;
|
1603 |
+
}
|
1604 |
+
|
1605 |
+
/**
|
1606 |
+
* Checks if attribute exists
|
1607 |
+
* If supplied, the attribute's value is also validated
|
1608 |
+
* @param string|array $attrs Attributes to retrieve attribute value from
|
1609 |
+
* @param string $attr Attribute name to retrieve
|
1610 |
+
* @param mixed $value (optional) Attribute value to check for
|
1611 |
+
* @param bool $internal (optional) Whether to check only internal attributes (Default: TRUE)
|
1612 |
+
* @see get_attribute()
|
1613 |
+
* @return bool Whether or not attribute (with matching value if specified) exists
|
1614 |
+
*/
|
1615 |
+
function has_attribute($attrs, $attr, $value = null, $internal = true) {
|
1616 |
+
$a = $this->get_attribute($attrs, $attr, $internal);
|
1617 |
+
$ret = false;
|
1618 |
+
if ( $a !== false ) {
|
1619 |
+
$ret = true;
|
1620 |
+
// Check value
|
1621 |
+
if ( !is_null($value) ) {
|
1622 |
+
if ( is_string($value) ) {
|
1623 |
+
$ret = ( $a == strval($value) ) ? true : false;
|
1624 |
+
} elseif ( is_bool($value) ) {
|
1625 |
+
$ret = ( !!$a == $value ) ? true : false;
|
1626 |
+
} else {
|
1627 |
+
$ret = false;
|
1628 |
+
}
|
1629 |
+
}
|
1630 |
+
}
|
1631 |
+
return $ret;
|
1632 |
+
}
|
1633 |
+
|
1634 |
+
/**
|
1635 |
+
* Build JS object of UI strings when initializing lightbox
|
1636 |
+
* @return array UI strings
|
1637 |
+
*/
|
1638 |
+
private function build_labels() {
|
1639 |
+
$ret = array();
|
1640 |
+
/* Get all UI options */
|
1641 |
+
$prefix = 'txt_';
|
1642 |
+
$opt_strings = array_filter( array_keys( $this->options->get_items() ), function ( $opt ) use ( $prefix ) {
|
1643 |
+
return ( strpos( $opt, $prefix ) === 0 );
|
1644 |
+
} );
|
1645 |
+
if ( count( $opt_strings ) ) {
|
1646 |
+
/* Build array of UI options */
|
1647 |
+
foreach ( $opt_strings as $key ) {
|
1648 |
+
$name = substr( $key, strlen( $prefix ) );
|
1649 |
+
$ret[ $name ] = $this->options->get_value( $key );
|
1650 |
+
}
|
1651 |
+
}
|
1652 |
+
return $ret;
|
1653 |
+
}
|
1654 |
+
}
|
functions.php
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Functions
|
4 |
+
* Provides global access to specific functionality
|
5 |
+
* @package Simple Lightbox
|
6 |
+
* @author Archetyped
|
7 |
+
*/
|
8 |
+
|
9 |
+
/* Template Tags */
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Activate links in user-defined content
|
13 |
+
* @param string $content
|
14 |
+
* @return string Updated content with activated links
|
15 |
+
*/
|
16 |
+
function slb_activate($content, $group = null) {
|
17 |
+
// Validate
|
18 |
+
if ( empty($content) ) {
|
19 |
+
return $content;
|
20 |
+
}
|
21 |
+
// Activate links
|
22 |
+
$content = $GLOBALS['slb']->activate_links($content, $group);
|
23 |
+
return $content;
|
24 |
+
}
|
grunt/jshint.js
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module.exports = function(grunt) {
|
2 |
+
|
3 |
+
grunt.config('jshint', {
|
4 |
+
options : {
|
5 |
+
reporter: require('jshint-stylish'),
|
6 |
+
curly : true,
|
7 |
+
eqeqeq : true,
|
8 |
+
immed : true,
|
9 |
+
latedef : true,
|
10 |
+
newcap : false,
|
11 |
+
noarg : true,
|
12 |
+
sub : true,
|
13 |
+
undef : true,
|
14 |
+
unused : true,
|
15 |
+
boss : true,
|
16 |
+
eqnull : true,
|
17 |
+
browser : true,
|
18 |
+
jquery : true,
|
19 |
+
globals : {}
|
20 |
+
},
|
21 |
+
grunt : {
|
22 |
+
options : {
|
23 |
+
node : true
|
24 |
+
},
|
25 |
+
src : ['Gruntfile.js', 'grunt/*.js']
|
26 |
+
},
|
27 |
+
all : {
|
28 |
+
options : {
|
29 |
+
globals : {
|
30 |
+
'SLB' : true,
|
31 |
+
'console' : true
|
32 |
+
}
|
33 |
+
},
|
34 |
+
src : ['<%= paths.js.files %>']
|
35 |
+
},
|
36 |
+
});
|
37 |
+
|
38 |
+
};
|
grunt/phplint.js
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module.exports = function(grunt) {
|
2 |
+
|
3 |
+
grunt.config('phplint', {
|
4 |
+
options : {
|
5 |
+
phpArgs : {
|
6 |
+
'-lf': null
|
7 |
+
}
|
8 |
+
},
|
9 |
+
all : {
|
10 |
+
src : '<%= paths.php.files %>'
|
11 |
+
}
|
12 |
+
});
|
13 |
+
|
14 |
+
};
|
grunt/sass.js
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module.exports = function(grunt) {
|
2 |
+
|
3 |
+
grunt.config('sass', {
|
4 |
+
options : {
|
5 |
+
outputStyle : 'compressed',
|
6 |
+
},
|
7 |
+
core : {
|
8 |
+
files : [{
|
9 |
+
expand : true,
|
10 |
+
cwd : '<%= paths.sass.base_src %>/',
|
11 |
+
dest : '<%= paths.sass.base_dest %>/',
|
12 |
+
src : ['<%= paths.sass.target %>', '<%= paths.sass.exclude %>'],
|
13 |
+
ext : '<%= paths.sass.ext %>'
|
14 |
+
}]
|
15 |
+
},
|
16 |
+
themes : {
|
17 |
+
options : {
|
18 |
+
},
|
19 |
+
files : [{
|
20 |
+
expand : true,
|
21 |
+
cwd : 'themes/',
|
22 |
+
src : ['*/**/*.scss', '<%= paths.sass.exclude %>'],
|
23 |
+
dest : '<%= paths.sass.dest %>/',
|
24 |
+
srcd : '<%= paths.sass.src %>/',
|
25 |
+
ext : '<%= paths.sass.ext %>',
|
26 |
+
rename : function(dest, matchedSrcPath, options) {
|
27 |
+
var path = [options.cwd, matchedSrcPath.replace(options.srcd, dest)].join('');
|
28 |
+
return path;
|
29 |
+
}
|
30 |
+
}]
|
31 |
+
}
|
32 |
+
});
|
33 |
+
|
34 |
+
};
|
grunt/uglify.js
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module.exports = function(grunt) {
|
2 |
+
|
3 |
+
grunt.config('uglify', {
|
4 |
+
options : {
|
5 |
+
mangle: false,
|
6 |
+
report: 'min'
|
7 |
+
},
|
8 |
+
all : {
|
9 |
+
files : [{
|
10 |
+
expand : true,
|
11 |
+
cwd : '',
|
12 |
+
dest : '',
|
13 |
+
src : ['<%= paths.js.files %>'],
|
14 |
+
rename : function(dest, srcPath) {
|
15 |
+
return srcPath.replace('/' + grunt.config.get('paths.js.src') + '/', '/' + grunt.config.get('paths.js.dest') + '/');
|
16 |
+
}
|
17 |
+
}]
|
18 |
+
},
|
19 |
+
});
|
20 |
+
|
21 |
+
};
|
grunt/watch.js
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module.exports = function(grunt) {
|
2 |
+
|
3 |
+
grunt.config('watch', {
|
4 |
+
phplint : {
|
5 |
+
files : '<%= paths.php.files_std %>',
|
6 |
+
tasks : ['phplint'],
|
7 |
+
options : {
|
8 |
+
spawn : false
|
9 |
+
}
|
10 |
+
},
|
11 |
+
sass_core : {
|
12 |
+
files : ['<%= paths.sass.base_src %>/**/*.scss'],
|
13 |
+
tasks : ['sass:core']
|
14 |
+
},
|
15 |
+
sass_themes : {
|
16 |
+
files : ['themes/**/<%= paths.sass.src %>/**/*.scss'],
|
17 |
+
tasks : ['sass:themes']
|
18 |
+
},
|
19 |
+
jshint : {
|
20 |
+
files : '<%= paths.js.files_std %>',
|
21 |
+
tasks : ['jshint:all'],
|
22 |
+
options : {
|
23 |
+
spawn : false
|
24 |
+
}
|
25 |
+
},
|
26 |
+
js : {
|
27 |
+
files : '<%= paths.js.files_std %>',
|
28 |
+
tasks : ['jshint:all', 'uglify:all'],
|
29 |
+
options : {
|
30 |
+
spawn : false
|
31 |
+
}
|
32 |
+
}
|
33 |
+
});
|
34 |
+
|
35 |
+
grunt.event.on('watch', function(action, filepath) {
|
36 |
+
// Determine task based on filepath
|
37 |
+
var get_ext = function(path) {
|
38 |
+
var ret = '';
|
39 |
+
var i = path.lastIndexOf('.');
|
40 |
+
if ( -1 !== i && i <= path.length ) {
|
41 |
+
ret = path.substr(i + 1);
|
42 |
+
}
|
43 |
+
return ret;
|
44 |
+
};
|
45 |
+
switch ( get_ext(filepath) ) {
|
46 |
+
// PHP
|
47 |
+
case 'php' :
|
48 |
+
grunt.config('paths.php.files', [filepath]);
|
49 |
+
break;
|
50 |
+
// JavaScript
|
51 |
+
case 'js' :
|
52 |
+
grunt.config('paths.js.files', [filepath]);
|
53 |
+
break;
|
54 |
+
}
|
55 |
+
});
|
56 |
+
|
57 |
+
};
|
includes/class-requirements-check.php
ADDED
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Requirements Validation
|
4 |
+
*
|
5 |
+
* Used to ensure environment meets plugin requirements.
|
6 |
+
*
|
7 |
+
* @package Simple Lightbox
|
8 |
+
* @since 2.7.0
|
9 |
+
*/
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Plugin Requirements Validation class
|
13 |
+
*
|
14 |
+
* @since 2.7.0
|
15 |
+
*/
|
16 |
+
class SLB_Requirements_Check {
|
17 |
+
/**
|
18 |
+
* Plugin name
|
19 |
+
*
|
20 |
+
* @var string
|
21 |
+
*/
|
22 |
+
private $name = '';
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Plugin file
|
26 |
+
*
|
27 |
+
* @var string
|
28 |
+
*/
|
29 |
+
private $file = '';
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Plugin dependencies
|
33 |
+
*
|
34 |
+
* @var array
|
35 |
+
*/
|
36 |
+
private $deps = array(
|
37 |
+
'php' => '5.4',
|
38 |
+
);
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Dependency failures log
|
42 |
+
*
|
43 |
+
* @var array
|
44 |
+
*/
|
45 |
+
private $fail = array();
|
46 |
+
|
47 |
+
/**
|
48 |
+
* URIs for notices, etc.
|
49 |
+
*
|
50 |
+
* @var array
|
51 |
+
*/
|
52 |
+
private $uri = array();
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Constructor
|
56 |
+
*
|
57 |
+
* @param array $args Requirements data.
|
58 |
+
* @return void
|
59 |
+
*/
|
60 |
+
public function __construct( $args ) {
|
61 |
+
$args = (array) $args;
|
62 |
+
// Set properties.
|
63 |
+
foreach ( array_keys( get_class_vars( get_class( $this ) ) ) as $prop ) {
|
64 |
+
if ( ! isset( $args[ $prop ] ) ) {
|
65 |
+
continue;
|
66 |
+
}
|
67 |
+
// Merge array properties.
|
68 |
+
if ( is_array( $this->$prop ) && is_array( $args[ $prop ] ) ) {
|
69 |
+
$this->$prop = array_merge( $this->$prop, $args[ $prop ] );
|
70 |
+
continue;
|
71 |
+
}
|
72 |
+
|
73 |
+
// Set string properties.
|
74 |
+
if ( is_string( $this->$prop ) && is_scalar( $args[ $prop ] ) ) {
|
75 |
+
$this->$prop = (string) $args[ $prop ];
|
76 |
+
continue;
|
77 |
+
}
|
78 |
+
}
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Check if plugin passes all requirements
|
83 |
+
*
|
84 |
+
* @return bool Requirements check result.
|
85 |
+
*/
|
86 |
+
public function passes() {
|
87 |
+
$result = true;
|
88 |
+
foreach ( $this->deps as $dep => $req ) {
|
89 |
+
$m = $dep . '_passes';
|
90 |
+
if ( ! method_exists( $this, $m ) ) {
|
91 |
+
continue;
|
92 |
+
}
|
93 |
+
$passes = $this->$m();
|
94 |
+
if ( ! $passes ) {
|
95 |
+
// Requirements do not pass.
|
96 |
+
$result = $passes;
|
97 |
+
// Log dependency failures.
|
98 |
+
$this->fail[] = $dep;
|
99 |
+
}
|
100 |
+
}
|
101 |
+
// Handle requirements failure.
|
102 |
+
if ( ! $result ) {
|
103 |
+
add_action( 'load-plugins.php', array( $this, 'handle_failure' ) );
|
104 |
+
}
|
105 |
+
return $result;
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Handle requirements failure
|
110 |
+
*
|
111 |
+
* @return void
|
112 |
+
*/
|
113 |
+
public function handle_failure() {
|
114 |
+
// Handle each failed dependency.
|
115 |
+
foreach ( $this->fail as $dep ) {
|
116 |
+
$m = $dep . '_handle_failure';
|
117 |
+
if ( method_exists( $this, $m ) ) {
|
118 |
+
$this->$m();
|
119 |
+
}
|
120 |
+
}
|
121 |
+
// Deactivate plugin.
|
122 |
+
deactivate_plugins( plugin_basename( $this->file ) );
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Validates PHP version.
|
127 |
+
*
|
128 |
+
* @return bool PHP requirement passes.
|
129 |
+
*/
|
130 |
+
private function php_passes() {
|
131 |
+
return version_compare( PHP_VERSION, $this->deps['php'], '>=' );
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Handle PHP requirement failure
|
136 |
+
*
|
137 |
+
* @return void
|
138 |
+
*/
|
139 |
+
private function php_handle_failure() {
|
140 |
+
// Clear activation query variable from request (stop UI notices).
|
141 |
+
unset( $_GET['activate'] );
|
142 |
+
// Display notice to user.
|
143 |
+
add_action( 'admin_notices', array( $this, 'php_notice' ) );
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Display requirements failure notice and deactivate plugin.
|
148 |
+
*
|
149 |
+
* @return void
|
150 |
+
*/
|
151 |
+
public function php_notice() {
|
152 |
+
global $slb_requirements;
|
153 |
+
// Display message to user.
|
154 |
+
$link = (object) array(
|
155 |
+
/* translators: 1: Plugin name */
|
156 |
+
'title' => sprintf( __( 'Learn more about %1$s\'s requirements', 'simple-lightbox' ), $this->name ),
|
157 |
+
/* translators: Plugin requirements link text. */
|
158 |
+
'text' => __( 'Learn More', 'simple-lightbox' ),
|
159 |
+
);
|
160 |
+
// Full link.
|
161 |
+
$link = sprintf( '<a target="_blank" href="%1$s" title="%2$s">%3$s</a>', $this->uri['reference'], esc_attr( $link->title ), esc_html( $link->text ) );
|
162 |
+
/* translators: 1: Plugin name. 2: PHP version requirement. 3: Plugin requirements link. */
|
163 |
+
$err_msg = sprintf( __( '%1$s requires PHP %2$s or higher. Please have your hosting provider update PHP to enable Simple Lightbox. (%3$s)', 'simple-lightbox' ), $this->name, $this->deps['php'], $link );
|
164 |
+
?>
|
165 |
+
<div class="error"><p><?php echo $err_msg; ?></p></div>
|
166 |
+
<?php
|
167 |
+
}
|
168 |
+
}
|
includes/class.admin.php
CHANGED
@@ -11,24 +11,6 @@ class SLB_Admin extends SLB_Base {
|
|
11 |
|
12 |
protected $mode = 'sub';
|
13 |
|
14 |
-
/* Files */
|
15 |
-
|
16 |
-
var $scripts = array (
|
17 |
-
'admin' => array (
|
18 |
-
'file' => 'client/js/lib.admin.js',
|
19 |
-
'deps' => array('[core]'),
|
20 |
-
'context' => array( 'admin_page_slb_options' ),
|
21 |
-
'in_footer' => true,
|
22 |
-
),
|
23 |
-
);
|
24 |
-
|
25 |
-
var $styles = array (
|
26 |
-
'admin' => array (
|
27 |
-
'file' => 'client/css/admin.css',
|
28 |
-
'context' => array( 'admin_page_slb_options', 'admin_page_plugins' )
|
29 |
-
)
|
30 |
-
);
|
31 |
-
|
32 |
/* Properties */
|
33 |
|
34 |
/**
|
@@ -36,13 +18,17 @@ class SLB_Admin extends SLB_Base {
|
|
36 |
* Set on initialization
|
37 |
* @var obj
|
38 |
*/
|
39 |
-
|
40 |
|
41 |
/**
|
42 |
* Messages
|
43 |
* @var array
|
44 |
*/
|
45 |
-
|
|
|
|
|
|
|
|
|
46 |
|
47 |
/* Views */
|
48 |
|
@@ -53,7 +39,7 @@ class SLB_Admin extends SLB_Base {
|
|
53 |
* > Val: Menu properties
|
54 |
* @var array
|
55 |
*/
|
56 |
-
|
57 |
|
58 |
/**
|
59 |
* Custom admin pages
|
@@ -62,7 +48,7 @@ class SLB_Admin extends SLB_Base {
|
|
62 |
* > Val: Page properties
|
63 |
* @var array
|
64 |
*/
|
65 |
-
|
66 |
|
67 |
/**
|
68 |
* Custom admin sections
|
@@ -71,50 +57,79 @@ class SLB_Admin extends SLB_Base {
|
|
71 |
* > Val: Section properties
|
72 |
* @var array
|
73 |
*/
|
74 |
-
|
75 |
|
76 |
/**
|
77 |
-
*
|
78 |
-
*
|
79 |
* @var array
|
80 |
*/
|
81 |
-
|
82 |
|
83 |
/* Constructor */
|
84 |
|
85 |
-
|
86 |
-
* TODO Determine if $parent needed
|
87 |
-
*/
|
88 |
-
function __construct(&$parent) {
|
89 |
parent::__construct();
|
90 |
-
//Set parent
|
91 |
if ( is_object($parent) )
|
92 |
-
$this->parent
|
93 |
}
|
94 |
|
95 |
/* Init */
|
96 |
|
97 |
protected function _hooks() {
|
98 |
parent::_hooks();
|
99 |
-
//Init
|
100 |
add_action('admin_menu', $this->m('init_menus'), 11);
|
101 |
|
102 |
-
//
|
103 |
add_action('admin_action_' . $this->add_prefix('admin'), $this->m('handle_action'));
|
104 |
|
105 |
-
//Notices
|
106 |
add_action('admin_notices', $this->m('handle_notices'));
|
107 |
|
108 |
-
//Plugin listing
|
109 |
add_filter('plugin_action_links_' . $this->util->get_plugin_base_name(), $this->m('plugin_action_links'), 10, 4);
|
|
|
110 |
add_action('in_plugin_update_message-' . $this->util->get_plugin_base_name(), $this->m('plugin_update_message'), 10, 2);
|
111 |
add_filter('site_transient_update_plugins', $this->m('plugin_update_transient'));
|
112 |
}
|
113 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
/* Handlers */
|
115 |
|
116 |
-
|
117 |
-
|
|
|
|
|
|
|
118 |
$t = 'type';
|
119 |
$g = 'group';
|
120 |
$o = 'obj';
|
@@ -123,11 +138,11 @@ class SLB_Admin extends SLB_Base {
|
|
123 |
$this->add_prefix_ref($o);
|
124 |
$r =& $_REQUEST;
|
125 |
|
126 |
-
//Retrieve view that initiated the action
|
127 |
if ( isset($r[$t]) && 'view' == $r[$t] ) {
|
128 |
if ( isset($r[$g]) && ( $prop = $r[$g] . 's' ) && property_exists($this, $prop) && is_array($this->{$prop}) && isset($r[$o]) && isset($this->{$prop}[$r[$o]]) ) {
|
129 |
$view =& $this->{$prop}[$r[$o]];
|
130 |
-
//Pass request to view
|
131 |
$view->do_callback();
|
132 |
}
|
133 |
}
|
@@ -138,13 +153,13 @@ class SLB_Admin extends SLB_Base {
|
|
138 |
* Messages are localized upon display
|
139 |
* @uses `admin_notices` action hook to display messages
|
140 |
*/
|
141 |
-
function handle_notices() {
|
142 |
$msgs = $this->util->apply_filters('admin_messages', array());
|
143 |
foreach ( $msgs as $mid => $msg ) {
|
144 |
-
//Filter out empty messages
|
145 |
if ( empty($msg) )
|
146 |
continue;
|
147 |
-
//Build and display message
|
148 |
$mid = $this->add_prefix('msg_' . $mid);
|
149 |
?>
|
150 |
<div id="<?php echo esc_attr($mid); ?>" class="updated fade">
|
@@ -156,21 +171,6 @@ class SLB_Admin extends SLB_Base {
|
|
156 |
}
|
157 |
}
|
158 |
|
159 |
-
/**
|
160 |
-
* Displays notices for admin operations
|
161 |
-
*/
|
162 |
-
function show_notices() {
|
163 |
-
if ( is_admin() && isset($_REQUEST[$this->add_prefix('action')]) ) {
|
164 |
-
$action = $_REQUEST[$this->add_prefix('action')];
|
165 |
-
$msg = null;
|
166 |
-
if ( $action ) {
|
167 |
-
$msg = $this->get_message($action);
|
168 |
-
if ( ! empty($msg) ) {
|
169 |
-
|
170 |
-
}
|
171 |
-
}
|
172 |
-
}
|
173 |
-
}
|
174 |
/* Views */
|
175 |
|
176 |
/**
|
@@ -178,56 +178,45 @@ class SLB_Admin extends SLB_Base {
|
|
178 |
* Section is added to specified admin section/menu
|
179 |
* @uses `admin_init` hook
|
180 |
*/
|
181 |
-
function init_menus() {
|
182 |
-
//Add top level menus (when necessary)
|
183 |
-
/**
|
184 |
-
* @var SLB_Admin_Menu
|
185 |
-
*/
|
186 |
$menu;
|
187 |
foreach ( $this->menus as $menu ) {
|
188 |
-
//Register menu
|
189 |
$hook = add_menu_page($menu->get_label('title'), $menu->get_label('menu'), $menu->get_capability(), $menu->get_id(), $menu->get_callback());
|
190 |
-
//Add hook to menu object
|
191 |
$menu->set_hookname($hook);
|
192 |
$this->menus[$menu->get_id_raw()] =& $menu;
|
193 |
}
|
194 |
|
195 |
-
/**
|
196 |
-
* @var SLB_Admin_Page
|
197 |
-
*/
|
198 |
$page;
|
199 |
-
//Add subpages
|
200 |
foreach ( $this->pages as $page ) {
|
201 |
-
//Build Arguments
|
202 |
$args = array ( $page->get_label('header'), $page->get_label('menu'), $page->get_capability(), $page->get_id(), $page->get_callback() );
|
203 |
$f = null;
|
204 |
-
//Handle pages for default WP menus
|
205 |
if ( $page->is_parent_wp() ) {
|
206 |
$f = 'add_' . $page->get_parent() . '_page';
|
207 |
}
|
208 |
|
209 |
-
//Handle pages for custom menus
|
210 |
if ( ! function_exists($f) ) {
|
211 |
array_unshift( $args, $page->get_parent() );
|
212 |
$f = 'add_submenu_page';
|
213 |
}
|
214 |
|
215 |
-
//Add admin page
|
216 |
$hook = call_user_func_array($f, $args);
|
217 |
-
//Save hook to page properties
|
218 |
$page->set_hookname($hook);
|
219 |
$this->pages[$page->get_id_raw()] =& $page;
|
220 |
}
|
221 |
|
222 |
-
//Add sections
|
223 |
-
/**
|
224 |
-
* @var SLB_Admin_Section
|
225 |
-
*/
|
226 |
$section;
|
227 |
foreach ( $this->sections as $section ) {
|
228 |
add_settings_section($section->get_id(), $section->get_title(), $section->get_callback(), $section->get_parent());
|
229 |
-
if ( $section->is_options_valid() )
|
230 |
-
register_setting($section->get_parent(), $section->get_id(), $section->get_options()->m('validate'));
|
231 |
}
|
232 |
}
|
233 |
|
@@ -239,38 +228,40 @@ class SLB_Admin extends SLB_Base {
|
|
239 |
* @param string $type View type
|
240 |
* @param string $id Unique view ID
|
241 |
* @param array $args Arguments to pass to view constructor
|
242 |
-
* @return
|
243 |
*/
|
244 |
-
|
245 |
-
//Validate request
|
246 |
$class = $this->add_prefix('admin_' . $type);
|
247 |
$collection = $type . 's';
|
248 |
-
if ( !class_exists($class)
|
249 |
-
|
250 |
-
|
|
|
|
|
251 |
$r = new ReflectionClass($class);
|
252 |
-
$view
|
253 |
-
if ( $view->is_valid() )
|
254 |
$this->{$collection}[$id] =& $view;
|
255 |
-
|
256 |
-
|
257 |
-
unset($view, $r);
|
258 |
-
return $id;
|
259 |
}
|
260 |
|
261 |
/**
|
262 |
-
* Add
|
263 |
-
* @
|
264 |
-
* @param
|
265 |
-
*
|
266 |
-
* >
|
267 |
-
* >
|
268 |
-
* >
|
269 |
-
*
|
|
|
|
|
270 |
*/
|
271 |
-
function
|
272 |
$args = func_get_args();
|
273 |
-
return $this->add_view('
|
274 |
}
|
275 |
|
276 |
/*-** Menus **-*/
|
@@ -280,9 +271,9 @@ class SLB_Admin extends SLB_Base {
|
|
280 |
* @param string $id Menu ID
|
281 |
* @param string|array $labels Text labels
|
282 |
* @param int $pos (optional) Menu position in navigation (index order)
|
283 |
-
* @return
|
284 |
*/
|
285 |
-
function add_menu($id, $labels, $position = null) {
|
286 |
$args = array ( $id, $labels, null, null, null, $position );
|
287 |
return $this->add_view('menu', $id, $args);
|
288 |
}
|
@@ -293,19 +284,15 @@ class SLB_Admin extends SLB_Base {
|
|
293 |
* Add admin page
|
294 |
* @uses this->pages
|
295 |
* @param string $id Page ID (unique)
|
|
|
296 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
297 |
* > menu: Menu title
|
298 |
* > header: Page header
|
299 |
-
* @param string $menu Menu ID to add page to
|
300 |
-
* @param obj|array $options (optional) Options object (Use array to define options object & specific group(s))
|
301 |
-
* > Array Example: array($options, 'group_1') or array($options, array('group_1', 'group_3'))
|
302 |
-
* @param callback $callback (optional) Callback for custom page building
|
303 |
* @param string $capability (optional) Custom capability for accessing page
|
304 |
-
* @return
|
305 |
*/
|
306 |
-
function add_page($id, $parent, $labels, $
|
307 |
$args = func_get_args();
|
308 |
-
wp_enqueue_script('postbox');
|
309 |
return $this->add_view('page', $id, $args);
|
310 |
}
|
311 |
|
@@ -315,24 +302,21 @@ class SLB_Admin extends SLB_Base {
|
|
315 |
* Add admin page to a standard WP menu
|
316 |
* @uses this->add_page()
|
317 |
* @param string $id Page ID (unique)
|
|
|
318 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
319 |
* > menu: Menu title
|
320 |
* > header: Page header
|
321 |
-
* @param string $menu Name of WP menu to add page to
|
322 |
-
* @param obj|array $options (optional) Options object (Use array to define options object & specific group(s))
|
323 |
-
* > Array Example: array($options, 'group_1') or array($options, array('group_1', 'group_3'))
|
324 |
-
* @param callback $callback (optional) Callback for custom page building
|
325 |
* @param string $capability (optional) Custom capability for accessing page
|
326 |
-
* @return
|
327 |
-
*/
|
328 |
-
function add_wp_page($id, $parent, $labels, $
|
329 |
-
//Add page
|
330 |
-
$
|
331 |
-
//Set parent as WP
|
332 |
-
if ( $
|
333 |
-
$
|
334 |
}
|
335 |
-
return $
|
336 |
}
|
337 |
|
338 |
/**
|
@@ -341,15 +325,11 @@ class SLB_Admin extends SLB_Base {
|
|
341 |
* @uses this->add_wp_page()
|
342 |
* @param string $id Page ID (unique)
|
343 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
344 |
-
* @param obj|array $options (optional) Options object (Use array to define options object & specific group(s))
|
345 |
-
* > Array Example: array($options, 'group_1') or array($options, array('group_1', 'group_3'))
|
346 |
-
* @param callback $callback (optional) Callback for custom page building
|
347 |
* @param string $capability (optional) Custom capability for accessing page
|
348 |
-
* @return
|
349 |
*/
|
350 |
-
function add_dashboard_page($id, $labels, $
|
351 |
-
|
352 |
-
return $id;
|
353 |
}
|
354 |
|
355 |
/**
|
@@ -358,15 +338,11 @@ class SLB_Admin extends SLB_Base {
|
|
358 |
* @uses this->add_wp_page()
|
359 |
* @param string $id Page ID (unique)
|
360 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
361 |
-
* @param obj|array $options (optional) Options object (Use array to define options object & specific group(s))
|
362 |
-
* > Array Example: array($options, 'group_1') or array($options, array('group_1', 'group_3'))
|
363 |
-
* @param callback $callback (optional) Callback for custom page building
|
364 |
* @param string $capability (optional) Custom capability for accessing page
|
365 |
* @return string Page ID
|
366 |
*/
|
367 |
-
function add_comments_page($id, $labels, $
|
368 |
-
|
369 |
-
return $id;
|
370 |
}
|
371 |
|
372 |
/**
|
@@ -375,15 +351,11 @@ class SLB_Admin extends SLB_Base {
|
|
375 |
* @uses this->add_wp_page()
|
376 |
* @param string $id Page ID (unique)
|
377 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
378 |
-
* @param obj|array $options (optional) Options object (Use array to define options object & specific group(s))
|
379 |
-
* > Array Example: array($options, 'group_1') or array($options, array('group_1', 'group_3'))
|
380 |
-
* @param callback $callback (optional) Callback for custom page building
|
381 |
* @param string $capability (optional) Custom capability for accessing page
|
382 |
* @return string Page ID
|
383 |
*/
|
384 |
-
function add_links_page($id, $labels, $
|
385 |
-
|
386 |
-
return $id;
|
387 |
}
|
388 |
|
389 |
|
@@ -393,15 +365,11 @@ class SLB_Admin extends SLB_Base {
|
|
393 |
* @uses this->add_wp_page()
|
394 |
* @param string $id Page ID (unique)
|
395 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
396 |
-
* @param obj|array $options (optional) Options object (Use array to define options object & specific group(s))
|
397 |
-
* > Array Example: array($options, 'group_1') or array($options, array('group_1', 'group_3'))
|
398 |
-
* @param callback $callback (optional) Callback for custom page building
|
399 |
* @param string $capability (optional) Custom capability for accessing page
|
400 |
* @return string Page ID
|
401 |
*/
|
402 |
-
function add_posts_page($id, $labels, $
|
403 |
-
|
404 |
-
return $id;
|
405 |
}
|
406 |
|
407 |
/**
|
@@ -410,15 +378,11 @@ class SLB_Admin extends SLB_Base {
|
|
410 |
* @uses this->add_wp_page()
|
411 |
* @param string $id Page ID (unique)
|
412 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
413 |
-
* @param obj|array $options (optional) Options object (Use array to define options object & specific group(s))
|
414 |
-
* > Array Example: array($options, 'group_1') or array($options, array('group_1', 'group_3'))
|
415 |
-
* @param callback $callback (optional) Callback for custom page building
|
416 |
* @param string $capability (optional) Custom capability for accessing page
|
417 |
* @return string Page ID
|
418 |
*/
|
419 |
-
function add_pages_page($id, $labels, $
|
420 |
-
|
421 |
-
return $id;
|
422 |
}
|
423 |
|
424 |
/**
|
@@ -427,15 +391,11 @@ class SLB_Admin extends SLB_Base {
|
|
427 |
* @uses this->add_wp_page()
|
428 |
* @param string $id Page ID (unique)
|
429 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
430 |
-
* @param obj|array $options (optional) Options object (Use array to define options object & specific group(s))
|
431 |
-
* > Array Example: array($options, 'group_1') or array($options, array('group_1', 'group_3'))
|
432 |
-
* @param callback $callback (optional) Callback for custom page building
|
433 |
* @param string $capability (optional) Custom capability for accessing page
|
434 |
* @return string Page ID
|
435 |
*/
|
436 |
-
function add_media_page($id, $labels, $
|
437 |
-
|
438 |
-
return $id;
|
439 |
}
|
440 |
|
441 |
/**
|
@@ -444,15 +404,11 @@ class SLB_Admin extends SLB_Base {
|
|
444 |
* @uses this->add_wp_page()
|
445 |
* @param string $id Page ID (unique)
|
446 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
447 |
-
* @param obj|array $options (optional) Options object (Use array to define options object & specific group(s))
|
448 |
-
* > Array Example: array($options, 'group_1') or array($options, array('group_1', 'group_3'))
|
449 |
-
* @param callback $callback (optional) Callback for custom page building
|
450 |
* @param string $capability (optional) Custom capability for accessing page
|
451 |
* @return string Page ID
|
452 |
*/
|
453 |
-
function add_theme_page($id, $labels, $
|
454 |
-
|
455 |
-
return $id;
|
456 |
}
|
457 |
|
458 |
/**
|
@@ -461,15 +417,11 @@ class SLB_Admin extends SLB_Base {
|
|
461 |
* @uses this->add_wp_page()
|
462 |
* @param string $id Page ID (unique)
|
463 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
464 |
-
* @param obj|array $options (optional) Options object (Use array to define options object & specific group(s))
|
465 |
-
* > Array Example: array($options, 'group_1') or array($options, array('group_1', 'group_3'))
|
466 |
-
* @param callback $callback (optional) Callback for custom page building
|
467 |
* @param string $capability (optional) Custom capability for accessing page
|
468 |
* @return string Page ID
|
469 |
*/
|
470 |
-
function add_plugins_page($id, $labels, $
|
471 |
-
|
472 |
-
return $id;
|
473 |
}
|
474 |
|
475 |
/**
|
@@ -478,15 +430,11 @@ class SLB_Admin extends SLB_Base {
|
|
478 |
* @uses this->add_wp_page()
|
479 |
* @param string $id Page ID (unique)
|
480 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
481 |
-
* @param obj|array $options (optional) Options object (Use array to define options object & specific group(s))
|
482 |
-
* > Array Example: array($options, 'group_1') or array($options, array('group_1', 'group_3'))
|
483 |
-
* @param callback $callback (optional) Callback for custom page building
|
484 |
* @param string $capability (optional) Custom capability for accessing page
|
485 |
* @return string Page ID
|
486 |
*/
|
487 |
-
function add_options_page($id, $labels, $
|
488 |
-
|
489 |
-
return $id;
|
490 |
}
|
491 |
|
492 |
/**
|
@@ -495,15 +443,11 @@ class SLB_Admin extends SLB_Base {
|
|
495 |
* @uses this->add_wp_page()
|
496 |
* @param string $id Page ID (unique)
|
497 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
498 |
-
* @param obj|array $options (optional) Options object (Use array to define options object & specific group(s))
|
499 |
-
* > Array Example: array($options, 'group_1') or array($options, array('group_1', 'group_3'))
|
500 |
-
* @param callback $callback (optional) Callback for custom page building
|
501 |
* @param string $capability (optional) Custom capability for accessing page
|
502 |
* @return string Page ID
|
503 |
*/
|
504 |
-
function add_management_page($id, $labels, $
|
505 |
-
|
506 |
-
return $id;
|
507 |
}
|
508 |
|
509 |
/**
|
@@ -511,15 +455,11 @@ class SLB_Admin extends SLB_Base {
|
|
511 |
* @uses this->add_wp_page()
|
512 |
* @param string $id Page ID (unique)
|
513 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
514 |
-
* @param obj|array $options (optional) Options object (Use array to define options object & specific group(s))
|
515 |
-
* > Array Example: array($options, 'group_1') or array($options, array('group_1', 'group_3'))
|
516 |
-
* @param callback $callback (optional) Callback for custom page building
|
517 |
* @param string $capability (optional) Custom capability for accessing page
|
518 |
* @return string Page ID
|
519 |
*/
|
520 |
-
function add_users_page($id, $labels, $
|
521 |
-
|
522 |
-
return $id;
|
523 |
}
|
524 |
|
525 |
/* Section */
|
@@ -530,20 +470,17 @@ class SLB_Admin extends SLB_Base {
|
|
530 |
* @param string $id Unique section ID
|
531 |
* @param string $page Page ID
|
532 |
* @param string $labels Label text
|
533 |
-
* @
|
534 |
-
* > Array Example: array($options, 'group_1') or array($options, array('group_1', 'group_3'))
|
535 |
-
* @param callback $callback (optional) Callback for custom building
|
536 |
-
* @return string Section ID
|
537 |
*/
|
538 |
-
function add_section($id, $parent, $labels
|
539 |
-
$
|
|
|
540 |
|
541 |
-
//Add Section
|
542 |
if ( $section->is_valid() )
|
543 |
-
$this->sections[$id]
|
544 |
-
|
545 |
-
|
546 |
-
return $id;
|
547 |
}
|
548 |
|
549 |
/* Operations */
|
@@ -556,9 +493,9 @@ class SLB_Admin extends SLB_Base {
|
|
556 |
* @param $plugin_data
|
557 |
* @param $context
|
558 |
*/
|
559 |
-
function plugin_action_links($actions, $plugin_file, $plugin_data, $context) {
|
560 |
global $admin_page_hooks;
|
561 |
-
//Add link to settings (only if active)
|
562 |
if ( is_plugin_active($this->util->get_plugin_base_name()) ) {
|
563 |
/* Get Actions */
|
564 |
|
@@ -579,33 +516,55 @@ class SLB_Admin extends SLB_Base {
|
|
579 |
}
|
580 |
}
|
581 |
|
582 |
-
/* Get
|
583 |
$type = 'title';
|
584 |
-
foreach ( $this->
|
585 |
-
if ( !$
|
586 |
continue;
|
587 |
-
$id = '
|
588 |
$acts[] = (object) array (
|
589 |
-
'id'
|
590 |
-
'label'
|
591 |
-
'uri'
|
592 |
-
'attributes' => $
|
593 |
);
|
594 |
}
|
|
|
595 |
|
596 |
-
//Add links
|
597 |
$links = array();
|
598 |
foreach ( $acts as $act ) {
|
599 |
$links[$act->id] = $this->util->build_html_link($act->uri, $act->label, $act->attributes);
|
600 |
}
|
601 |
|
602 |
-
//Add links
|
603 |
$actions = array_merge($links, $actions);
|
604 |
}
|
605 |
return $actions;
|
606 |
}
|
607 |
-
|
608 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
609 |
|
610 |
/**
|
611 |
* Adds additional message for plugin updates
|
@@ -614,7 +573,7 @@ class SLB_Admin extends SLB_Base {
|
|
614 |
* @var array $plugin_data Current plugin data
|
615 |
* @var object $r Update response data
|
616 |
*/
|
617 |
-
function plugin_update_message($plugin_data, $r) {
|
618 |
if ( !isset($r->new_version) )
|
619 |
return false;
|
620 |
if ( stripos($r->new_version, 'beta') !== false ) {
|
@@ -630,7 +589,7 @@ class SLB_Admin extends SLB_Base {
|
|
630 |
* @param obj $transient Transient data
|
631 |
* @return obj Modified transient data
|
632 |
*/
|
633 |
-
function plugin_update_transient($transient) {
|
634 |
$n = $this->util->get_plugin_base_name();
|
635 |
if ( isset($transient->response) && isset($transient->response[$n]) && is_object($transient->response[$n]) && !isset($transient->response[$n]->upgrade_notice) ) {
|
636 |
$r =& $transient->response[$n];
|
@@ -645,7 +604,7 @@ class SLB_Admin extends SLB_Base {
|
|
645 |
* @param obj $r Response data from plugin update API
|
646 |
* @return string Message (Default: empty string)
|
647 |
*/
|
648 |
-
function plugin_update_get_message($r) {
|
649 |
$msg = '';
|
650 |
$cls_notice = $this->add_prefix('notice');
|
651 |
if ( !is_object($r) || !isset($r->new_version) )
|
@@ -663,7 +622,7 @@ class SLB_Admin extends SLB_Base {
|
|
663 |
* @param string $msg_id Message ID
|
664 |
* @return string Message text
|
665 |
*/
|
666 |
-
function get_message($msg_id) {
|
667 |
$msg = '';
|
668 |
$msgs = $this->get_messages();
|
669 |
if ( is_string($msg_id) && isset($msgs[$msg_id]) ) {
|
@@ -680,7 +639,7 @@ class SLB_Admin extends SLB_Base {
|
|
680 |
*/
|
681 |
function get_messages() {
|
682 |
if ( empty($this->messages) ) {
|
683 |
-
//Initialize messages if necessary
|
684 |
$this->messages = array(
|
685 |
'reset' => __('The settings have been reset', 'simple-lightbox'),
|
686 |
'beta' => __('<strong class="%1$s">Notice:</strong> This update is a <strong class="%1$s">Beta version</strong>. It is highly recommended that you test the update on a test server before updating the plugin on a production server.', 'simple-lightbox'),
|
@@ -696,881 +655,7 @@ class SLB_Admin extends SLB_Base {
|
|
696 |
* @param string $id Message ID
|
697 |
* @param string $text Message text
|
698 |
*/
|
699 |
-
function set_message($id, $text) {
|
700 |
$this->messages[trim($id)] = $text;
|
701 |
}
|
702 |
-
|
703 |
-
|
704 |
-
}
|
705 |
-
|
706 |
-
/**
|
707 |
-
* Admin View Base functionality
|
708 |
-
* Core functionality for Menus/Pages/Sections
|
709 |
-
* @package Simple Lightbox
|
710 |
-
* @subpackage Admin
|
711 |
-
* @author Archetyped
|
712 |
-
*/
|
713 |
-
class SLB_Admin_View extends SLB_Base {
|
714 |
-
/* Properties */
|
715 |
-
|
716 |
-
/**
|
717 |
-
* Unique ID
|
718 |
-
* @var string
|
719 |
-
*/
|
720 |
-
var $id = null;
|
721 |
-
|
722 |
-
/**
|
723 |
-
* Labels
|
724 |
-
* @var array (Associative)
|
725 |
-
*/
|
726 |
-
var $labels = array();
|
727 |
-
|
728 |
-
/**
|
729 |
-
* Options object to use
|
730 |
-
* @var SLB_Options
|
731 |
-
*/
|
732 |
-
var $options = null;
|
733 |
-
|
734 |
-
/**
|
735 |
-
* Option groups to use
|
736 |
-
* If empty, use entire options object
|
737 |
-
* @var array
|
738 |
-
*/
|
739 |
-
var $option_groups = array();
|
740 |
-
|
741 |
-
/**
|
742 |
-
* Option building arguments
|
743 |
-
* @var array
|
744 |
-
*/
|
745 |
-
var $option_args = array();
|
746 |
-
|
747 |
-
/**
|
748 |
-
* Function to handle building UI
|
749 |
-
* @var callback
|
750 |
-
*/
|
751 |
-
var $callback = null;
|
752 |
-
|
753 |
-
/**
|
754 |
-
* Capability for access control
|
755 |
-
* @var string
|
756 |
-
*/
|
757 |
-
var $capability = 'manage_options';
|
758 |
-
|
759 |
-
/**
|
760 |
-
* Icon to use
|
761 |
-
* @var string
|
762 |
-
*/
|
763 |
-
var $icon = null;
|
764 |
-
|
765 |
-
/**
|
766 |
-
* View parent ID/Slug
|
767 |
-
* @var string
|
768 |
-
*/
|
769 |
-
var $parent = null;
|
770 |
-
|
771 |
-
/**
|
772 |
-
* Whether parent is a custom view or a default WP one
|
773 |
-
* @var bool
|
774 |
-
*/
|
775 |
-
var $parent_custom = true;
|
776 |
-
|
777 |
-
/**
|
778 |
-
* If view requires a parent
|
779 |
-
* @var bool
|
780 |
-
*/
|
781 |
-
var $parent_required = false;
|
782 |
-
|
783 |
-
/**
|
784 |
-
* WP-Generated hook name for view
|
785 |
-
* @var string
|
786 |
-
*/
|
787 |
-
var $hookname = null;
|
788 |
-
|
789 |
-
/**
|
790 |
-
* Messages to be displayed
|
791 |
-
* Indexed Array
|
792 |
-
* @var array
|
793 |
-
*/
|
794 |
-
var $messages = array();
|
795 |
-
|
796 |
-
/**
|
797 |
-
* Required properties
|
798 |
-
* Associative array
|
799 |
-
* > Key: Property name
|
800 |
-
* > Value: Required data type
|
801 |
-
* @var array
|
802 |
-
*/
|
803 |
-
protected $required = array();
|
804 |
-
|
805 |
-
/**
|
806 |
-
* Default required properties
|
807 |
-
* Merged into $required array with this->init_required()
|
808 |
-
* @see this->required for more information
|
809 |
-
* @var array
|
810 |
-
*/
|
811 |
-
protected $_required = array ( 'id' => 'string', 'labels' => 'array' );
|
812 |
-
|
813 |
-
/* Init */
|
814 |
-
|
815 |
-
function __construct($id, $labels, $options = null, $callback = null, $capability = null, $icon = null) {
|
816 |
-
parent::__construct();
|
817 |
-
|
818 |
-
$this->init_required();
|
819 |
-
$this->set_id($id);
|
820 |
-
$this->set_labels($labels);
|
821 |
-
$this->set_options($options);
|
822 |
-
$this->set_callback($callback);
|
823 |
-
$this->set_capability($capability);
|
824 |
-
$this->set_icon($icon);
|
825 |
-
}
|
826 |
-
|
827 |
-
function init_required() {
|
828 |
-
$this->required = array_merge($this->_required, $this->required);
|
829 |
-
//Check for parent requirement
|
830 |
-
if ( $this->parent_required )
|
831 |
-
$this->required['parent'] = 'string';
|
832 |
-
}
|
833 |
-
|
834 |
-
/* Property Methods */
|
835 |
-
|
836 |
-
/**
|
837 |
-
* Retrieve ID (Formatted by default)
|
838 |
-
* @param bool $formatted (optional) Whether ID should be formatted for external use or not
|
839 |
-
* @return string ID
|
840 |
-
*/
|
841 |
-
function get_id($formatted = true) {
|
842 |
-
$id = $this->id;
|
843 |
-
if ( $formatted )
|
844 |
-
$this->add_prefix_ref($id);
|
845 |
-
return $id;
|
846 |
-
}
|
847 |
-
|
848 |
-
/**
|
849 |
-
* Retrieve raw ID
|
850 |
-
* @return string Raw ID
|
851 |
-
*/
|
852 |
-
function get_id_raw() {
|
853 |
-
return $this->get_id(false);
|
854 |
-
}
|
855 |
-
|
856 |
-
/**
|
857 |
-
* Set ID
|
858 |
-
* @param string ID
|
859 |
-
*/
|
860 |
-
function set_id($id) {
|
861 |
-
if ( is_scalar($id) ) {
|
862 |
-
$this->id = trim(strval($id));
|
863 |
-
return true;
|
864 |
-
}
|
865 |
-
return false;
|
866 |
-
}
|
867 |
-
|
868 |
-
/**
|
869 |
-
* Retrieve label
|
870 |
-
* Uses first label (or default if defined) if specified type does not exist
|
871 |
-
* @param string $type Label type to retrieve
|
872 |
-
* @param string $default (optional) Default value if label type does not exist
|
873 |
-
* @return string Label text
|
874 |
-
*/
|
875 |
-
function get_label($type, $default = null) {
|
876 |
-
//Retrieve existing label type
|
877 |
-
if ( $this->has_label($type) )
|
878 |
-
return $this->labels[$type];
|
879 |
-
//Use default label if type is not set
|
880 |
-
if ( empty($default) && !empty($this->labels) ) {
|
881 |
-
reset($this->labels);
|
882 |
-
$default = current($this->labels);
|
883 |
-
}
|
884 |
-
|
885 |
-
return ( empty($default) ) ? '' : $default;
|
886 |
-
}
|
887 |
-
|
888 |
-
/**
|
889 |
-
* Set text labels
|
890 |
-
* @param array|string $labels
|
891 |
-
*/
|
892 |
-
function set_labels($labels) {
|
893 |
-
if ( empty($labels) )
|
894 |
-
return false;
|
895 |
-
//Single string
|
896 |
-
if ( is_string($labels) ) {
|
897 |
-
$labels = array ( $labels );
|
898 |
-
}
|
899 |
-
|
900 |
-
//Array
|
901 |
-
if ( is_array($labels) ) {
|
902 |
-
//Merge with existing labels
|
903 |
-
if ( empty($this->labels) || !is_array($this->labels) ) {
|
904 |
-
$this->labels = array();
|
905 |
-
}
|
906 |
-
$this->labels = array_merge($this->labels, $labels);
|
907 |
-
}
|
908 |
-
}
|
909 |
-
|
910 |
-
/**
|
911 |
-
* Set single text label
|
912 |
-
* @uses this->set_labels()
|
913 |
-
* @param string $type Label type to set
|
914 |
-
* @param string $value Label value
|
915 |
-
*/
|
916 |
-
function set_label($type, $value) {
|
917 |
-
if ( is_string($type) && is_string($value) ) {
|
918 |
-
$label = array( $type => $value );
|
919 |
-
$this->set_labels($label);
|
920 |
-
}
|
921 |
-
}
|
922 |
-
|
923 |
-
/**
|
924 |
-
* Checks if specified label is set on view
|
925 |
-
* @param string $type Label type
|
926 |
-
* @return bool TRUE if label exists, FALSE otherwise
|
927 |
-
*/
|
928 |
-
function has_label($type) {
|
929 |
-
return ( isset($this->labels[$type]) );
|
930 |
-
}
|
931 |
-
|
932 |
-
/**
|
933 |
-
* Retrieve instance options
|
934 |
-
* @return SLB_Options Options instance
|
935 |
-
*/
|
936 |
-
function &get_options() {
|
937 |
-
return $this->options;
|
938 |
-
}
|
939 |
-
|
940 |
-
/**
|
941 |
-
* Set options object
|
942 |
-
* @param obj|array $options Options instance
|
943 |
-
* > If array, Options instance and specific groups are specified
|
944 |
-
* > 0: Options instance
|
945 |
-
* > 1: Group(s)
|
946 |
-
*/
|
947 |
-
function set_options($options) {
|
948 |
-
if ( empty($options) )
|
949 |
-
return false;
|
950 |
-
|
951 |
-
$groups = null;
|
952 |
-
|
953 |
-
if ( is_array($options) ) {
|
954 |
-
$options = array_values($options);
|
955 |
-
//Set option groups
|
956 |
-
if ( isset($options[1]) ) {
|
957 |
-
$groups = $options[1];
|
958 |
-
}
|
959 |
-
//Set options object
|
960 |
-
$options =& $options[0];
|
961 |
-
}
|
962 |
-
|
963 |
-
if ( $this->util->is_a($options, 'Options') ) {
|
964 |
-
//Save options
|
965 |
-
$this->options =& $options;
|
966 |
-
|
967 |
-
//Save option groups for valid options
|
968 |
-
$this->set_option_groups($groups);
|
969 |
-
}
|
970 |
-
}
|
971 |
-
|
972 |
-
/**
|
973 |
-
* Set option groups
|
974 |
-
* @param string|array $groups Specified group(s)
|
975 |
-
*/
|
976 |
-
function set_option_groups($groups) {
|
977 |
-
if ( empty($groups) )
|
978 |
-
return false;
|
979 |
-
|
980 |
-
//Validate data
|
981 |
-
if ( !is_array($groups) ) {
|
982 |
-
if ( is_scalar($groups) ) {
|
983 |
-
$groups = array(strval($groups));
|
984 |
-
}
|
985 |
-
}
|
986 |
-
|
987 |
-
if ( is_array($groups) ) {
|
988 |
-
$this->option_groups = $groups;
|
989 |
-
}
|
990 |
-
}
|
991 |
-
|
992 |
-
/**
|
993 |
-
* Retrieve view messages
|
994 |
-
* @return array Messages
|
995 |
-
*/
|
996 |
-
function &get_messages() {
|
997 |
-
if ( !is_array($this->messages) )
|
998 |
-
$this->messages = array();
|
999 |
-
return $this->messages;
|
1000 |
-
}
|
1001 |
-
|
1002 |
-
/**
|
1003 |
-
* Save message
|
1004 |
-
* @param string $text Message text
|
1005 |
-
*/
|
1006 |
-
function set_message($text) {
|
1007 |
-
$msgs =& $this->get_messages();
|
1008 |
-
$text = trim($text);
|
1009 |
-
if ( empty($msgs) && !empty($text) )
|
1010 |
-
$this->util->add_filter('admin_messages', $this->m('do_messages'));
|
1011 |
-
$msgs[] = $text;
|
1012 |
-
}
|
1013 |
-
|
1014 |
-
/**
|
1015 |
-
* Add messages to array
|
1016 |
-
* Called by internal `admin_messages` filter hook
|
1017 |
-
* @param array $msgs Aggregated messages
|
1018 |
-
* @return array Merged messages array
|
1019 |
-
*/
|
1020 |
-
function do_messages($msgs = array()) {
|
1021 |
-
$m =& $this->get_messages();
|
1022 |
-
if ( !empty($m) )
|
1023 |
-
$msgs = array_merge($msgs, $m);
|
1024 |
-
return $msgs;
|
1025 |
-
}
|
1026 |
-
|
1027 |
-
/**
|
1028 |
-
* Retrieve view callback
|
1029 |
-
* @return callback Callback
|
1030 |
-
*/
|
1031 |
-
function get_callback() {
|
1032 |
-
return ( $this->has_callback() ) ? $this->callback : $this->m('handle');
|
1033 |
-
}
|
1034 |
-
|
1035 |
-
/**
|
1036 |
-
* Set callback function for building item
|
1037 |
-
* @param callback $callback Callback function to use
|
1038 |
-
*/
|
1039 |
-
function set_callback($callback) {
|
1040 |
-
if ( is_callable($callback) )
|
1041 |
-
$this->callback = $callback;
|
1042 |
-
}
|
1043 |
-
|
1044 |
-
function has_callback() {
|
1045 |
-
return ( !empty($this->callback) ) ? true : false;
|
1046 |
-
}
|
1047 |
-
|
1048 |
-
function do_callback() {
|
1049 |
-
call_user_func($this->get_callback());
|
1050 |
-
}
|
1051 |
-
|
1052 |
-
/**
|
1053 |
-
* Retrieve capability
|
1054 |
-
* @return string Capability
|
1055 |
-
*/
|
1056 |
-
function get_capability() {
|
1057 |
-
return $this->capability;
|
1058 |
-
}
|
1059 |
-
|
1060 |
-
/**
|
1061 |
-
* Set capability for access control
|
1062 |
-
* @param string $capability Capability
|
1063 |
-
*/
|
1064 |
-
function set_capability($capability) {
|
1065 |
-
if ( is_string($capability) && !empty($capability) )
|
1066 |
-
$this->capability = $capability;
|
1067 |
-
}
|
1068 |
-
|
1069 |
-
/**
|
1070 |
-
* Set icon
|
1071 |
-
* @param string $icon Icon URI
|
1072 |
-
*/
|
1073 |
-
function set_icon($icon) {
|
1074 |
-
if ( !empty($icon) && is_string($icon) )
|
1075 |
-
$this->icon = $icon;
|
1076 |
-
}
|
1077 |
-
|
1078 |
-
function get_hookname() {
|
1079 |
-
return ( empty($this->hookname) ) ? '' : $this->hookname;
|
1080 |
-
}
|
1081 |
-
|
1082 |
-
/**
|
1083 |
-
* Set hookname
|
1084 |
-
* @param string $hookname Hookname value
|
1085 |
-
*/
|
1086 |
-
function set_hookname($hookname) {
|
1087 |
-
if ( !empty($hookname) && is_string($hookname) )
|
1088 |
-
$this->hookname = $hookname;
|
1089 |
-
}
|
1090 |
-
|
1091 |
-
/**
|
1092 |
-
* Retrieve parent
|
1093 |
-
* Formats parent ID for custom parents
|
1094 |
-
* @return string Parent ID
|
1095 |
-
*/
|
1096 |
-
function get_parent() {
|
1097 |
-
$parent = $this->parent;
|
1098 |
-
return ( $this->is_parent_custom() ) ? $this->add_prefix($parent) : $parent;
|
1099 |
-
}
|
1100 |
-
|
1101 |
-
/**
|
1102 |
-
* Set parent for view
|
1103 |
-
* @param string $parent Parent ID
|
1104 |
-
*/
|
1105 |
-
function set_parent($parent) {
|
1106 |
-
if ( $this->parent_required ) {
|
1107 |
-
if ( !empty($parent) && is_string($parent) )
|
1108 |
-
$this->parent = $parent;
|
1109 |
-
} else {
|
1110 |
-
$this->parent = null;
|
1111 |
-
}
|
1112 |
-
}
|
1113 |
-
|
1114 |
-
/**
|
1115 |
-
* Specify whether parent is a custom view or a WP view
|
1116 |
-
* @param bool $custom (optional) TRUE if custom, FALSE if WP
|
1117 |
-
*/
|
1118 |
-
function set_parent_custom($custom = true) {
|
1119 |
-
if ( $this->parent_required ) {
|
1120 |
-
$this->parent_custom = !!$custom;
|
1121 |
-
}
|
1122 |
-
}
|
1123 |
-
|
1124 |
-
/**
|
1125 |
-
* Set parent as WP view
|
1126 |
-
* @uses this->set_parent_custom()
|
1127 |
-
*/
|
1128 |
-
function set_parent_wp() {
|
1129 |
-
$this->set_parent_custom(false);
|
1130 |
-
}
|
1131 |
-
|
1132 |
-
/**
|
1133 |
-
* Get view URI
|
1134 |
-
* URI Structures:
|
1135 |
-
* > Top Level Menus: admin.php?page={menu_id}
|
1136 |
-
* > Pages: [parent_page_file.php|admin.php]?page={page_id}
|
1137 |
-
* > Section: [parent_menu_uri]#{section_id}
|
1138 |
-
*
|
1139 |
-
* @uses $admin_page_hooks to determine if page is child of default WP page
|
1140 |
-
* @return string Object URI
|
1141 |
-
*/
|
1142 |
-
function get_uri($file = null, $format = null) {
|
1143 |
-
static $page_hooks = null;
|
1144 |
-
$uri = '';
|
1145 |
-
if ( empty($file) )
|
1146 |
-
$file = 'admin.php';
|
1147 |
-
if ( $this->is_child() ) {
|
1148 |
-
$parent = str_replace('_page_' . $this->get_id(), '', $this->get_hookname());
|
1149 |
-
if ( is_null($page_hooks) ) {
|
1150 |
-
$page_hooks = array_flip($GLOBALS['admin_page_hooks']);
|
1151 |
-
}
|
1152 |
-
if ( isset($page_hooks[$parent]) )
|
1153 |
-
$file = $page_hooks[$parent];
|
1154 |
-
}
|
1155 |
-
|
1156 |
-
if ( empty($format) ) {
|
1157 |
-
$delim = ( strpos($file, '?') === false ) ? '?' : '&';
|
1158 |
-
$format = '%1$s' . $delim . 'page=%2$s';
|
1159 |
-
}
|
1160 |
-
$uri = sprintf($format, $file, $this->get_id());
|
1161 |
-
|
1162 |
-
return $uri;
|
1163 |
-
}
|
1164 |
-
|
1165 |
-
/* Handlers */
|
1166 |
-
|
1167 |
-
/**
|
1168 |
-
* Default View handler
|
1169 |
-
* Used as callback when none set
|
1170 |
-
*/
|
1171 |
-
function handle() {}
|
1172 |
-
|
1173 |
-
/* Validation */
|
1174 |
-
|
1175 |
-
/**
|
1176 |
-
* Check if instance is valid based on required properties/data types
|
1177 |
-
* @return bool TRUE if valid, FALSE if not valid
|
1178 |
-
*/
|
1179 |
-
function is_valid() {
|
1180 |
-
$valid = true;
|
1181 |
-
foreach ( $this->required as $prop => $type ) {
|
1182 |
-
if ( empty($this->{$prop} )
|
1183 |
-
|| ( !empty($type) && is_string($type) && ( $f = 'is_' . $type ) && function_exists($f) && !$f($this->{$prop}) ) ) {
|
1184 |
-
$valid = false;
|
1185 |
-
break;
|
1186 |
-
}
|
1187 |
-
}
|
1188 |
-
return $valid;
|
1189 |
-
}
|
1190 |
-
|
1191 |
-
function is_child() {
|
1192 |
-
return $this->parent_required;
|
1193 |
-
}
|
1194 |
-
|
1195 |
-
function is_parent_custom() {
|
1196 |
-
return ( $this->is_child() && $this->parent_custom ) ? true : false;
|
1197 |
-
}
|
1198 |
-
|
1199 |
-
function is_parent_wp() {
|
1200 |
-
return ( $this->is_child() && !$this->parent_custom ) ? true : false;
|
1201 |
-
}
|
1202 |
-
|
1203 |
-
function is_options_valid() {
|
1204 |
-
return ( is_object($this->get_options()) && $this->util->is_a($this->get_options(), $this->util->get_class('Options')) ) ? true : false;
|
1205 |
-
}
|
1206 |
-
|
1207 |
-
/* Options */
|
1208 |
-
|
1209 |
-
/**
|
1210 |
-
* Parse options build vars
|
1211 |
-
* @uses `options_parse_build_vars` filter hook
|
1212 |
-
*/
|
1213 |
-
function options_parse_build_vars($vars, $opts) {
|
1214 |
-
//Handle form submission
|
1215 |
-
if ( isset($_REQUEST[$opts->get_id('formatted')]) ) {
|
1216 |
-
$vars['validate_pre'] = $vars['save_pre'] = true;
|
1217 |
-
}
|
1218 |
-
return $vars;
|
1219 |
-
}
|
1220 |
-
|
1221 |
-
function options_build_pre(&$opts) {
|
1222 |
-
//Build form output
|
1223 |
-
$form_id = $this->add_prefix('admin_form_' . $this->get_id_raw());
|
1224 |
-
?>
|
1225 |
-
<form id="<?php esc_attr_e($form_id); ?>" name="<?php esc_attr_e($form_id); ?>" action="" method="post">
|
1226 |
-
<?php
|
1227 |
-
}
|
1228 |
-
|
1229 |
-
function options_build_post(&$opts) {
|
1230 |
-
submit_button();
|
1231 |
-
?>
|
1232 |
-
</form>
|
1233 |
-
<?php
|
1234 |
-
}
|
1235 |
-
|
1236 |
-
/**
|
1237 |
-
* Builds option groups output
|
1238 |
-
* @param SLB_Options $options Options instance
|
1239 |
-
* @param array $groups Groups to build
|
1240 |
-
*/
|
1241 |
-
function options_build_groups($options, $groups) {
|
1242 |
-
//Add meta box for each group
|
1243 |
-
$screen = get_current_screen();
|
1244 |
-
foreach ( $groups as $gid ) {
|
1245 |
-
$g = $options->get_group($gid);
|
1246 |
-
if ( !count($options->get_items($gid)) ) {
|
1247 |
-
continue;
|
1248 |
-
}
|
1249 |
-
add_meta_box($gid, $g->title, $this->m('options_build_group'), $screen, 'normal', 'default', array('options' => $options, 'group' => $gid));
|
1250 |
-
}
|
1251 |
-
//Build options
|
1252 |
-
do_meta_boxes($screen, 'normal', null);
|
1253 |
-
}
|
1254 |
-
|
1255 |
-
function options_build_group($obj, $args) {
|
1256 |
-
$args = $args['args'];
|
1257 |
-
$group = $args['group'];
|
1258 |
-
$opts = $args['options'];
|
1259 |
-
$opts->build_group($group);
|
1260 |
-
}
|
1261 |
-
|
1262 |
-
function show_options($show_submit = true) {
|
1263 |
-
//Build options output
|
1264 |
-
if ( !$this->is_options_valid() ) {
|
1265 |
-
return false;
|
1266 |
-
}
|
1267 |
-
/**
|
1268 |
-
* @var SLB_Options
|
1269 |
-
*/
|
1270 |
-
$opts =& $this->get_options();
|
1271 |
-
$hooks = array (
|
1272 |
-
'filter' => array (
|
1273 |
-
'parse_build_vars' => array( $this->m('options_parse_build_vars'), 10, 2 )
|
1274 |
-
),
|
1275 |
-
'action' => array (
|
1276 |
-
'build_pre' => array( $this->m('options_build_pre') ),
|
1277 |
-
'build_post' => array ( $this->m('options_build_post') ),
|
1278 |
-
)
|
1279 |
-
);
|
1280 |
-
//Add hooks
|
1281 |
-
foreach ( $hooks as $type => $hook ) {
|
1282 |
-
$m = 'add_' . $type;
|
1283 |
-
foreach ( $hook as $tag => $args ) {
|
1284 |
-
array_unshift($args, $tag);
|
1285 |
-
call_user_func_array($opts->util->m($m), $args);
|
1286 |
-
}
|
1287 |
-
}
|
1288 |
-
?>
|
1289 |
-
<div class="metabox-holder">
|
1290 |
-
<?php
|
1291 |
-
//Build output
|
1292 |
-
$opts->build(array('build_groups' => $this->m('options_build_groups')));
|
1293 |
-
?>
|
1294 |
-
</div>
|
1295 |
-
<?php
|
1296 |
-
//Remove hooks
|
1297 |
-
foreach ( $hooks as $type => $hook ) {
|
1298 |
-
$m = 'remove_' . $type;
|
1299 |
-
foreach ( $hook as $tag => $args ) {
|
1300 |
-
call_user_func($opts->util->m($m), $tag, $args[0]);
|
1301 |
-
}
|
1302 |
-
}
|
1303 |
-
}
|
1304 |
-
|
1305 |
-
/* UI Elements */
|
1306 |
-
|
1307 |
-
/**
|
1308 |
-
* Build submit button element
|
1309 |
-
* @param string $text (optional) Button text
|
1310 |
-
* @param string $id (optional) Button ID (prefixed on output)
|
1311 |
-
* @param object $parent (optional) Page/Section object that contains button
|
1312 |
-
* @return object Button properties (id, output)
|
1313 |
-
*/
|
1314 |
-
function get_button_submit($text = null, $id = null, $parent = null) {
|
1315 |
-
//Format values
|
1316 |
-
if ( !is_string($text) || empty($text) )
|
1317 |
-
$text = __('Save Changes');
|
1318 |
-
if ( is_object($parent) && isset($parent->id) )
|
1319 |
-
$parent = $parent->id . '_';
|
1320 |
-
else
|
1321 |
-
$parent = '';
|
1322 |
-
if ( !is_string($id) || empty($id) )
|
1323 |
-
$id = 'submit';
|
1324 |
-
$id = $this->add_prefix($parent . $id);
|
1325 |
-
//Build HTML
|
1326 |
-
$out = $this->util->build_html_element(array(
|
1327 |
-
'tag' => 'input',
|
1328 |
-
'wrap' => false,
|
1329 |
-
'attributes' => array(
|
1330 |
-
'type' => 'submit',
|
1331 |
-
'class' => 'button-primary',
|
1332 |
-
'id' => $id,
|
1333 |
-
'name' => $id,
|
1334 |
-
'value' => $text
|
1335 |
-
)
|
1336 |
-
));
|
1337 |
-
$out = '<p class="submit">' . $out . '</p>';
|
1338 |
-
$ret = new stdClass;
|
1339 |
-
$ret->id = $id;
|
1340 |
-
$ret->output = $out;
|
1341 |
-
return $ret;
|
1342 |
-
}
|
1343 |
-
|
1344 |
-
/**
|
1345 |
-
* Output submit button element
|
1346 |
-
* @param string $text (optional) Button text
|
1347 |
-
* @param string $id (optional) Button ID (prefixed on output)
|
1348 |
-
* @param object $parent (optional) Page/Section object that contains button
|
1349 |
-
* @return object Button properties (id, output)
|
1350 |
-
*/
|
1351 |
-
function button_submit($text = null, $id = null, $parent = null) {
|
1352 |
-
$btn = $this->get_button_submit($text, $id, $parent);
|
1353 |
-
echo $btn->output;
|
1354 |
-
return $btn;
|
1355 |
-
}
|
1356 |
-
}
|
1357 |
-
|
1358 |
-
/**
|
1359 |
-
* Admin Menu functionality
|
1360 |
-
* @package Simple Lightbox
|
1361 |
-
* @subpackage Admin
|
1362 |
-
* @author Archetyped
|
1363 |
-
*/
|
1364 |
-
class SLB_Admin_Menu extends SLB_Admin_View {
|
1365 |
-
/* Properties */
|
1366 |
-
|
1367 |
-
/**
|
1368 |
-
* Menu position
|
1369 |
-
* @var int
|
1370 |
-
*/
|
1371 |
-
var $position = null;
|
1372 |
-
|
1373 |
-
/* Init */
|
1374 |
-
|
1375 |
-
function __construct($id, $labels, $options = null, $callback = null, $capability = null, $icon = null, $position = null) {
|
1376 |
-
//Default
|
1377 |
-
parent::__construct($id, $labels, $options, $callback, $capability, $icon);
|
1378 |
-
//Class specific
|
1379 |
-
$this->set_position($position);
|
1380 |
-
}
|
1381 |
-
|
1382 |
-
/* Getters/Setters */
|
1383 |
-
|
1384 |
-
function set_position($position) {
|
1385 |
-
if ( is_int($position) )
|
1386 |
-
$this->position = $position;
|
1387 |
-
}
|
1388 |
-
|
1389 |
-
/* Handlers */
|
1390 |
-
|
1391 |
-
function handle() {
|
1392 |
-
if ( !current_user_can($this->get_capability()) )
|
1393 |
-
wp_die(__('Access Denied', 'simple-lightbox'));
|
1394 |
-
?>
|
1395 |
-
<div class="wrap">
|
1396 |
-
<h2><?php esc_html_e( $this->get_label('header') ); ?></h2>
|
1397 |
-
<?php
|
1398 |
-
$this->show_options();
|
1399 |
-
?>
|
1400 |
-
</div>
|
1401 |
-
<?php
|
1402 |
-
}
|
1403 |
-
}
|
1404 |
-
|
1405 |
-
/**
|
1406 |
-
* Admin Page functionality
|
1407 |
-
* @package Simple Lightbox
|
1408 |
-
* @subpackage Admin
|
1409 |
-
* @author Archetyped
|
1410 |
-
*/
|
1411 |
-
class SLB_Admin_Page extends SLB_Admin_View {
|
1412 |
-
/* Properties */
|
1413 |
-
|
1414 |
-
var $parent_required = true;
|
1415 |
-
|
1416 |
-
/* Init */
|
1417 |
-
|
1418 |
-
function __construct($id, $parent, $labels, $options = null, $callback = null, $capability = null, $icon = null) {
|
1419 |
-
//Default
|
1420 |
-
parent::__construct($id, $labels, $options, $callback, $capability, $icon);
|
1421 |
-
//Class specific
|
1422 |
-
$this->set_parent($parent);
|
1423 |
-
}
|
1424 |
-
|
1425 |
-
/* Operations */
|
1426 |
-
|
1427 |
-
function show_icon() {
|
1428 |
-
echo screen_icon();
|
1429 |
-
}
|
1430 |
-
|
1431 |
-
/* Handlers */
|
1432 |
-
|
1433 |
-
/**
|
1434 |
-
* Default Page handler
|
1435 |
-
* Builds options form UI for page
|
1436 |
-
* @see this->init_menus() Set as callback for custom admin pages
|
1437 |
-
* @uses current_user_can() to check if user has access to current page
|
1438 |
-
* @uses wp_die() to end execution when user does not have permission to access page
|
1439 |
-
*/
|
1440 |
-
function handle() {
|
1441 |
-
if ( !current_user_can($this->get_capability()) )
|
1442 |
-
wp_die(__('Access Denied', 'simple-lightbox'));
|
1443 |
-
?>
|
1444 |
-
<div class="wrap">
|
1445 |
-
<?php $this->show_icon(); ?>
|
1446 |
-
<h2><?php esc_html_e( $this->get_label('header') ); ?></h2>
|
1447 |
-
<?php
|
1448 |
-
$this->show_options();
|
1449 |
-
?>
|
1450 |
-
</div>
|
1451 |
-
<?php
|
1452 |
-
}
|
1453 |
-
}
|
1454 |
-
|
1455 |
-
/**
|
1456 |
-
* Admin Section functionality
|
1457 |
-
* @package Simple Lightbox
|
1458 |
-
* @subpackage Admin
|
1459 |
-
* @author Archetyped
|
1460 |
-
*/
|
1461 |
-
class SLB_Admin_Section extends SLB_Admin_View {
|
1462 |
-
/* Properties */
|
1463 |
-
|
1464 |
-
var $parent_required = true;
|
1465 |
-
var $parent_custom = false;
|
1466 |
-
|
1467 |
-
/* Init */
|
1468 |
-
|
1469 |
-
function __construct($id, $parent, $labels, $options = null, $callback = null, $capability = null) {
|
1470 |
-
//Default
|
1471 |
-
parent::__construct($id, $labels, $options, $callback, $capability);
|
1472 |
-
//Class specific
|
1473 |
-
$this->set_parent($parent);
|
1474 |
-
}
|
1475 |
-
|
1476 |
-
/* Getters/Setters */
|
1477 |
-
|
1478 |
-
function get_uri() {
|
1479 |
-
$file = 'options-' . $this->get_parent() . '.php';
|
1480 |
-
return parent::get_uri($file, '%1$s#%2$s');
|
1481 |
-
}
|
1482 |
-
|
1483 |
-
/**
|
1484 |
-
* Retrieve formatted title for section
|
1485 |
-
* Wraps title text in element with anchor so that it can be linked to
|
1486 |
-
* @return string Title
|
1487 |
-
*/
|
1488 |
-
function get_title() {
|
1489 |
-
return '<div id="' . $this->get_id() . '" class="' . $this->add_prefix('section_head') . '">' . $this->get_label('title') . '</div>';
|
1490 |
-
}
|
1491 |
-
|
1492 |
-
/* Handlers */
|
1493 |
-
|
1494 |
-
function handle() {
|
1495 |
-
$this->show_options(false);
|
1496 |
-
}
|
1497 |
-
|
1498 |
-
function options_parse_build_vars($vars, $opts) {
|
1499 |
-
return $vars;
|
1500 |
-
}
|
1501 |
-
|
1502 |
-
function options_build_pre() {}
|
1503 |
-
|
1504 |
-
function options_build_post() {}
|
1505 |
-
}
|
1506 |
-
|
1507 |
-
class SLB_Admin_Reset extends SLB_Admin_View {
|
1508 |
-
/* Properties */
|
1509 |
-
|
1510 |
-
var $required = array ( 'options' => 'object' );
|
1511 |
-
|
1512 |
-
var $parent_required = false;
|
1513 |
-
|
1514 |
-
/* Init */
|
1515 |
-
|
1516 |
-
function __construct($id, $labels, $options) {
|
1517 |
-
parent::__construct($id, $labels, $options);
|
1518 |
-
}
|
1519 |
-
|
1520 |
-
/* Handlers */
|
1521 |
-
|
1522 |
-
/**
|
1523 |
-
* Default handler
|
1524 |
-
* Resets plugin settings
|
1525 |
-
* @return string Status message (success, fail, etc.)
|
1526 |
-
*/
|
1527 |
-
function handle() {
|
1528 |
-
//Validate user
|
1529 |
-
if ( ! current_user_can('activate_plugins') || ! check_admin_referer($this->get_id()) )
|
1530 |
-
wp_die(__('Access Denied', 'simple-lightbox'));
|
1531 |
-
|
1532 |
-
//Reset settings
|
1533 |
-
if ( $this->is_options_valid() )
|
1534 |
-
$this->get_options()->reset(true);
|
1535 |
-
|
1536 |
-
//Set Status Message
|
1537 |
-
$this->set_message($this->get_label('success'));
|
1538 |
-
|
1539 |
-
/*
|
1540 |
-
//Redirect user
|
1541 |
-
$uri = remove_query_arg(array('_wpnonce', 'action'), add_query_arg(array($this->add_prefix('action') => $action), $_SERVER['REQUEST_URI']));
|
1542 |
-
wp_redirect($uri);
|
1543 |
-
exit;
|
1544 |
-
*/
|
1545 |
-
}
|
1546 |
-
|
1547 |
-
function get_uri() {
|
1548 |
-
return wp_nonce_url(add_query_arg($this->get_query_args(), remove_query_arg($this->get_query_args_remove(), $_SERVER['REQUEST_URI'])), $this->get_id());
|
1549 |
-
}
|
1550 |
-
|
1551 |
-
function get_query_args() {
|
1552 |
-
return array (
|
1553 |
-
'action' => $this->add_prefix('admin'),
|
1554 |
-
$this->add_prefix('type') => 'view',
|
1555 |
-
$this->add_prefix('group') => 'reset',
|
1556 |
-
$this->add_prefix('obj') => $this->get_id_raw()
|
1557 |
-
);
|
1558 |
-
}
|
1559 |
-
|
1560 |
-
function get_query_args_remove() {
|
1561 |
-
$args_r = array (
|
1562 |
-
'_wpnonce',
|
1563 |
-
$this->add_prefix('action')
|
1564 |
-
);
|
1565 |
-
|
1566 |
-
return array_unique( array_merge( array_keys( $this->get_query_args() ), $args_r ) );
|
1567 |
-
}
|
1568 |
-
|
1569 |
-
function get_link_attr() {
|
1570 |
-
return array (
|
1571 |
-
'class' => 'delete',
|
1572 |
-
'onclick' => "return confirm('" . $this->get_label('confirm') . "')"
|
1573 |
-
);
|
1574 |
-
}
|
1575 |
-
|
1576 |
-
}
|
11 |
|
12 |
protected $mode = 'sub';
|
13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
/* Properties */
|
15 |
|
16 |
/**
|
18 |
* Set on initialization
|
19 |
* @var obj
|
20 |
*/
|
21 |
+
protected $parent = null;
|
22 |
|
23 |
/**
|
24 |
* Messages
|
25 |
* @var array
|
26 |
*/
|
27 |
+
protected $messages = array(
|
28 |
+
'reset' => 'The settings have been reset',
|
29 |
+
'beta' => '<strong class="%1$s">Notice:</strong> This update is a <strong class="%1$s">Beta version</strong>. It is highly recommended that you test the update on a test server before updating the plugin on a production server.',
|
30 |
+
'access_denied' => 'You do not have sufficient permissions'
|
31 |
+
);
|
32 |
|
33 |
/* Views */
|
34 |
|
39 |
* > Val: Menu properties
|
40 |
* @var array
|
41 |
*/
|
42 |
+
protected $menus = array();
|
43 |
|
44 |
/**
|
45 |
* Custom admin pages
|
48 |
* > Val: Page properties
|
49 |
* @var array
|
50 |
*/
|
51 |
+
protected $pages = array();
|
52 |
|
53 |
/**
|
54 |
* Custom admin sections
|
57 |
* > Val: Section properties
|
58 |
* @var array
|
59 |
*/
|
60 |
+
protected $sections = array();
|
61 |
|
62 |
/**
|
63 |
+
* Actions
|
64 |
+
* Index Array
|
65 |
* @var array
|
66 |
*/
|
67 |
+
protected $actions = array();
|
68 |
|
69 |
/* Constructor */
|
70 |
|
71 |
+
public function __construct(&$parent) {
|
|
|
|
|
|
|
72 |
parent::__construct();
|
73 |
+
// Set parent
|
74 |
if ( is_object($parent) )
|
75 |
+
$this->parent = $parent;
|
76 |
}
|
77 |
|
78 |
/* Init */
|
79 |
|
80 |
protected function _hooks() {
|
81 |
parent::_hooks();
|
82 |
+
// Init
|
83 |
add_action('admin_menu', $this->m('init_menus'), 11);
|
84 |
|
85 |
+
// Plugin actions
|
86 |
add_action('admin_action_' . $this->add_prefix('admin'), $this->m('handle_action'));
|
87 |
|
88 |
+
// Notices
|
89 |
add_action('admin_notices', $this->m('handle_notices'));
|
90 |
|
91 |
+
// Plugin listing
|
92 |
add_filter('plugin_action_links_' . $this->util->get_plugin_base_name(), $this->m('plugin_action_links'), 10, 4);
|
93 |
+
add_filter('plugin_row_meta', $this->m('plugin_row_meta'), 10, 4);
|
94 |
add_action('in_plugin_update_message-' . $this->util->get_plugin_base_name(), $this->m('plugin_update_message'), 10, 2);
|
95 |
add_filter('site_transient_update_plugins', $this->m('plugin_update_transient'));
|
96 |
}
|
97 |
|
98 |
+
/**
|
99 |
+
* Declare client files (scripts, styles)
|
100 |
+
* @uses parent::_client_files()
|
101 |
+
* @return void
|
102 |
+
*/
|
103 |
+
protected function _client_files($files = null) {
|
104 |
+
$js_path = 'client/js/';
|
105 |
+
$js_path .= ( SLB_DEV ) ? 'dev' : 'prod';
|
106 |
+
$pfx = $this->get_prefix();
|
107 |
+
$files = array (
|
108 |
+
'scripts' => array (
|
109 |
+
'admin' => array (
|
110 |
+
'file' => "$js_path/lib.admin.js",
|
111 |
+
'deps' => array('[core]'),
|
112 |
+
'context' => array( "admin_page_$pfx" ),
|
113 |
+
'in_footer' => true,
|
114 |
+
),
|
115 |
+
),
|
116 |
+
'styles' => array (
|
117 |
+
'admin' => array (
|
118 |
+
'file' => 'client/css/admin.css',
|
119 |
+
'context' => array( "admin_page_$pfx", 'admin_page_plugins' )
|
120 |
+
)
|
121 |
+
)
|
122 |
+
);
|
123 |
+
parent::_client_files($files);
|
124 |
+
}
|
125 |
+
|
126 |
/* Handlers */
|
127 |
|
128 |
+
/**
|
129 |
+
* Handle routing of internal action to appropriate handler
|
130 |
+
*/
|
131 |
+
public function handle_action() {
|
132 |
+
// Parse action
|
133 |
$t = 'type';
|
134 |
$g = 'group';
|
135 |
$o = 'obj';
|
138 |
$this->add_prefix_ref($o);
|
139 |
$r =& $_REQUEST;
|
140 |
|
141 |
+
// Retrieve view that initiated the action
|
142 |
if ( isset($r[$t]) && 'view' == $r[$t] ) {
|
143 |
if ( isset($r[$g]) && ( $prop = $r[$g] . 's' ) && property_exists($this, $prop) && is_array($this->{$prop}) && isset($r[$o]) && isset($this->{$prop}[$r[$o]]) ) {
|
144 |
$view =& $this->{$prop}[$r[$o]];
|
145 |
+
// Pass request to view
|
146 |
$view->do_callback();
|
147 |
}
|
148 |
}
|
153 |
* Messages are localized upon display
|
154 |
* @uses `admin_notices` action hook to display messages
|
155 |
*/
|
156 |
+
public function handle_notices() {
|
157 |
$msgs = $this->util->apply_filters('admin_messages', array());
|
158 |
foreach ( $msgs as $mid => $msg ) {
|
159 |
+
// Filter out empty messages
|
160 |
if ( empty($msg) )
|
161 |
continue;
|
162 |
+
// Build and display message
|
163 |
$mid = $this->add_prefix('msg_' . $mid);
|
164 |
?>
|
165 |
<div id="<?php echo esc_attr($mid); ?>" class="updated fade">
|
171 |
}
|
172 |
}
|
173 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
174 |
/* Views */
|
175 |
|
176 |
/**
|
178 |
* Section is added to specified admin section/menu
|
179 |
* @uses `admin_init` hook
|
180 |
*/
|
181 |
+
public function init_menus() {
|
182 |
+
// Add top level menus (when necessary)
|
|
|
|
|
|
|
183 |
$menu;
|
184 |
foreach ( $this->menus as $menu ) {
|
185 |
+
// Register menu
|
186 |
$hook = add_menu_page($menu->get_label('title'), $menu->get_label('menu'), $menu->get_capability(), $menu->get_id(), $menu->get_callback());
|
187 |
+
// Add hook to menu object
|
188 |
$menu->set_hookname($hook);
|
189 |
$this->menus[$menu->get_id_raw()] =& $menu;
|
190 |
}
|
191 |
|
|
|
|
|
|
|
192 |
$page;
|
193 |
+
// Add subpages
|
194 |
foreach ( $this->pages as $page ) {
|
195 |
+
// Build Arguments
|
196 |
$args = array ( $page->get_label('header'), $page->get_label('menu'), $page->get_capability(), $page->get_id(), $page->get_callback() );
|
197 |
$f = null;
|
198 |
+
// Handle pages for default WP menus
|
199 |
if ( $page->is_parent_wp() ) {
|
200 |
$f = 'add_' . $page->get_parent() . '_page';
|
201 |
}
|
202 |
|
203 |
+
// Handle pages for custom menus
|
204 |
if ( ! function_exists($f) ) {
|
205 |
array_unshift( $args, $page->get_parent() );
|
206 |
$f = 'add_submenu_page';
|
207 |
}
|
208 |
|
209 |
+
// Add admin page
|
210 |
$hook = call_user_func_array($f, $args);
|
211 |
+
// Save hook to page properties
|
212 |
$page->set_hookname($hook);
|
213 |
$this->pages[$page->get_id_raw()] =& $page;
|
214 |
}
|
215 |
|
216 |
+
// Add sections
|
|
|
|
|
|
|
217 |
$section;
|
218 |
foreach ( $this->sections as $section ) {
|
219 |
add_settings_section($section->get_id(), $section->get_title(), $section->get_callback(), $section->get_parent());
|
|
|
|
|
220 |
}
|
221 |
}
|
222 |
|
228 |
* @param string $type View type
|
229 |
* @param string $id Unique view ID
|
230 |
* @param array $args Arguments to pass to view constructor
|
231 |
+
* @return Admin_View|bool View instance (FALSE if view was not properly initialized)
|
232 |
*/
|
233 |
+
protected function add_view($type, $id, $args) {
|
234 |
+
// Validate request
|
235 |
$class = $this->add_prefix('admin_' . $type);
|
236 |
$collection = $type . 's';
|
237 |
+
if ( !class_exists($class) ) {
|
238 |
+
$class = $this->add_prefix('admin_view');
|
239 |
+
$collection = null;
|
240 |
+
}
|
241 |
+
// Create new instance
|
242 |
$r = new ReflectionClass($class);
|
243 |
+
$view = $r->newInstanceArgs($args);
|
244 |
+
if ( $view->is_valid() && !empty($collection) && property_exists($this, $collection) && is_array($this->{$collection}) )
|
245 |
$this->{$collection}[$id] =& $view;
|
246 |
+
unset($r);
|
247 |
+
return $view;
|
|
|
|
|
248 |
}
|
249 |
|
250 |
/**
|
251 |
+
* Add plugin action link
|
252 |
+
* @uses `add_view()` to init/attach action instance
|
253 |
+
* @param string $id Action ID
|
254 |
+
* @param array $labels Text for action
|
255 |
+
* > title - Link text (also title attribute value)
|
256 |
+
* > confirm - Confirmation message
|
257 |
+
* > success - Success message
|
258 |
+
* > failure - Failure message
|
259 |
+
* @param array $data Additional data for action
|
260 |
+
* @return obj Action instance
|
261 |
*/
|
262 |
+
public function add_action($id, $labels, $data = null) {
|
263 |
$args = func_get_args();
|
264 |
+
return $this->add_view('action', $id, $args);
|
265 |
}
|
266 |
|
267 |
/*-** Menus **-*/
|
271 |
* @param string $id Menu ID
|
272 |
* @param string|array $labels Text labels
|
273 |
* @param int $pos (optional) Menu position in navigation (index order)
|
274 |
+
* @return Admin_Menu Menu instance
|
275 |
*/
|
276 |
+
public function add_menu($id, $labels, $position = null) {
|
277 |
$args = array ( $id, $labels, null, null, null, $position );
|
278 |
return $this->add_view('menu', $id, $args);
|
279 |
}
|
284 |
* Add admin page
|
285 |
* @uses this->pages
|
286 |
* @param string $id Page ID (unique)
|
287 |
+
* @param string $parent Menu ID to add page to
|
288 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
289 |
* > menu: Menu title
|
290 |
* > header: Page header
|
|
|
|
|
|
|
|
|
291 |
* @param string $capability (optional) Custom capability for accessing page
|
292 |
+
* @return Admin_Page Page instance
|
293 |
*/
|
294 |
+
public function add_page($id, $parent, $labels, $callback = null, $capability = null) {
|
295 |
$args = func_get_args();
|
|
|
296 |
return $this->add_view('page', $id, $args);
|
297 |
}
|
298 |
|
302 |
* Add admin page to a standard WP menu
|
303 |
* @uses this->add_page()
|
304 |
* @param string $id Page ID (unique)
|
305 |
+
* @param string $parent Name of WP menu to add page to
|
306 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
307 |
* > menu: Menu title
|
308 |
* > header: Page header
|
|
|
|
|
|
|
|
|
309 |
* @param string $capability (optional) Custom capability for accessing page
|
310 |
+
* @return Admin_Page Page instance
|
311 |
+
*/
|
312 |
+
public function add_wp_page($id, $parent, $labels, $callback = null, $capability = null) {
|
313 |
+
// Add page
|
314 |
+
$pg = $this->add_page($id, $parent, $labels, $capability);
|
315 |
+
// Set parent as WP
|
316 |
+
if ( $pg ) {
|
317 |
+
$pg->set_parent_wp();
|
318 |
}
|
319 |
+
return $pg;
|
320 |
}
|
321 |
|
322 |
/**
|
325 |
* @uses this->add_wp_page()
|
326 |
* @param string $id Page ID (unique)
|
327 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
|
|
|
|
|
|
328 |
* @param string $capability (optional) Custom capability for accessing page
|
329 |
+
* @return Admin_Page Page instance
|
330 |
*/
|
331 |
+
public function add_dashboard_page($id, $labels, $callback = null, $capability = null) {
|
332 |
+
return $this->add_wp_page($id, 'dashboard', $labels, $capability);
|
|
|
333 |
}
|
334 |
|
335 |
/**
|
338 |
* @uses this->add_wp_page()
|
339 |
* @param string $id Page ID (unique)
|
340 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
|
|
|
|
|
|
341 |
* @param string $capability (optional) Custom capability for accessing page
|
342 |
* @return string Page ID
|
343 |
*/
|
344 |
+
public function add_comments_page($id, $labels, $callback = null, $capability = null) {
|
345 |
+
return $this->add_wp_page($id, 'comments', $labels, $capability);
|
|
|
346 |
}
|
347 |
|
348 |
/**
|
351 |
* @uses this->add_wp_page()
|
352 |
* @param string $id Page ID (unique)
|
353 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
|
|
|
|
|
|
354 |
* @param string $capability (optional) Custom capability for accessing page
|
355 |
* @return string Page ID
|
356 |
*/
|
357 |
+
public function add_links_page($id, $labels, $callback = null, $capability = null) {
|
358 |
+
return $this->add_wp_page($id, 'links', $labels, $capability);
|
|
|
359 |
}
|
360 |
|
361 |
|
365 |
* @uses this->add_wp_page()
|
366 |
* @param string $id Page ID (unique)
|
367 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
|
|
|
|
|
|
368 |
* @param string $capability (optional) Custom capability for accessing page
|
369 |
* @return string Page ID
|
370 |
*/
|
371 |
+
public function add_posts_page($id, $labels, $callback = null, $capability = null) {
|
372 |
+
return $this->add_wp_page($id, 'posts', $labels, $capability);
|
|
|
373 |
}
|
374 |
|
375 |
/**
|
378 |
* @uses this->add_wp_page()
|
379 |
* @param string $id Page ID (unique)
|
380 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
|
|
|
|
|
|
381 |
* @param string $capability (optional) Custom capability for accessing page
|
382 |
* @return string Page ID
|
383 |
*/
|
384 |
+
public function add_pages_page($id, $labels, $callback = null, $capability = null) {
|
385 |
+
return $this->add_wp_page($id, 'pages', $labels, $capability);
|
|
|
386 |
}
|
387 |
|
388 |
/**
|
391 |
* @uses this->add_wp_page()
|
392 |
* @param string $id Page ID (unique)
|
393 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
|
|
|
|
|
|
394 |
* @param string $capability (optional) Custom capability for accessing page
|
395 |
* @return string Page ID
|
396 |
*/
|
397 |
+
public function add_media_page($id, $labels, $callback = null, $capability = null) {
|
398 |
+
return $this->add_wp_page($id, 'media', $labels, $capability);
|
|
|
399 |
}
|
400 |
|
401 |
/**
|
404 |
* @uses this->add_wp_page()
|
405 |
* @param string $id Page ID (unique)
|
406 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
|
|
|
|
|
|
407 |
* @param string $capability (optional) Custom capability for accessing page
|
408 |
* @return string Page ID
|
409 |
*/
|
410 |
+
public function add_theme_page($id, $labels, $callback = null, $capability = null) {
|
411 |
+
return $this->add_wp_page($id, 'theme', $labels, $capability);
|
|
|
412 |
}
|
413 |
|
414 |
/**
|
417 |
* @uses this->add_wp_page()
|
418 |
* @param string $id Page ID (unique)
|
419 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
|
|
|
|
|
|
420 |
* @param string $capability (optional) Custom capability for accessing page
|
421 |
* @return string Page ID
|
422 |
*/
|
423 |
+
public function add_plugins_page($id, $labels, $callback = null, $capability = null) {
|
424 |
+
return $this->add_wp_page($id, 'plugins', $labels, $capability);
|
|
|
425 |
}
|
426 |
|
427 |
/**
|
430 |
* @uses this->add_wp_page()
|
431 |
* @param string $id Page ID (unique)
|
432 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
|
|
|
|
|
|
433 |
* @param string $capability (optional) Custom capability for accessing page
|
434 |
* @return string Page ID
|
435 |
*/
|
436 |
+
public function add_options_page($id, $labels, $callback = null, $capability = null) {
|
437 |
+
return $this->add_wp_page($id, 'options', $labels, $capability);
|
|
|
438 |
}
|
439 |
|
440 |
/**
|
443 |
* @uses this->add_wp_page()
|
444 |
* @param string $id Page ID (unique)
|
445 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
|
|
|
|
|
|
446 |
* @param string $capability (optional) Custom capability for accessing page
|
447 |
* @return string Page ID
|
448 |
*/
|
449 |
+
public function add_management_page($id, $labels, $callback = null, $capability = null) {
|
450 |
+
return $this->add_wp_page($id, 'management', $labels, $capability);
|
|
|
451 |
}
|
452 |
|
453 |
/**
|
455 |
* @uses this->add_wp_page()
|
456 |
* @param string $id Page ID (unique)
|
457 |
* @param string|array $labels Text labels (Associative array for multiple labels)
|
|
|
|
|
|
|
458 |
* @param string $capability (optional) Custom capability for accessing page
|
459 |
* @return string Page ID
|
460 |
*/
|
461 |
+
public function add_users_page($id, $labels, $callback = null, $capability = null) {
|
462 |
+
return $this->add_wp_page($id, 'users', $labels, $capability);
|
|
|
463 |
}
|
464 |
|
465 |
/* Section */
|
470 |
* @param string $id Unique section ID
|
471 |
* @param string $page Page ID
|
472 |
* @param string $labels Label text
|
473 |
+
* @return obj Section instance
|
|
|
|
|
|
|
474 |
*/
|
475 |
+
public function add_section($id, $parent, $labels) {
|
476 |
+
$args = func_get_args();
|
477 |
+
$section = $this->add_view('section', $id, $args);
|
478 |
|
479 |
+
// Add Section
|
480 |
if ( $section->is_valid() )
|
481 |
+
$this->sections[$id] = $section;
|
482 |
+
|
483 |
+
return $section;
|
|
|
484 |
}
|
485 |
|
486 |
/* Operations */
|
493 |
* @param $plugin_data
|
494 |
* @param $context
|
495 |
*/
|
496 |
+
public function plugin_action_links($actions, $plugin_file, $plugin_data, $context) {
|
497 |
global $admin_page_hooks;
|
498 |
+
// Add link to settings (only if active)
|
499 |
if ( is_plugin_active($this->util->get_plugin_base_name()) ) {
|
500 |
/* Get Actions */
|
501 |
|
516 |
}
|
517 |
}
|
518 |
|
519 |
+
/* Get action links */
|
520 |
$type = 'title';
|
521 |
+
foreach ( $this->actions as $a ) {
|
522 |
+
if ( !$a->has_label($type) )
|
523 |
continue;
|
524 |
+
$id = 'action_' . $a->get_id();
|
525 |
$acts[] = (object) array (
|
526 |
+
'id' => $id,
|
527 |
+
'label' => $a->get_label($type),
|
528 |
+
'uri' => $a->get_uri(),
|
529 |
+
'attributes' => $a->get_link_attr()
|
530 |
);
|
531 |
}
|
532 |
+
unset($a);
|
533 |
|
534 |
+
// Add links
|
535 |
$links = array();
|
536 |
foreach ( $acts as $act ) {
|
537 |
$links[$act->id] = $this->util->build_html_link($act->uri, $act->label, $act->attributes);
|
538 |
}
|
539 |
|
540 |
+
// Add links
|
541 |
$actions = array_merge($links, $actions);
|
542 |
}
|
543 |
return $actions;
|
544 |
}
|
545 |
+
|
546 |
+
/**
|
547 |
+
* Update plugin listings metadata
|
548 |
+
* @param array $plugin_meta Plugin metadata
|
549 |
+
* @param string $plugin_file Plugin file
|
550 |
+
* @param array $plugin_data Plugin Data
|
551 |
+
* @param string $status Plugin status
|
552 |
+
* @return array Updated plugin metadata
|
553 |
+
*/
|
554 |
+
public function plugin_row_meta($plugin_meta, $plugin_file, $plugin_data, $status) {
|
555 |
+
$u = ( is_object($this->parent) && isset($this->parent->util) ) ? $this->parent->util : $this->util;
|
556 |
+
$hook_base = 'admin_plugin_row_meta_';
|
557 |
+
if ( $plugin_file == $u->get_plugin_base_name() ) {
|
558 |
+
// Add metadata
|
559 |
+
// Support
|
560 |
+
$l = $u->get_plugin_info('SupportURI');
|
561 |
+
if ( !empty($l) ) {
|
562 |
+
$t = __( $this->util->apply_filters($hook_base . 'support', 'Get Support'), 'simple-lightbox');
|
563 |
+
$plugin_meta[] = $u->build_html_link($l, $t);
|
564 |
+
}
|
565 |
+
}
|
566 |
+
return $plugin_meta;
|
567 |
+
}
|
568 |
|
569 |
/**
|
570 |
* Adds additional message for plugin updates
|
573 |
* @var array $plugin_data Current plugin data
|
574 |
* @var object $r Update response data
|
575 |
*/
|
576 |
+
public function plugin_update_message($plugin_data, $r) {
|
577 |
if ( !isset($r->new_version) )
|
578 |
return false;
|
579 |
if ( stripos($r->new_version, 'beta') !== false ) {
|
589 |
* @param obj $transient Transient data
|
590 |
* @return obj Modified transient data
|
591 |
*/
|
592 |
+
public function plugin_update_transient($transient) {
|
593 |
$n = $this->util->get_plugin_base_name();
|
594 |
if ( isset($transient->response) && isset($transient->response[$n]) && is_object($transient->response[$n]) && !isset($transient->response[$n]->upgrade_notice) ) {
|
595 |
$r =& $transient->response[$n];
|
604 |
* @param obj $r Response data from plugin update API
|
605 |
* @return string Message (Default: empty string)
|
606 |
*/
|
607 |
+
protected function plugin_update_get_message($r) {
|
608 |
$msg = '';
|
609 |
$cls_notice = $this->add_prefix('notice');
|
610 |
if ( !is_object($r) || !isset($r->new_version) )
|
622 |
* @param string $msg_id Message ID
|
623 |
* @return string Message text
|
624 |
*/
|
625 |
+
public function get_message($msg_id) {
|
626 |
$msg = '';
|
627 |
$msgs = $this->get_messages();
|
628 |
if ( is_string($msg_id) && isset($msgs[$msg_id]) ) {
|
639 |
*/
|
640 |
function get_messages() {
|
641 |
if ( empty($this->messages) ) {
|
642 |
+
// Initialize messages if necessary
|
643 |
$this->messages = array(
|
644 |
'reset' => __('The settings have been reset', 'simple-lightbox'),
|
645 |
'beta' => __('<strong class="%1$s">Notice:</strong> This update is a <strong class="%1$s">Beta version</strong>. It is highly recommended that you test the update on a test server before updating the plugin on a production server.', 'simple-lightbox'),
|
655 |
* @param string $id Message ID
|
656 |
* @param string $text Message text
|
657 |
*/
|
658 |
+
public function set_message($id, $text) {
|
659 |
$this->messages[trim($id)] = $text;
|
660 |
}
|
661 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/class.admin_action.php
ADDED
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Plugin action functionality
|
5 |
+
* Used for adding action links to plugin listing, etc.
|
6 |
+
* @package Simple Lightbox
|
7 |
+
* @subpackage Admin
|
8 |
+
* @author Archetyped
|
9 |
+
*/
|
10 |
+
class SLB_Admin_Action extends SLB_Admin_View {
|
11 |
+
/* Properties */
|
12 |
+
|
13 |
+
protected $parent_required = false;
|
14 |
+
|
15 |
+
public $hook_prefix = 'admin_action';
|
16 |
+
|
17 |
+
/* Init */
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Init
|
21 |
+
* @param string $id ID
|
22 |
+
* @param array $labels Labels
|
23 |
+
* @param obj $data Action data
|
24 |
+
* @return obj Current instance
|
25 |
+
*/
|
26 |
+
function __construct($id, $labels, $data = null) {
|
27 |
+
parent::__construct($id, $labels);
|
28 |
+
// Default options instance
|
29 |
+
if ( !empty($data) ) {
|
30 |
+
$this->add_content('data', $data);
|
31 |
+
}
|
32 |
+
return $this;
|
33 |
+
}
|
34 |
+
|
35 |
+
/* Handlers */
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Default handler
|
39 |
+
* Handles action
|
40 |
+
* @return string Status message (success, fail, etc.)
|
41 |
+
*/
|
42 |
+
public function handle() {
|
43 |
+
// Validate user
|
44 |
+
if ( ! current_user_can('activate_plugins') || ! check_admin_referer($this->get_id()) )
|
45 |
+
wp_die(__('Access Denied', 'simple-lightbox'));
|
46 |
+
|
47 |
+
// Get data
|
48 |
+
$content = $this->get_content();
|
49 |
+
|
50 |
+
$success = true;
|
51 |
+
|
52 |
+
// Iterate through data
|
53 |
+
$hook = $this->util->get_hook($this->get_id_raw());
|
54 |
+
foreach ( $content as $c ) {
|
55 |
+
// Trigger action
|
56 |
+
$res = apply_filters($hook, $success, $c->data, $this);
|
57 |
+
// Set result
|
58 |
+
if ( !!$success ) {
|
59 |
+
$success = $res;
|
60 |
+
}
|
61 |
+
}
|
62 |
+
|
63 |
+
// Set Status Message
|
64 |
+
$lbl = ( $success ) ? 'success' : 'failure';
|
65 |
+
$this->set_message($this->get_label($lbl));
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Get URI
|
70 |
+
* @see Admin_View::get_uri()
|
71 |
+
*/
|
72 |
+
public function get_uri($file = null, $format = null) {
|
73 |
+
return wp_nonce_url(add_query_arg($this->get_query_args(), remove_query_arg($this->get_query_args_remove(), $_SERVER['REQUEST_URI'])), $this->get_id());
|
74 |
+
}
|
75 |
+
|
76 |
+
protected function get_query_args() {
|
77 |
+
return array (
|
78 |
+
'action' => $this->add_prefix('admin'),
|
79 |
+
$this->add_prefix('type') => 'view',
|
80 |
+
$this->add_prefix('group') => 'action',
|
81 |
+
$this->add_prefix('obj') => $this->get_id_raw()
|
82 |
+
);
|
83 |
+
}
|
84 |
+
|
85 |
+
protected function get_query_args_remove() {
|
86 |
+
$args_r = array (
|
87 |
+
'_wpnonce',
|
88 |
+
$this->add_prefix('action')
|
89 |
+
);
|
90 |
+
|
91 |
+
return array_unique( array_merge( array_keys( $this->get_query_args() ), $args_r ) );
|
92 |
+
}
|
93 |
+
|
94 |
+
public function get_link_attr() {
|
95 |
+
return array (
|
96 |
+
'class' => $this->util->get_hook($this->get_id_raw()),
|
97 |
+
'onclick' => "return confirm('" . esc_js( $this->get_label('confirm') ) . "')"
|
98 |
+
);
|
99 |
+
}
|
100 |
+
|
101 |
+
/* Content */
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Save options
|
105 |
+
*/
|
106 |
+
public function add_content($id, $data) {
|
107 |
+
return parent::add_content($id, array('data' => $data));
|
108 |
+
}
|
109 |
+
}
|
includes/class.admin_menu.php
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Admin Menu
|
5 |
+
* Menus are top-level views in the Admin UI
|
6 |
+
* @package Simple Lightbox
|
7 |
+
* @subpackage Admin
|
8 |
+
* @author Archetyped
|
9 |
+
*/
|
10 |
+
class SLB_Admin_Menu extends SLB_Admin_View {
|
11 |
+
/* Properties */
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Menu position
|
15 |
+
* @var int
|
16 |
+
*/
|
17 |
+
protected $position = null;
|
18 |
+
|
19 |
+
/* Init */
|
20 |
+
|
21 |
+
public function __construct($id, $labels, $callback = null, $capability = null, $icon = null, $position = null) {
|
22 |
+
// Default
|
23 |
+
parent::__construct($id, $labels, $callback, $capability, $icon);
|
24 |
+
// Class specific
|
25 |
+
$this->set_position($position);
|
26 |
+
return $this;
|
27 |
+
}
|
28 |
+
|
29 |
+
/* Getters/Setters */
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Set menu position
|
33 |
+
* @return obj Current instance
|
34 |
+
*/
|
35 |
+
public function set_position($position) {
|
36 |
+
if ( is_int($position) )
|
37 |
+
$this->position = $position;
|
38 |
+
return $this;
|
39 |
+
}
|
40 |
+
}
|
includes/class.admin_page.php
ADDED
@@ -0,0 +1,182 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Admin Page
|
5 |
+
* Pages are part of a Menu
|
6 |
+
* @package Simple Lightbox
|
7 |
+
* @subpackage Admin
|
8 |
+
* @author Archetyped
|
9 |
+
*/
|
10 |
+
class SLB_Admin_Page extends SLB_Admin_View {
|
11 |
+
/* Properties */
|
12 |
+
|
13 |
+
protected $parent_required = true;
|
14 |
+
|
15 |
+
public $hook_prefix = 'admin_page';
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Required features/elements
|
19 |
+
*/
|
20 |
+
private $_required = array();
|
21 |
+
|
22 |
+
/* Init */
|
23 |
+
|
24 |
+
public function __construct($id, $parent, $labels, $callback = null, $capability = null) {
|
25 |
+
// Default
|
26 |
+
parent::__construct($id, $labels, $callback, $capability);
|
27 |
+
// Class specific
|
28 |
+
$this->set_parent($parent);
|
29 |
+
return $this;
|
30 |
+
}
|
31 |
+
|
32 |
+
/* Operations */
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Add content to page
|
36 |
+
* @uses parent::add_content()
|
37 |
+
* @param string $id Module ID
|
38 |
+
* @param string $title Module title
|
39 |
+
* @param mixed $callback Callback method or other data for building module UI
|
40 |
+
* @param string $context (optional) Context to add module to (Default: primary)
|
41 |
+
* @param string $priority (optional) Controls module ordering (Default: default)
|
42 |
+
* @param array $callback_args (optional) Additional data to pass callback (Default: NULL)
|
43 |
+
* @return object Page instance reference
|
44 |
+
*/
|
45 |
+
public function add_content($id, $title, $callback = null, $context = 'primary', $priority = 'default', $callback_args = null) {
|
46 |
+
return parent::add_content($id, array(
|
47 |
+
'id' => $id,
|
48 |
+
'title' => $title,
|
49 |
+
'callback' => $callback,
|
50 |
+
'context' => $context,
|
51 |
+
'priority' => $priority,
|
52 |
+
'callback_args' => $callback_args
|
53 |
+
)
|
54 |
+
);
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Parse content by parameters
|
59 |
+
* Sets content value
|
60 |
+
*/
|
61 |
+
protected function parse_content() {
|
62 |
+
// Get raw content
|
63 |
+
$raw = $this->get_content(false);
|
64 |
+
// Group by context
|
65 |
+
$content = array();
|
66 |
+
foreach ( $raw as $c ) {
|
67 |
+
// Add new context
|
68 |
+
if ( !isset($content[$c->context]) ) {
|
69 |
+
$content[$c->context] = array();
|
70 |
+
}
|
71 |
+
// Add item to context
|
72 |
+
$content[$c->context][] = $c;
|
73 |
+
}
|
74 |
+
return $content;
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Render content blocks
|
79 |
+
* @param string $context (optional) Context to render
|
80 |
+
*/
|
81 |
+
protected function render_content($context = 'primary') {
|
82 |
+
// Get content
|
83 |
+
$content = $this->get_content();
|
84 |
+
// Check for context
|
85 |
+
if ( !isset($content[$context]) ) {
|
86 |
+
return false;
|
87 |
+
}
|
88 |
+
$content = $content[$context];
|
89 |
+
$out = '';
|
90 |
+
// Render content
|
91 |
+
?>
|
92 |
+
<div class="content-wrap">
|
93 |
+
<?php
|
94 |
+
// Add meta boxes
|
95 |
+
$screen = get_current_screen();
|
96 |
+
foreach ( $content as $c ) {
|
97 |
+
$c->screen = $screen;
|
98 |
+
// Callback
|
99 |
+
if ( is_callable($c->callback) ) {
|
100 |
+
$callback = $c->callback;
|
101 |
+
add_meta_box($c->id, $c->title, $c->callback, $c->screen, $c->context, $c->priority, $c->callback_args);
|
102 |
+
} else {
|
103 |
+
// Let handlers build output
|
104 |
+
$this->util->do_action('render_content', $c->callback, $this, $c);
|
105 |
+
}
|
106 |
+
}
|
107 |
+
// Output meta boxes
|
108 |
+
do_meta_boxes($screen, $context, null);
|
109 |
+
?>
|
110 |
+
</div>
|
111 |
+
<?php
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Require form submission support
|
116 |
+
* @return obj Page instance
|
117 |
+
*/
|
118 |
+
public function require_form() {
|
119 |
+
$this->_require('form_submit');
|
120 |
+
return $this;
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Check if form submission is required
|
125 |
+
* @return bool TRUE if form submission required
|
126 |
+
*/
|
127 |
+
private function is_required_form() {
|
128 |
+
return $this->_is_required('form_submit');
|
129 |
+
}
|
130 |
+
|
131 |
+
/* Handlers */
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Default Page handler
|
135 |
+
* Builds content blocks
|
136 |
+
* @see this->init_menus() Set as callback for custom admin pages
|
137 |
+
* @uses current_user_can() to check if user has access to current page
|
138 |
+
* @uses wp_die() to end execution when user does not have permission to access page
|
139 |
+
*/
|
140 |
+
public function handle() {
|
141 |
+
if ( !current_user_can($this->get_capability()) )
|
142 |
+
wp_die(__('Access Denied', 'simple-lightbox'));
|
143 |
+
wp_enqueue_script('postbox');
|
144 |
+
?>
|
145 |
+
<div class="wrap slb">
|
146 |
+
<h2><?php esc_html_e( $this->get_label('header') ); ?></h2>
|
147 |
+
<?php
|
148 |
+
// Form submission support
|
149 |
+
if ( $this->is_required_form() ) {
|
150 |
+
// Build form output
|
151 |
+
$form_id = $this->add_prefix('admin_form_' . $this->get_id_raw());
|
152 |
+
?>
|
153 |
+
<form id="<?php esc_attr_e($form_id); ?>" name="<?php esc_attr_e($form_id); ?>" action="" method="post">
|
154 |
+
<?php
|
155 |
+
}
|
156 |
+
?>
|
157 |
+
<div class="metabox-holder columns-2">
|
158 |
+
<div class="content-primary postbox-container">
|
159 |
+
<?php
|
160 |
+
$this->render_content('primary');
|
161 |
+
?>
|
162 |
+
</div>
|
163 |
+
<div class="content-secondary postbox-container">
|
164 |
+
<?php
|
165 |
+
$this->render_content('secondary');
|
166 |
+
?>
|
167 |
+
</div>
|
168 |
+
</div>
|
169 |
+
<br class="clear" />
|
170 |
+
<?php
|
171 |
+
// Form submission support
|
172 |
+
if ( $this->is_required_form() ) {
|
173 |
+
submit_button();
|
174 |
+
?>
|
175 |
+
</form>
|
176 |
+
<?php
|
177 |
+
}
|
178 |
+
?>
|
179 |
+
</div>
|
180 |
+
<?php
|
181 |
+
}
|
182 |
+
}
|
includes/class.admin_section.php
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Admin Section
|
5 |
+
* Sections are part of a Page
|
6 |
+
* @package Simple Lightbox
|
7 |
+
* @subpackage Admin
|
8 |
+
* @author Archetyped
|
9 |
+
*/
|
10 |
+
class SLB_Admin_Section extends SLB_Admin_View {
|
11 |
+
/* Properties */
|
12 |
+
|
13 |
+
protected $parent_required = true;
|
14 |
+
protected $parent_custom = false;
|
15 |
+
|
16 |
+
/* Init */
|
17 |
+
|
18 |
+
public function __construct($id, $parent, $labels, $callback = null, $capability = null) {
|
19 |
+
// Default
|
20 |
+
parent::__construct($id, $labels, $callback, $capability);
|
21 |
+
// Class specific
|
22 |
+
$this->set_parent($parent);
|
23 |
+
return $this;
|
24 |
+
}
|
25 |
+
|
26 |
+
/* Getters/Setters */
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Retrieve URI
|
30 |
+
* @uses Admin_View::get_uri()
|
31 |
+
* @param string $file (optional) Base file name
|
32 |
+
* @param string $format (optional) String format
|
33 |
+
* @return string Section URI
|
34 |
+
*/
|
35 |
+
public function get_uri($file = null, $format = null) {
|
36 |
+
if ( !is_string($file) )
|
37 |
+
$file = 'options-' . $this->get_parent() . '.php';
|
38 |
+
if ( !is_string($format) )
|
39 |
+
$format = '%1$s#%2$s';
|
40 |
+
return parent::get_uri($file, $format);
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Retrieve formatted title for section
|
45 |
+
* Wraps title text in element with anchor so that it can be linked to
|
46 |
+
* @return string Title
|
47 |
+
*/
|
48 |
+
public function get_title() {
|
49 |
+
return sprintf('<div id="%1$s" class="%2$s">%3$s</div>', $this->get_id(), $this->add_prefix('section_head'), $this->get_label('title'));
|
50 |
+
}
|
51 |
+
}
|
includes/class.admin_view.php
ADDED
@@ -0,0 +1,529 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Admin View Base
|
5 |
+
* Core functionality Admin UI components
|
6 |
+
* @package Simple Lightbox
|
7 |
+
* @subpackage Admin
|
8 |
+
* @author Archetyped
|
9 |
+
*/
|
10 |
+
class SLB_Admin_View extends SLB_Base_Object {
|
11 |
+
/* Properties */
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Labels
|
15 |
+
* @var array (Associative)
|
16 |
+
*/
|
17 |
+
protected $labels = array();
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Function to handle building UI
|
21 |
+
* @var callback
|
22 |
+
*/
|
23 |
+
protected $callback = null;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Capability for access control
|
27 |
+
* @var string
|
28 |
+
*/
|
29 |
+
protected $capability = 'manage_options';
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Icon to use
|
33 |
+
* @var string
|
34 |
+
*/
|
35 |
+
protected $icon = null;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* View parent ID/Slug
|
39 |
+
* @var string
|
40 |
+
*/
|
41 |
+
protected $parent = null;
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Whether parent is a custom view or a default WP one
|
45 |
+
* @var bool
|
46 |
+
*/
|
47 |
+
protected $parent_custom = true;
|
48 |
+
|
49 |
+
/**
|
50 |
+
* If view requires a parent
|
51 |
+
* @var bool
|
52 |
+
*/
|
53 |
+
protected $parent_required = false;
|
54 |
+
|
55 |
+
/**
|
56 |
+
* WP-Generated hook name for view
|
57 |
+
* @var string
|
58 |
+
*/
|
59 |
+
protected $hookname = null;
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Raw content parameters
|
63 |
+
* Stores pre-rendered content parameters
|
64 |
+
* Items stored by ID (key)
|
65 |
+
* @var array
|
66 |
+
*/
|
67 |
+
protected $content_raw = array();
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Parsed content parameters
|
71 |
+
* @var array
|
72 |
+
*/
|
73 |
+
protected $content = array();
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Messages to be displayed
|
77 |
+
* Indexed Array
|
78 |
+
* @var array
|
79 |
+
*/
|
80 |
+
protected $messages = array();
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Required properties
|
84 |
+
* Associative array
|
85 |
+
* > Key: Property name
|
86 |
+
* > Value: Required data type
|
87 |
+
* @var array
|
88 |
+
*/
|
89 |
+
private $required = array();
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Default required properties
|
93 |
+
* Merged into $required array with this->init_required()
|
94 |
+
* @see this->required for more information
|
95 |
+
* @var array
|
96 |
+
*/
|
97 |
+
private $_required = array ( 'id' => 'string', 'labels' => 'array' );
|
98 |
+
|
99 |
+
/* Init */
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Constructor
|
103 |
+
* @return obj Current instance
|
104 |
+
*/
|
105 |
+
public function __construct($id, $labels, $callback = null, $capability = null, $icon = null) {
|
106 |
+
$props = array(
|
107 |
+
'labels' => $labels,
|
108 |
+
'callback' => $callback,
|
109 |
+
'capability' => $capability,
|
110 |
+
'icon' => $icon,
|
111 |
+
);
|
112 |
+
parent::__construct($id, $props);
|
113 |
+
$this->init_required();
|
114 |
+
return $this;
|
115 |
+
}
|
116 |
+
|
117 |
+
protected function init_required() {
|
118 |
+
$this->required = array_merge($this->_required, $this->required);
|
119 |
+
// Check for parent requirement
|
120 |
+
if ( $this->parent_required )
|
121 |
+
$this->required['parent'] = 'string';
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Set required feature
|
126 |
+
* @param string $feature Required feature
|
127 |
+
*/
|
128 |
+
protected function _require($feature) {
|
129 |
+
if ( !isset($this->_required[$feature]) ) {
|
130 |
+
$this->_required[$feature] = true;
|
131 |
+
}
|
132 |
+
return $this;
|
133 |
+
}
|
134 |
+
|
135 |
+
/**
|
136 |
+
* Check if feature is required
|
137 |
+
* @param string $feature Feature to check for
|
138 |
+
* @return bool TRUE if feature required
|
139 |
+
*/
|
140 |
+
protected function _is_required($feature) {
|
141 |
+
return ( isset($this->_required[$feature]) ) ? true : false;
|
142 |
+
}
|
143 |
+
|
144 |
+
/* Property Methods */
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Retrieve ID (Formatted by default)
|
148 |
+
* @param bool $formatted (optional) Whether ID should be formatted for external use or not
|
149 |
+
* @return string ID
|
150 |
+
*/
|
151 |
+
public function get_id($formatted = true) {
|
152 |
+
$id = parent::get_id();
|
153 |
+
if ( $formatted )
|
154 |
+
$this->add_prefix_ref($id);
|
155 |
+
return $id;
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Retrieve raw ID
|
160 |
+
* @return string Raw ID
|
161 |
+
*/
|
162 |
+
public function get_id_raw() {
|
163 |
+
return $this->get_id(false);
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Retrieve label
|
168 |
+
* Uses first label (or default if defined) if specified type does not exist
|
169 |
+
* @param string $type Label type to retrieve
|
170 |
+
* @param string $default (optional) Default value if label type does not exist
|
171 |
+
* @return string Label text
|
172 |
+
*/
|
173 |
+
public function get_label($type, $default = null) {
|
174 |
+
// Retrieve existing label type
|
175 |
+
if ( $this->has_label($type) )
|
176 |
+
return $this->labels[$type];
|
177 |
+
// Use default label if type is not set
|
178 |
+
if ( empty($default) && !empty($this->labels) ) {
|
179 |
+
reset($this->labels);
|
180 |
+
$default = current($this->labels);
|
181 |
+
}
|
182 |
+
|
183 |
+
return ( empty($default) ) ? '' : $default;
|
184 |
+
}
|
185 |
+
|
186 |
+
/**
|
187 |
+
* Set text labels
|
188 |
+
* @param array|string $labels
|
189 |
+
* @return obj Current instance
|
190 |
+
*/
|
191 |
+
public function set_labels($labels) {
|
192 |
+
if ( empty($labels) )
|
193 |
+
return this;
|
194 |
+
// Single string
|
195 |
+
if ( is_string($labels) ) {
|
196 |
+
$labels = array ( $labels );
|
197 |
+
}
|
198 |
+
|
199 |
+
// Array
|
200 |
+
if ( is_array($labels) ) {
|
201 |
+
// Merge with existing labels
|
202 |
+
if ( empty($this->labels) || !is_array($this->labels) ) {
|
203 |
+
$this->labels = array();
|
204 |
+
}
|
205 |
+
$this->labels = array_merge($this->labels, $labels);
|
206 |
+
}
|
207 |
+
return $this;
|
208 |
+
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Set single text label
|
212 |
+
* @uses this->set_labels()
|
213 |
+
* @param string $type Label type to set
|
214 |
+
* @param string $value Label value
|
215 |
+
* @return obj Current instance
|
216 |
+
*/
|
217 |
+
public function set_label($type, $value) {
|
218 |
+
if ( is_string($type) && is_string($value) ) {
|
219 |
+
$label = array( $type => $value );
|
220 |
+
$this->set_labels($label);
|
221 |
+
}
|
222 |
+
return $this;
|
223 |
+
}
|
224 |
+
|
225 |
+
/**
|
226 |
+
* Checks if specified label is set on view
|
227 |
+
* @param string $type Label type
|
228 |
+
* @return bool TRUE if label exists, FALSE otherwise
|
229 |
+
*/
|
230 |
+
public function has_label($type) {
|
231 |
+
return ( isset($this->labels[$type]) );
|
232 |
+
}
|
233 |
+
|
234 |
+
/* Content */
|
235 |
+
|
236 |
+
/**
|
237 |
+
* Add content block to view
|
238 |
+
* Child classes define method functionality
|
239 |
+
* @param string $id Content block ID
|
240 |
+
* @param array $args Content arguments (Defined by child class), converted to an object
|
241 |
+
* @return obj Current View instance
|
242 |
+
*/
|
243 |
+
public function add_content($id, $args) {
|
244 |
+
// Save parameters
|
245 |
+
$this->content_raw[$id] = (object) $args;
|
246 |
+
// Clear parsed content
|
247 |
+
$this->content = array();
|
248 |
+
// Return instance reference
|
249 |
+
return $this;
|
250 |
+
}
|
251 |
+
|
252 |
+
/**
|
253 |
+
* Retrieve content
|
254 |
+
*/
|
255 |
+
protected function get_content($parsed = true) {
|
256 |
+
$content = $this->content_raw;
|
257 |
+
if ( $parsed ) {
|
258 |
+
// Return previously parsed content
|
259 |
+
if ( !empty($this->content) ) {
|
260 |
+
$content = $this->content;
|
261 |
+
}
|
262 |
+
elseif ( !empty($this->content_raw) ) {
|
263 |
+
// Parse content before returning
|
264 |
+
$content = $this->content = $this->parse_content();
|
265 |
+
}
|
266 |
+
}
|
267 |
+
return $content;
|
268 |
+
}
|
269 |
+
|
270 |
+
/**
|
271 |
+
* Parse content
|
272 |
+
* Child classes define functionality
|
273 |
+
* @return array Parsed content
|
274 |
+
*/
|
275 |
+
protected function parse_content() {
|
276 |
+
return $this->get_content(false);
|
277 |
+
}
|
278 |
+
|
279 |
+
/**
|
280 |
+
* Check if content has been added to view
|
281 |
+
* @return bool TRUE if content added
|
282 |
+
*/
|
283 |
+
protected function has_content() {
|
284 |
+
$raw = $this->get_content(false);
|
285 |
+
return !empty($raw);
|
286 |
+
}
|
287 |
+
|
288 |
+
/**
|
289 |
+
* Render content
|
290 |
+
*/
|
291 |
+
protected function render_content($context = 'default') {}
|
292 |
+
|
293 |
+
/**
|
294 |
+
* Retrieve view messages
|
295 |
+
* @return array Messages
|
296 |
+
*/
|
297 |
+
protected function &get_messages() {
|
298 |
+
if ( !is_array($this->messages) )
|
299 |
+
$this->messages = array();
|
300 |
+
return $this->messages;
|
301 |
+
}
|
302 |
+
|
303 |
+
/**
|
304 |
+
* Save message
|
305 |
+
* @param string $text Message text
|
306 |
+
* @return obj Current instance
|
307 |
+
*/
|
308 |
+
public function set_message($text) {
|
309 |
+
$msgs =& $this->get_messages();
|
310 |
+
$text = trim($text);
|
311 |
+
if ( empty($msgs) && !empty($text) )
|
312 |
+
$this->util->add_filter('admin_messages', $this->m('do_messages'), 10, 1, false);
|
313 |
+
$msgs[] = $text;
|
314 |
+
return $this;
|
315 |
+
}
|
316 |
+
|
317 |
+
/**
|
318 |
+
* Add messages to array
|
319 |
+
* Called by internal `admin_messages` filter hook
|
320 |
+
* @param array $msgs Aggregated messages
|
321 |
+
* @return array Merged messages array
|
322 |
+
*/
|
323 |
+
public function do_messages($msgs = array()) {
|
324 |
+
$m =& $this->get_messages();
|
325 |
+
if ( !empty($m) )
|
326 |
+
$msgs = array_merge($msgs, $m);
|
327 |
+
return $msgs;
|
328 |
+
}
|
329 |
+
|
330 |
+
/**
|
331 |
+
* Retrieve view callback
|
332 |
+
* @return callback Callback (Default: standard handler method)
|
333 |
+
*/
|
334 |
+
public function get_callback() {
|
335 |
+
return ( $this->has_callback() ) ? $this->callback : $this->m('handle');
|
336 |
+
}
|
337 |
+
|
338 |
+
/**
|
339 |
+
* Set callback function for building item
|
340 |
+
* @param callback $callback Callback function to use
|
341 |
+
* @return obj Current instance
|
342 |
+
*/
|
343 |
+
public function set_callback($callback) {
|
344 |
+
$this->callback = ( is_callable($callback) ) ? $callback : null;
|
345 |
+
return $this;
|
346 |
+
}
|
347 |
+
|
348 |
+
/**
|
349 |
+
* Check if callback set
|
350 |
+
* @return bool TRUE if callback is set
|
351 |
+
*/
|
352 |
+
protected function has_callback() {
|
353 |
+
return ( !empty($this->callback) ) ? true : false;
|
354 |
+
}
|
355 |
+
|
356 |
+
/**
|
357 |
+
* Run callback
|
358 |
+
*/
|
359 |
+
public function do_callback() {
|
360 |
+
call_user_func($this->get_callback());
|
361 |
+
}
|
362 |
+
|
363 |
+
/**
|
364 |
+
* Retrieve capability
|
365 |
+
* @return string Capability
|
366 |
+
*/
|
367 |
+
public function get_capability() {
|
368 |
+
return $this->capability;
|
369 |
+
}
|
370 |
+
|
371 |
+
/**
|
372 |
+
* Set capability for access control
|
373 |
+
* @param string $capability Capability
|
374 |
+
* @return obj Current instance
|
375 |
+
*/
|
376 |
+
public function set_capability($capability) {
|
377 |
+
if ( is_string($capability) && !empty($capability) )
|
378 |
+
$this->capability = $capability;
|
379 |
+
return $this;
|
380 |
+
}
|
381 |
+
|
382 |
+
/**
|
383 |
+
* Set icon
|
384 |
+
* @param string $icon Icon URI
|
385 |
+
* @return obj Current instance
|
386 |
+
*/
|
387 |
+
public function set_icon($icon) {
|
388 |
+
if ( !empty($icon) && is_string($icon) )
|
389 |
+
$this->icon = $icon;
|
390 |
+
return $this;
|
391 |
+
}
|
392 |
+
|
393 |
+
protected function get_hookname() {
|
394 |
+
return ( empty($this->hookname) ) ? '' : $this->hookname;
|
395 |
+
}
|
396 |
+
|
397 |
+
/**
|
398 |
+
* Set hookname
|
399 |
+
* @param string $hookname Hookname value
|
400 |
+
* @return obj Current instance
|
401 |
+
*/
|
402 |
+
public function set_hookname($hookname) {
|
403 |
+
if ( !empty($hookname) && is_string($hookname) )
|
404 |
+
$this->hookname = $hookname;
|
405 |
+
return $this;
|
406 |
+
}
|
407 |
+
|
408 |
+
/**
|
409 |
+
* Retrieve parent
|
410 |
+
* Formats parent ID for custom parents
|
411 |
+
* @uses parent::get_parent()
|
412 |
+
* @return string Parent ID
|
413 |
+
*/
|
414 |
+
public function get_parent() {
|
415 |
+
$parent = parent::get_parent();
|
416 |
+
return ( $this->is_parent_custom() ) ? $this->add_prefix($parent) : $parent;
|
417 |
+
}
|
418 |
+
|
419 |
+
/**
|
420 |
+
* Set parent for view
|
421 |
+
* @param string $parent Parent ID
|
422 |
+
* @return obj Current instance
|
423 |
+
*/
|
424 |
+
public function set_parent($parent) {
|
425 |
+
if ( $this->parent_required ) {
|
426 |
+
if ( !empty($parent) && is_string($parent) )
|
427 |
+
$this->parent = $parent;
|
428 |
+
} else {
|
429 |
+
$this->parent = null;
|
430 |
+
}
|
431 |
+
return $this;
|
432 |
+
}
|
433 |
+
|
434 |
+
/**
|
435 |
+
* Specify whether parent is a custom view or a WP view
|
436 |
+
* @param bool $custom (optional) TRUE if custom, FALSE if WP
|
437 |
+
* @return obj Current instance
|
438 |
+
*/
|
439 |
+
protected function set_parent_custom($custom = true) {
|
440 |
+
if ( $this->parent_required ) {
|
441 |
+
$this->parent_custom = !!$custom;
|
442 |
+
}
|
443 |
+
return $this;
|
444 |
+
}
|
445 |
+
|
446 |
+
/**
|
447 |
+
* Set parent as WP view
|
448 |
+
* @uses this->set_parent_custom()
|
449 |
+
* @return obj Current instance
|
450 |
+
*/
|
451 |
+
public function set_parent_wp() {
|
452 |
+
$this->set_parent_custom(false);
|
453 |
+
return $this;
|
454 |
+
}
|
455 |
+
|
456 |
+
/**
|
457 |
+
* Get view URI
|
458 |
+
* URI Structures:
|
459 |
+
* > Top Level Menus: admin.php?page={menu_id}
|
460 |
+
* > Pages: [parent_page_file.php|admin.php]?page={page_id}
|
461 |
+
* > Section: [parent_menu_uri]#{section_id}
|
462 |
+
*
|
463 |
+
* @uses $admin_page_hooks to determine if page is child of default WP page
|
464 |
+
* @param string $file (optional) Base file name
|
465 |
+
* @param string $format (optional) Format string for URI
|
466 |
+
* @return string Object URI
|
467 |
+
*/
|
468 |
+
public function get_uri($file = null, $format = null) {
|
469 |
+
static $page_hooks = null;
|
470 |
+
$uri = '';
|
471 |
+
if ( empty($file) )
|
472 |
+
$file = 'admin.php';
|
473 |
+
if ( $this->is_child() ) {
|
474 |
+
$parent = str_replace('_page_' . $this->get_id(), '', $this->get_hookname());
|
475 |
+
if ( is_null($page_hooks) ) {
|
476 |
+
$page_hooks = array_flip($GLOBALS['admin_page_hooks']);
|
477 |
+
}
|
478 |
+
if ( isset($page_hooks[$parent]) )
|
479 |
+
$file = $page_hooks[$parent];
|
480 |
+
}
|
481 |
+
|
482 |
+
if ( empty($format) ) {
|
483 |
+
$delim = ( strpos($file, '?') === false ) ? '?' : '&';
|
484 |
+
$format = '%1$s' . $delim . 'page=%2$s';
|
485 |
+
}
|
486 |
+
$uri = sprintf($format, $file, $this->get_id());
|
487 |
+
|
488 |
+
return $uri;
|
489 |
+
}
|
490 |
+
|
491 |
+
/* Handlers */
|
492 |
+
|
493 |
+
/**
|
494 |
+
* Default View handler
|
495 |
+
* Used as callback when none set
|
496 |
+
*/
|
497 |
+
public function handle() {}
|
498 |
+
|
499 |
+
/* Validation */
|
500 |
+
|
501 |
+
/**
|
502 |
+
* Check if instance is valid based on required properties/data types
|
503 |
+
* @return bool TRUE if valid, FALSE if not valid
|
504 |
+
*/
|
505 |
+
public function is_valid() {
|
506 |
+
$valid = true;
|
507 |
+
foreach ( $this->required as $prop => $type ) {
|
508 |
+
if ( empty($this->{$prop} )
|
509 |
+
|| ( !empty($type) && is_string($type) && ( $f = 'is_' . $type ) && function_exists($f) && !$f($this->{$prop}) ) ) {
|
510 |
+
$valid = false;
|
511 |
+
break;
|
512 |
+
}
|
513 |
+
}
|
514 |
+
return $valid;
|
515 |
+
}
|
516 |
+
|
517 |
+
protected function is_child() {
|
518 |
+
return $this->parent_required;
|
519 |
+
}
|
520 |
+
|
521 |
+
protected function is_parent_custom() {
|
522 |
+
return ( $this->is_child() && $this->parent_custom ) ? true : false;
|
523 |
+
}
|
524 |
+
|
525 |
+
public function is_parent_wp() {
|
526 |
+
return ( $this->is_child() && !$this->parent_custom ) ? true : false;
|
527 |
+
}
|
528 |
+
|
529 |
+
}
|
includes/class.base.php
CHANGED
@@ -83,7 +83,7 @@ class SLB_Base {
|
|
83 |
*
|
84 |
* Array is processed and converted to an object on init
|
85 |
*/
|
86 |
-
|
87 |
'scripts' => array(),
|
88 |
'styles' => array()
|
89 |
);
|
@@ -100,7 +100,7 @@ class SLB_Base {
|
|
100 |
* Options
|
101 |
* @var SLB_Options
|
102 |
*/
|
103 |
-
|
104 |
|
105 |
/**
|
106 |
* Admin
|
@@ -116,11 +116,11 @@ class SLB_Base {
|
|
116 |
function __construct() {
|
117 |
$this->util = new SLB_Utilities($this);
|
118 |
if ( $this->can('init') ) {
|
119 |
-
$hook = '
|
120 |
-
if (
|
121 |
$this->_init();
|
122 |
} else {
|
123 |
-
add_action($hook, $this->m('_init'));
|
124 |
}
|
125 |
}
|
126 |
}
|
@@ -139,22 +139,22 @@ class SLB_Base {
|
|
139 |
if ( $this->_init || !isset($this) || !$this->can('init') )
|
140 |
return false;
|
141 |
$this->_init = true;
|
142 |
-
//Environment
|
143 |
$this->_env();
|
144 |
|
145 |
if ( $this->can('control') ) {
|
146 |
-
//Options
|
147 |
$this->_options();
|
148 |
|
149 |
-
//Admin
|
150 |
if ( is_admin() )
|
151 |
$this->_admin();
|
152 |
}
|
153 |
|
154 |
-
//Hooks
|
155 |
$this->_hooks();
|
156 |
|
157 |
-
//Client files
|
158 |
$this->_client_files();
|
159 |
}
|
160 |
|
@@ -165,42 +165,45 @@ class SLB_Base {
|
|
165 |
if ( !$this->can('singleton') ) {
|
166 |
return false;
|
167 |
}
|
168 |
-
//Localization
|
169 |
$ldir = 'l10n';
|
170 |
$lpath = $this->util->get_plugin_file_path($ldir, array(false, false));
|
171 |
$lpath_abs = $this->util->get_file_path($ldir);
|
172 |
if ( is_dir($lpath_abs) ) {
|
173 |
-
load_plugin_textdomain('
|
174 |
}
|
175 |
|
176 |
-
//Context
|
177 |
add_action( ( is_admin() ) ? 'admin_print_footer_scripts' : 'wp_footer', $this->util->m('set_client_context'), $this->util->priority('client_footer_output') );
|
178 |
}
|
179 |
|
|
|
|
|
|
|
|
|
|
|
|
|
180 |
/**
|
181 |
* Initialize options
|
182 |
* To be called by child class
|
183 |
*/
|
184 |
-
protected function
|
185 |
$class = $this->util->get_class('Options');
|
186 |
$key = 'options';
|
187 |
if ( $this->shares($key) ) {
|
188 |
-
/**
|
189 |
-
* @var SLB_Options
|
190 |
-
*/
|
191 |
$opts = $this->gvar($key);
|
192 |
-
//Setup options instance
|
193 |
-
if ( !
|
194 |
$opts = $this->gvar($key, new $class());
|
195 |
}
|
196 |
} else {
|
197 |
$opts = new $class();
|
198 |
}
|
199 |
-
//Load options
|
200 |
if ( $this->is_options_valid($options_config, false) ) {
|
201 |
$opts->load($options_config);
|
202 |
}
|
203 |
-
//Set instance property
|
204 |
$this->options = $opts;
|
205 |
}
|
206 |
|
@@ -215,18 +218,15 @@ class SLB_Base {
|
|
215 |
$class = $this->util->get_class('Admin');
|
216 |
$key = 'admin';
|
217 |
if ( $this->shares($key) ) {
|
218 |
-
/**
|
219 |
-
* @var SLB_Admin
|
220 |
-
*/
|
221 |
$adm = $this->gvar($key);
|
222 |
-
//Setup options instance
|
223 |
-
if ( !
|
224 |
$adm = $this->gvar($key, new $class($this));
|
225 |
}
|
226 |
} else {
|
227 |
$adm = new $class($this);
|
228 |
}
|
229 |
-
//Set instance property
|
230 |
$this->admin = $adm;
|
231 |
}
|
232 |
|
@@ -235,12 +235,12 @@ class SLB_Base {
|
|
235 |
*/
|
236 |
protected function _hooks() {
|
237 |
$base = $this->util->get_plugin_base_file();
|
238 |
-
//Activation
|
239 |
$func_activate = '_activate';
|
240 |
if ( method_exists($this, $func_activate) )
|
241 |
register_activation_hook($base, $this->m($func_activate));
|
242 |
|
243 |
-
//Deactivation
|
244 |
$func_deactivate = '_deactivate';
|
245 |
if ( method_exists($this, $func_deactivate) )
|
246 |
register_deactivation_hook($base, $this->m($func_deactivate));
|
@@ -249,25 +249,36 @@ class SLB_Base {
|
|
249 |
/**
|
250 |
* Initialize client files
|
251 |
*/
|
252 |
-
protected function _client_files() {
|
|
|
|
|
|
|
|
|
253 |
foreach ( $this->client_files as $key => $val ) {
|
254 |
-
if (
|
255 |
-
$this->client_files[$key]
|
256 |
-
$g =& $this->client_files[$key];
|
257 |
-
if ( is_array($g) && !empty($g) ) {
|
258 |
-
$g = $this->util->parse_client_files($g, $key);
|
259 |
}
|
260 |
-
//Remove empty file groups
|
261 |
-
if ( empty($
|
262 |
unset($this->client_files[$key]);
|
|
|
263 |
}
|
264 |
-
|
265 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
266 |
add_action('init', $this->m('register_client_files'));
|
267 |
|
268 |
-
//Enqueue
|
269 |
-
$
|
270 |
-
|
|
|
|
|
|
|
271 |
}
|
272 |
|
273 |
/**
|
@@ -283,10 +294,10 @@ class SLB_Base {
|
|
283 |
if ( !$func )
|
284 |
continue;
|
285 |
foreach ( $files as $f ) {
|
286 |
-
//Get file URI
|
287 |
-
$f->file = ( !$this->util->is_file($f->file) && is_callable($f->file) ) ? call_user_func($f->file) : $this->util->get_file_url($f->file);
|
288 |
$params = array($f->id, $f->file, $f->deps, $v);
|
289 |
-
//Set additional parameters based on file type (script, style, etc.)
|
290 |
switch ( $type ) {
|
291 |
case 'scripts':
|
292 |
$params[] = $f->in_footer;
|
@@ -295,7 +306,7 @@ class SLB_Base {
|
|
295 |
$params[] = $f->media;
|
296 |
break;
|
297 |
}
|
298 |
-
//Register file
|
299 |
call_user_func_array($func, $params);
|
300 |
}
|
301 |
}
|
@@ -305,53 +316,74 @@ class SLB_Base {
|
|
305 |
* Enqueues files for client output (scripts/styles) based on context
|
306 |
* @uses `admin_enqueue_scripts` Action hook depending on context
|
307 |
* @uses `wp_enqueue_scripts` Action hook depending on context
|
|
|
308 |
* @return void
|
309 |
*/
|
310 |
-
function enqueue_client_files() {
|
311 |
-
//
|
|
|
|
|
|
|
|
|
312 |
foreach ( $this->client_files as $type => $files ) {
|
313 |
$func = $this->get_client_files_handler($type, 'enqueue');
|
314 |
if ( !$func ) {
|
315 |
continue;
|
316 |
}
|
317 |
-
foreach ( $files as $f ) {
|
318 |
-
//Skip shadow files
|
319 |
-
if ( !$f->enqueue ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
320 |
continue;
|
321 |
}
|
322 |
$load = true;
|
323 |
-
//Global Callback
|
324 |
if ( is_callable($f->callback) && !call_user_func($f->callback) ) {
|
325 |
$load = false;
|
326 |
}
|
327 |
-
//Context
|
328 |
if ( $load && !empty($f->context) ) {
|
329 |
-
//Reset $load before evaluating context
|
330 |
$load = false;
|
331 |
-
//Iterate through contexts
|
332 |
foreach ( $f->context as $ctx ) {
|
333 |
-
//Context + Callback
|
334 |
if ( is_array($ctx) ) {
|
335 |
-
//Stop checking context if callback is invalid
|
336 |
if ( !is_callable($ctx[1]) || !call_user_func($ctx[1]) )
|
337 |
continue;
|
338 |
$ctx = $ctx[0];
|
339 |
}
|
340 |
-
//Stop checking context if valid context found
|
341 |
if ( $this->util->is_context($ctx) ) {
|
342 |
$load = true;
|
343 |
break;
|
344 |
}
|
345 |
}
|
346 |
}
|
347 |
-
|
348 |
-
//Load valid file
|
349 |
if ( $load ) {
|
|
|
|
|
350 |
$func($f->id);
|
351 |
}
|
352 |
}
|
353 |
}
|
354 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
355 |
|
356 |
/**
|
357 |
* Build function name for handling client operations
|
@@ -462,7 +494,7 @@ class SLB_Base {
|
|
462 |
|
463 |
protected function can($cap) {
|
464 |
if ( is_null($this->caps) ) {
|
465 |
-
//Build capabilities based on instance properties
|
466 |
$this->caps = array(
|
467 |
'init' => ( 'object' != $this->mode ) ? true : false,
|
468 |
'singleton' => ( !!$this->model ) ? true : false,
|
@@ -491,10 +523,10 @@ class SLB_Base {
|
|
491 |
}
|
492 |
$ret = $val;
|
493 |
if ( null !== $val ) {
|
494 |
-
//Set Value
|
495 |
$g[$name] = $val;
|
496 |
} elseif ( isset($g[$name]) ) {
|
497 |
-
//Retrieve variable
|
498 |
$ret = $g[$name];
|
499 |
}
|
500 |
return $ret;
|
@@ -514,7 +546,7 @@ class SLB_Base {
|
|
514 |
function is_options_valid($data, $check_var = true) {
|
515 |
$class = $this->util->get_class('Options');
|
516 |
$ret = ( empty($data) || !is_array($data) || !class_exists($class) ) ? false : true;
|
517 |
-
if ( $ret && $check_var && !
|
518 |
$ret = false;
|
519 |
return $ret;
|
520 |
}
|
83 |
*
|
84 |
* Array is processed and converted to an object on init
|
85 |
*/
|
86 |
+
private $client_files = array (
|
87 |
'scripts' => array(),
|
88 |
'styles' => array()
|
89 |
);
|
100 |
* Options
|
101 |
* @var SLB_Options
|
102 |
*/
|
103 |
+
protected $options = null;
|
104 |
|
105 |
/**
|
106 |
* Admin
|
116 |
function __construct() {
|
117 |
$this->util = new SLB_Utilities($this);
|
118 |
if ( $this->can('init') ) {
|
119 |
+
$hook = 'init';
|
120 |
+
if ( did_action($hook) || self::$_init_passed ) {
|
121 |
$this->_init();
|
122 |
} else {
|
123 |
+
add_action($hook, $this->m('_init'), 1);
|
124 |
}
|
125 |
}
|
126 |
}
|
139 |
if ( $this->_init || !isset($this) || !$this->can('init') )
|
140 |
return false;
|
141 |
$this->_init = true;
|
142 |
+
// Environment
|
143 |
$this->_env();
|
144 |
|
145 |
if ( $this->can('control') ) {
|
146 |
+
// Options
|
147 |
$this->_options();
|
148 |
|
149 |
+
// Admin
|
150 |
if ( is_admin() )
|
151 |
$this->_admin();
|
152 |
}
|
153 |
|
154 |
+
// Hooks
|
155 |
$this->_hooks();
|
156 |
|
157 |
+
// Client files
|
158 |
$this->_client_files();
|
159 |
}
|
160 |
|
165 |
if ( !$this->can('singleton') ) {
|
166 |
return false;
|
167 |
}
|
168 |
+
// Localization
|
169 |
$ldir = 'l10n';
|
170 |
$lpath = $this->util->get_plugin_file_path($ldir, array(false, false));
|
171 |
$lpath_abs = $this->util->get_file_path($ldir);
|
172 |
if ( is_dir($lpath_abs) ) {
|
173 |
+
load_plugin_textdomain('simple-lightbox', false, $lpath);
|
174 |
}
|
175 |
|
176 |
+
// Context
|
177 |
add_action( ( is_admin() ) ? 'admin_print_footer_scripts' : 'wp_footer', $this->util->m('set_client_context'), $this->util->priority('client_footer_output') );
|
178 |
}
|
179 |
|
180 |
+
/**
|
181 |
+
* Initialize options
|
182 |
+
* To be implemented in child classes
|
183 |
+
*/
|
184 |
+
protected function _options() {}
|
185 |
+
|
186 |
/**
|
187 |
* Initialize options
|
188 |
* To be called by child class
|
189 |
*/
|
190 |
+
protected function _set_options($options_config = null) {
|
191 |
$class = $this->util->get_class('Options');
|
192 |
$key = 'options';
|
193 |
if ( $this->shares($key) ) {
|
|
|
|
|
|
|
194 |
$opts = $this->gvar($key);
|
195 |
+
// Setup options instance
|
196 |
+
if ( !($opts instanceof $class) ) {
|
197 |
$opts = $this->gvar($key, new $class());
|
198 |
}
|
199 |
} else {
|
200 |
$opts = new $class();
|
201 |
}
|
202 |
+
// Load options
|
203 |
if ( $this->is_options_valid($options_config, false) ) {
|
204 |
$opts->load($options_config);
|
205 |
}
|
206 |
+
// Set instance property
|
207 |
$this->options = $opts;
|
208 |
}
|
209 |
|
218 |
$class = $this->util->get_class('Admin');
|
219 |
$key = 'admin';
|
220 |
if ( $this->shares($key) ) {
|
|
|
|
|
|
|
221 |
$adm = $this->gvar($key);
|
222 |
+
// Setup options instance
|
223 |
+
if ( !($adm instanceof $class) ) {
|
224 |
$adm = $this->gvar($key, new $class($this));
|
225 |
}
|
226 |
} else {
|
227 |
$adm = new $class($this);
|
228 |
}
|
229 |
+
// Set instance property
|
230 |
$this->admin = $adm;
|
231 |
}
|
232 |
|
235 |
*/
|
236 |
protected function _hooks() {
|
237 |
$base = $this->util->get_plugin_base_file();
|
238 |
+
// Activation
|
239 |
$func_activate = '_activate';
|
240 |
if ( method_exists($this, $func_activate) )
|
241 |
register_activation_hook($base, $this->m($func_activate));
|
242 |
|
243 |
+
// Deactivation
|
244 |
$func_deactivate = '_deactivate';
|
245 |
if ( method_exists($this, $func_deactivate) )
|
246 |
register_deactivation_hook($base, $this->m($func_deactivate));
|
249 |
/**
|
250 |
* Initialize client files
|
251 |
*/
|
252 |
+
protected function _client_files($files = null) {
|
253 |
+
// Validation
|
254 |
+
if ( !is_array($files) || empty($files) ) {
|
255 |
+
return false;
|
256 |
+
}
|
257 |
foreach ( $this->client_files as $key => $val ) {
|
258 |
+
if ( isset($files[$key]) && is_array($files[$key]) || !empty($files[$key]) ) {
|
259 |
+
$this->client_files[$key] = $this->util->parse_client_files($files[$key], $key);
|
|
|
|
|
|
|
260 |
}
|
261 |
+
// Remove empty file groups
|
262 |
+
if ( empty($this->client_files[$key]) ) {
|
263 |
unset($this->client_files[$key]);
|
264 |
+
}
|
265 |
}
|
266 |
+
|
267 |
+
|
268 |
+
// Stop if no files are set for registration
|
269 |
+
if ( empty($this->client_files) ) {
|
270 |
+
return false;
|
271 |
+
}
|
272 |
+
|
273 |
+
// Register
|
274 |
add_action('init', $this->m('register_client_files'));
|
275 |
|
276 |
+
// Enqueue
|
277 |
+
$hk_prfx = ( ( is_admin() ) ? 'admin' : 'wp' );
|
278 |
+
$hk_enqueue = $hk_prfx . '_enqueue_scripts' ;
|
279 |
+
$hk_enqueue_ft = $hk_prfx . '_footer';
|
280 |
+
add_action($hk_enqueue, $this->m('enqueue_client_files'), 10, 0);
|
281 |
+
add_action($hk_enqueue_ft, $this->m('enqueue_client_files_footer'), 1);
|
282 |
}
|
283 |
|
284 |
/**
|
294 |
if ( !$func )
|
295 |
continue;
|
296 |
foreach ( $files as $f ) {
|
297 |
+
// Get file URI
|
298 |
+
$f->file = ( !$this->util->is_file($f->file) && is_callable($f->file) ) ? call_user_func($f->file) : $this->util->get_file_url($f->file, true);
|
299 |
$params = array($f->id, $f->file, $f->deps, $v);
|
300 |
+
// Set additional parameters based on file type (script, style, etc.)
|
301 |
switch ( $type ) {
|
302 |
case 'scripts':
|
303 |
$params[] = $f->in_footer;
|
306 |
$params[] = $f->media;
|
307 |
break;
|
308 |
}
|
309 |
+
// Register file
|
310 |
call_user_func_array($func, $params);
|
311 |
}
|
312 |
}
|
316 |
* Enqueues files for client output (scripts/styles) based on context
|
317 |
* @uses `admin_enqueue_scripts` Action hook depending on context
|
318 |
* @uses `wp_enqueue_scripts` Action hook depending on context
|
319 |
+
* @param bool $footer (optional) Whether to enqueue footer files (Default: No)
|
320 |
* @return void
|
321 |
*/
|
322 |
+
function enqueue_client_files($footer = false) {
|
323 |
+
// Validate
|
324 |
+
if ( !is_bool($footer) ) {
|
325 |
+
$footer = false;
|
326 |
+
}
|
327 |
+
// Enqueue files
|
328 |
foreach ( $this->client_files as $type => $files ) {
|
329 |
$func = $this->get_client_files_handler($type, 'enqueue');
|
330 |
if ( !$func ) {
|
331 |
continue;
|
332 |
}
|
333 |
+
foreach ( $files as $fkey => $f ) {
|
334 |
+
// Skip previously-enqueued files and shadow files
|
335 |
+
if ( $f->enqueued || !$f->enqueue ) {
|
336 |
+
continue;
|
337 |
+
}
|
338 |
+
// Enqueue files only for current location (header/footer)
|
339 |
+
if ( isset($f->in_footer) ) {
|
340 |
+
if ( $f->in_footer != $footer ) {
|
341 |
+
continue;
|
342 |
+
}
|
343 |
+
} elseif ( $footer ) {
|
344 |
continue;
|
345 |
}
|
346 |
$load = true;
|
347 |
+
// Global Callback
|
348 |
if ( is_callable($f->callback) && !call_user_func($f->callback) ) {
|
349 |
$load = false;
|
350 |
}
|
351 |
+
// Context
|
352 |
if ( $load && !empty($f->context) ) {
|
353 |
+
// Reset $load before evaluating context
|
354 |
$load = false;
|
355 |
+
// Iterate through contexts
|
356 |
foreach ( $f->context as $ctx ) {
|
357 |
+
// Context + Callback
|
358 |
if ( is_array($ctx) ) {
|
359 |
+
// Stop checking context if callback is invalid
|
360 |
if ( !is_callable($ctx[1]) || !call_user_func($ctx[1]) )
|
361 |
continue;
|
362 |
$ctx = $ctx[0];
|
363 |
}
|
364 |
+
// Stop checking context if valid context found
|
365 |
if ( $this->util->is_context($ctx) ) {
|
366 |
$load = true;
|
367 |
break;
|
368 |
}
|
369 |
}
|
370 |
}
|
371 |
+
// Load valid file
|
|
|
372 |
if ( $load ) {
|
373 |
+
// Mark file as enqueued
|
374 |
+
$this->client_files[$type]->{$fkey}->enqueued = true;
|
375 |
$func($f->id);
|
376 |
}
|
377 |
}
|
378 |
}
|
379 |
}
|
380 |
+
|
381 |
+
/**
|
382 |
+
* Enqueue client files in the footer
|
383 |
+
*/
|
384 |
+
public function enqueue_client_files_footer() {
|
385 |
+
$this->enqueue_client_files(true);
|
386 |
+
}
|
387 |
|
388 |
/**
|
389 |
* Build function name for handling client operations
|
494 |
|
495 |
protected function can($cap) {
|
496 |
if ( is_null($this->caps) ) {
|
497 |
+
// Build capabilities based on instance properties
|
498 |
$this->caps = array(
|
499 |
'init' => ( 'object' != $this->mode ) ? true : false,
|
500 |
'singleton' => ( !!$this->model ) ? true : false,
|
523 |
}
|
524 |
$ret = $val;
|
525 |
if ( null !== $val ) {
|
526 |
+
// Set Value
|
527 |
$g[$name] = $val;
|
528 |
} elseif ( isset($g[$name]) ) {
|
529 |
+
// Retrieve variable
|
530 |
$ret = $g[$name];
|
531 |
}
|
532 |
return $ret;
|
546 |
function is_options_valid($data, $check_var = true) {
|
547 |
$class = $this->util->get_class('Options');
|
548 |
$ret = ( empty($data) || !is_array($data) || !class_exists($class) ) ? false : true;
|
549 |
+
if ( $ret && $check_var && !($this->options instanceof $class) )
|
550 |
$ret = false;
|
551 |
return $ret;
|
552 |
}
|
includes/class.base_collection.php
CHANGED
@@ -64,7 +64,7 @@ class SLB_Base_Collection extends SLB_Base {
|
|
64 |
* Calls `init` action if collection has a hook prefix
|
65 |
*/
|
66 |
private function init() {
|
67 |
-
//Initialize
|
68 |
if ( is_null($this->items) ) {
|
69 |
$this->items = array();
|
70 |
if ( !empty($this->hook_prefix) ) {
|
@@ -84,10 +84,10 @@ class SLB_Base_Collection extends SLB_Base {
|
|
84 |
if ( !is_array($items) ) {
|
85 |
$items = array($items);
|
86 |
}
|
87 |
-
//Validate item type
|
88 |
if ( !is_null($this->item_type) ) {
|
89 |
foreach ( $items as $idx => $item ) {
|
90 |
-
//Remove invalid items
|
91 |
if ( !( $item instanceof $this->item_type ) ) {
|
92 |
unset($items[$idx]);
|
93 |
}
|
@@ -100,7 +100,7 @@ class SLB_Base_Collection extends SLB_Base {
|
|
100 |
}
|
101 |
|
102 |
protected function item_valid($item) {
|
103 |
-
//Validate item type
|
104 |
return ( empty($this->item_type) || ( $item instanceof $this->item_type ) ) ? true : false;
|
105 |
}
|
106 |
|
@@ -123,7 +123,7 @@ class SLB_Base_Collection extends SLB_Base {
|
|
123 |
protected function get_key($item, $check_existing = false) {
|
124 |
$ret = null;
|
125 |
if ( $this->unique || !!$check_existing ) {
|
126 |
-
//Check for item in collection
|
127 |
if ( $this->has($item) ) {
|
128 |
$ret = array_search($item, $this->items);
|
129 |
} elseif ( !!$this->key_prop && ( is_object($item) || is_array($item) ) ) {
|
@@ -150,9 +150,9 @@ class SLB_Base_Collection extends SLB_Base {
|
|
150 |
*/
|
151 |
public function add($item, $meta = null) {
|
152 |
$this->init();
|
153 |
-
//Validate
|
154 |
if ( $this->item_valid($item) ) {
|
155 |
-
//Add item to collection
|
156 |
$key = $this->get_key($item);
|
157 |
if ( !$key ) {
|
158 |
$this->items[] = $item;
|
@@ -160,7 +160,7 @@ class SLB_Base_Collection extends SLB_Base {
|
|
160 |
} else {
|
161 |
$this->items[$key] = $item;
|
162 |
}
|
163 |
-
//Add metadata
|
164 |
if ( !!$key && is_array($meta) ) {
|
165 |
$this->add_meta($key, $meta);
|
166 |
}
|
@@ -195,7 +195,7 @@ class SLB_Base_Collection extends SLB_Base {
|
|
195 |
* @return bool TRUE if item(s) in collection
|
196 |
*/
|
197 |
public function has($items) {
|
198 |
-
//Attempt to locate item
|
199 |
return false;
|
200 |
}
|
201 |
|
@@ -207,7 +207,7 @@ class SLB_Base_Collection extends SLB_Base {
|
|
207 |
*/
|
208 |
public function get($args = null) {
|
209 |
$this->init();
|
210 |
-
//Parse args
|
211 |
$args_default = array(
|
212 |
'orderby' => null,
|
213 |
'order' => 'DESC',
|
@@ -220,42 +220,42 @@ class SLB_Base_Collection extends SLB_Base {
|
|
220 |
|
221 |
/* Sort */
|
222 |
if ( !is_null($r['orderby']) ) {
|
223 |
-
//Validate
|
224 |
if ( !is_array($r['orderby']) ) {
|
225 |
$r['orderby'] = array('item' => $r['orderby']);
|
226 |
}
|
227 |
-
//Prep
|
228 |
$metas = ( isset($r['orderby']['meta']) ) ? $this->items_meta : array();
|
229 |
-
//Sort
|
230 |
foreach ( $r['orderby'] as $stype => $sval ) {
|
231 |
/* Meta sorting */
|
232 |
if ( 'meta' == $stype ) {
|
233 |
-
//Build sorting buckets
|
234 |
$buckets = array();
|
235 |
foreach ( $metas as $item => $meta ) {
|
236 |
if ( !isset($meta[$sval]) ) {
|
237 |
continue;
|
238 |
}
|
239 |
-
//Create bucket
|
240 |
$idx = $meta[$sval];
|
241 |
if ( !isset($buckets[ $idx ]) ) {
|
242 |
$buckets[ $idx ] = array();
|
243 |
}
|
244 |
-
//Add item to bucket
|
245 |
$buckets[ $idx ][] = $item;
|
246 |
}
|
247 |
-
//Sort buckets
|
248 |
ksort($buckets, SORT_NUMERIC);
|
249 |
-
//Merge buckets
|
250 |
$pool = array();
|
251 |
foreach ( $buckets as $bucket ) {
|
252 |
$pool = array_merge($pool, $bucket);
|
253 |
}
|
254 |
-
//Fill with items
|
255 |
$items = array_merge( array_fill_keys($pool, null), $items);
|
256 |
}
|
257 |
}
|
258 |
-
//Clear workers
|
259 |
unset($stype, $sval, $buckets, $pool, $item, $metas, $meta, $idx);
|
260 |
}
|
261 |
return $items;
|
@@ -272,18 +272,18 @@ class SLB_Base_Collection extends SLB_Base {
|
|
272 |
* @return object Current instance
|
273 |
*/
|
274 |
protected function add_meta($item, $meta_key, $meta_value = null, $reset = false) {
|
275 |
-
//Validate
|
276 |
if ( $this->key_valid($item) && ( is_array($meta_key) || is_string($meta_key) ) ) {
|
277 |
-
//Prepare metadata
|
278 |
$meta = ( is_string($meta_key) ) ? array($meta_key => $meta_value) : $meta_key;
|
279 |
-
//Reset existing meta (if necessary)
|
280 |
if ( is_array($meta_key) && func_num_args() > 2) {
|
281 |
$reset = func_get_arg(2);
|
282 |
}
|
283 |
if ( !!$reset ) {
|
284 |
unset($this->items_meta[$item]);
|
285 |
}
|
286 |
-
//Add metadata
|
287 |
if ( !isset($this->items_meta[$item]) ) {
|
288 |
$this->items_meta[$item] = array();
|
289 |
}
|
@@ -300,10 +300,10 @@ class SLB_Base_Collection extends SLB_Base {
|
|
300 |
protected function remove_meta($item, $meta_key = null) {
|
301 |
if ( $this->key_valid($item) && isset($this->items_meta[$item]) ) {
|
302 |
if ( is_string($meta_key) ) {
|
303 |
-
//Remove specific meta value
|
304 |
unset($this->items_meta[$item][$meta_key]);
|
305 |
} else {
|
306 |
-
//Remove all metadata
|
307 |
unset($this->items_meta[$item]);
|
308 |
}
|
309 |
}
|
@@ -335,15 +335,15 @@ class SLB_Base_Collection extends SLB_Base {
|
|
335 |
* Prints output
|
336 |
*/
|
337 |
function build($build_vars = array()) {
|
338 |
-
//Parse vars
|
339 |
$this->parse_build_vars($build_vars);
|
340 |
-
$this->util->do_action_ref_array('build_init', array(
|
341 |
-
//Pre-build output
|
342 |
-
$this->util->do_action_ref_array('build_pre', array(
|
343 |
-
//Build groups
|
344 |
$this->build_groups();
|
345 |
-
//Post-build output
|
346 |
-
$this->util->do_action_ref_array('build_post', array(
|
347 |
}
|
348 |
|
349 |
/**
|
64 |
* Calls `init` action if collection has a hook prefix
|
65 |
*/
|
66 |
private function init() {
|
67 |
+
// Initialize
|
68 |
if ( is_null($this->items) ) {
|
69 |
$this->items = array();
|
70 |
if ( !empty($this->hook_prefix) ) {
|
84 |
if ( !is_array($items) ) {
|
85 |
$items = array($items);
|
86 |
}
|
87 |
+
// Validate item type
|
88 |
if ( !is_null($this->item_type) ) {
|
89 |
foreach ( $items as $idx => $item ) {
|
90 |
+
// Remove invalid items
|
91 |
if ( !( $item instanceof $this->item_type ) ) {
|
92 |
unset($items[$idx]);
|
93 |
}
|
100 |
}
|
101 |
|
102 |
protected function item_valid($item) {
|
103 |
+
// Validate item type
|
104 |
return ( empty($this->item_type) || ( $item instanceof $this->item_type ) ) ? true : false;
|
105 |
}
|
106 |
|
123 |
protected function get_key($item, $check_existing = false) {
|
124 |
$ret = null;
|
125 |
if ( $this->unique || !!$check_existing ) {
|
126 |
+
// Check for item in collection
|
127 |
if ( $this->has($item) ) {
|
128 |
$ret = array_search($item, $this->items);
|
129 |
} elseif ( !!$this->key_prop && ( is_object($item) || is_array($item) ) ) {
|
150 |
*/
|
151 |
public function add($item, $meta = null) {
|
152 |
$this->init();
|
153 |
+
// Validate
|
154 |
if ( $this->item_valid($item) ) {
|
155 |
+
// Add item to collection
|
156 |
$key = $this->get_key($item);
|
157 |
if ( !$key ) {
|
158 |
$this->items[] = $item;
|
160 |
} else {
|
161 |
$this->items[$key] = $item;
|
162 |
}
|
163 |
+
// Add metadata
|
164 |
if ( !!$key && is_array($meta) ) {
|
165 |
$this->add_meta($key, $meta);
|
166 |
}
|
195 |
* @return bool TRUE if item(s) in collection
|
196 |
*/
|
197 |
public function has($items) {
|
198 |
+
// Attempt to locate item
|
199 |
return false;
|
200 |
}
|
201 |
|
207 |
*/
|
208 |
public function get($args = null) {
|
209 |
$this->init();
|
210 |
+
// Parse args
|
211 |
$args_default = array(
|
212 |
'orderby' => null,
|
213 |
'order' => 'DESC',
|
220 |
|
221 |
/* Sort */
|
222 |
if ( !is_null($r['orderby']) ) {
|
223 |
+
// Validate
|
224 |
if ( !is_array($r['orderby']) ) {
|
225 |
$r['orderby'] = array('item' => $r['orderby']);
|
226 |
}
|
227 |
+
// Prep
|
228 |
$metas = ( isset($r['orderby']['meta']) ) ? $this->items_meta : array();
|
229 |
+
// Sort
|
230 |
foreach ( $r['orderby'] as $stype => $sval ) {
|
231 |
/* Meta sorting */
|
232 |
if ( 'meta' == $stype ) {
|
233 |
+
// Build sorting buckets
|
234 |
$buckets = array();
|
235 |
foreach ( $metas as $item => $meta ) {
|
236 |
if ( !isset($meta[$sval]) ) {
|
237 |
continue;
|
238 |
}
|
239 |
+
// Create bucket
|
240 |
$idx = $meta[$sval];
|
241 |
if ( !isset($buckets[ $idx ]) ) {
|
242 |
$buckets[ $idx ] = array();
|
243 |
}
|
244 |
+
// Add item to bucket
|
245 |
$buckets[ $idx ][] = $item;
|
246 |
}
|
247 |
+
// Sort buckets
|
248 |
ksort($buckets, SORT_NUMERIC);
|
249 |
+
// Merge buckets
|
250 |
$pool = array();
|
251 |
foreach ( $buckets as $bucket ) {
|
252 |
$pool = array_merge($pool, $bucket);
|
253 |
}
|
254 |
+
// Fill with items
|
255 |
$items = array_merge( array_fill_keys($pool, null), $items);
|
256 |
}
|
257 |
}
|
258 |
+
// Clear workers
|
259 |
unset($stype, $sval, $buckets, $pool, $item, $metas, $meta, $idx);
|
260 |
}
|
261 |
return $items;
|
272 |
* @return object Current instance
|
273 |
*/
|
274 |
protected function add_meta($item, $meta_key, $meta_value = null, $reset = false) {
|
275 |
+
// Validate
|
276 |
if ( $this->key_valid($item) && ( is_array($meta_key) || is_string($meta_key) ) ) {
|
277 |
+
// Prepare metadata
|
278 |
$meta = ( is_string($meta_key) ) ? array($meta_key => $meta_value) : $meta_key;
|
279 |
+
// Reset existing meta (if necessary)
|
280 |
if ( is_array($meta_key) && func_num_args() > 2) {
|
281 |
$reset = func_get_arg(2);
|
282 |
}
|
283 |
if ( !!$reset ) {
|
284 |
unset($this->items_meta[$item]);
|
285 |
}
|
286 |
+
// Add metadata
|
287 |
if ( !isset($this->items_meta[$item]) ) {
|
288 |
$this->items_meta[$item] = array();
|
289 |
}
|
300 |
protected function remove_meta($item, $meta_key = null) {
|
301 |
if ( $this->key_valid($item) && isset($this->items_meta[$item]) ) {
|
302 |
if ( is_string($meta_key) ) {
|
303 |
+
// Remove specific meta value
|
304 |
unset($this->items_meta[$item][$meta_key]);
|
305 |
} else {
|
306 |
+
// Remove all metadata
|
307 |
unset($this->items_meta[$item]);
|
308 |
}
|
309 |
}
|
335 |
* Prints output
|
336 |
*/
|
337 |
function build($build_vars = array()) {
|
338 |
+
// Parse vars
|
339 |
$this->parse_build_vars($build_vars);
|
340 |
+
$this->util->do_action_ref_array('build_init', array($this));
|
341 |
+
// Pre-build output
|
342 |
+
$this->util->do_action_ref_array('build_pre', array($this));
|
343 |
+
// Build groups
|
344 |
$this->build_groups();
|
345 |
+
// Post-build output
|
346 |
+
$this->util->do_action_ref_array('build_post', array($this));
|
347 |
}
|
348 |
|
349 |
/**
|
includes/class.base_object.php
CHANGED
@@ -98,7 +98,7 @@ class SLB_Base_Object extends SLB_Base {
|
|
98 |
protected function set_props($props) {
|
99 |
if ( is_array($props) && !empty($props) ) {
|
100 |
foreach ( $props as $key => $val ) {
|
101 |
-
//Check for setter method
|
102 |
$m = 'set_' . $key;
|
103 |
if ( method_exists($this, $m) ) {
|
104 |
$this->{$m}($val);
|
@@ -142,9 +142,9 @@ class SLB_Base_Object extends SLB_Base {
|
|
142 |
$ret = array();
|
143 |
$curr = $this;
|
144 |
while ( $curr->has_parent() ) {
|
145 |
-
//Add ancestor
|
146 |
$ret[] = $par = $curr->get_parent();
|
147 |
-
//Get next ancestor
|
148 |
$curr = $par;
|
149 |
}
|
150 |
return $ret;
|
@@ -161,20 +161,41 @@ class SLB_Base_Object extends SLB_Base {
|
|
161 |
*/
|
162 |
protected function add_file($type, $handle, $src, $deps = array()) {
|
163 |
if ( is_string($type) && is_string($handle) && is_string($src) ) {
|
164 |
-
//Validate dependencies
|
165 |
if ( !is_array($deps) ) {
|
166 |
$deps = array();
|
167 |
}
|
168 |
-
//Init file group
|
169 |
if ( !isset($this->files[$type]) || !is_array($this->files[$type]) ) {
|
170 |
$this->files[$type] = array();
|
171 |
}
|
172 |
-
//Add file to group
|
173 |
$this->files[$type][$handle] = array('handle' => $handle, 'uri' => $src, 'deps' => $deps);
|
174 |
}
|
175 |
return $this;
|
176 |
}
|
177 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
/**
|
179 |
* Retrieve files
|
180 |
* All files or a specific group of files can be retrieved
|
@@ -200,19 +221,39 @@ class SLB_Base_Object extends SLB_Base {
|
|
200 |
* @return array|null File properties (Default: NULL)
|
201 |
*/
|
202 |
protected function get_file($type, $handle, $format = null) {
|
203 |
-
//Get files
|
204 |
$files = $this->get_files($type);
|
205 |
-
//Get specified file
|
206 |
$ret = ( is_string($type) && isset($files[$handle]) ) ? $files[$handle] : null;
|
207 |
-
//Format return value
|
208 |
if ( !empty($ret) && !!$format ) {
|
209 |
switch ( $format ) {
|
210 |
case 'uri':
|
211 |
$ret = $ret['uri'];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
212 |
break;
|
213 |
case 'object':
|
214 |
$ret = (object) $ret;
|
215 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
216 |
}
|
217 |
}
|
218 |
return $ret;
|
@@ -232,8 +273,27 @@ class SLB_Base_Object extends SLB_Base {
|
|
232 |
* Retrieve stylesheet files
|
233 |
* @return array Stylesheet files
|
234 |
*/
|
235 |
-
public function get_styles() {
|
236 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
237 |
}
|
238 |
|
239 |
/**
|
98 |
protected function set_props($props) {
|
99 |
if ( is_array($props) && !empty($props) ) {
|
100 |
foreach ( $props as $key => $val ) {
|
101 |
+
// Check for setter method
|
102 |
$m = 'set_' . $key;
|
103 |
if ( method_exists($this, $m) ) {
|
104 |
$this->{$m}($val);
|
142 |
$ret = array();
|
143 |
$curr = $this;
|
144 |
while ( $curr->has_parent() ) {
|
145 |
+
// Add ancestor
|
146 |
$ret[] = $par = $curr->get_parent();
|
147 |
+
// Get next ancestor
|
148 |
$curr = $par;
|
149 |
}
|
150 |
return $ret;
|
161 |
*/
|
162 |
protected function add_file($type, $handle, $src, $deps = array()) {
|
163 |
if ( is_string($type) && is_string($handle) && is_string($src) ) {
|
164 |
+
// Validate dependencies
|
165 |
if ( !is_array($deps) ) {
|
166 |
$deps = array();
|
167 |
}
|
168 |
+
// Init file group
|
169 |
if ( !isset($this->files[$type]) || !is_array($this->files[$type]) ) {
|
170 |
$this->files[$type] = array();
|
171 |
}
|
172 |
+
// Add file to group
|
173 |
$this->files[$type][$handle] = array('handle' => $handle, 'uri' => $src, 'deps' => $deps);
|
174 |
}
|
175 |
return $this;
|
176 |
}
|
177 |
|
178 |
+
/**
|
179 |
+
* Add multiple files
|
180 |
+
* @param string $type Group to add files to
|
181 |
+
* @param array $files Files to add
|
182 |
+
* @see add_file() for file parameters
|
183 |
+
* @return object Current instance
|
184 |
+
*/
|
185 |
+
protected function add_files($type, $files) {
|
186 |
+
if ( !is_array($files) || empty($files) )
|
187 |
+
return false;
|
188 |
+
$m = $this->m('add_file');
|
189 |
+
foreach ( $files as $file ) {
|
190 |
+
if ( !is_array($file) || empty($file) ) {
|
191 |
+
continue;
|
192 |
+
}
|
193 |
+
array_unshift($file, $type);
|
194 |
+
call_user_func_array($m, $file);
|
195 |
+
}
|
196 |
+
return $this;
|
197 |
+
}
|
198 |
+
|
199 |
/**
|
200 |
* Retrieve files
|
201 |
* All files or a specific group of files can be retrieved
|
221 |
* @return array|null File properties (Default: NULL)
|
222 |
*/
|
223 |
protected function get_file($type, $handle, $format = null) {
|
224 |
+
// Get files
|
225 |
$files = $this->get_files($type);
|
226 |
+
// Get specified file
|
227 |
$ret = ( is_string($type) && isset($files[$handle]) ) ? $files[$handle] : null;
|
228 |
+
// Format return value
|
229 |
if ( !empty($ret) && !!$format ) {
|
230 |
switch ( $format ) {
|
231 |
case 'uri':
|
232 |
$ret = $ret['uri'];
|
233 |
+
// Normalize URI
|
234 |
+
if ( !$this->util->is_uri($ret) ) {
|
235 |
+
$ret = $this->util->normalize_path(site_url(), $ret);
|
236 |
+
}
|
237 |
+
break;
|
238 |
+
case 'path':
|
239 |
+
$ret = $ret['uri'];
|
240 |
+
// Normalize path
|
241 |
+
if ( !$this->util->is_uri($ret) ) {
|
242 |
+
$ret = $this->util->get_relative_path($ret);
|
243 |
+
$ret = $this->util->normalize_path(ABSPATH, $ret);
|
244 |
+
}
|
245 |
break;
|
246 |
case 'object':
|
247 |
$ret = (object) $ret;
|
248 |
break;
|
249 |
+
case 'contents':
|
250 |
+
$ret = $ret['uri'];
|
251 |
+
if ( !$this->util->is_uri($ret) ) {
|
252 |
+
$ret = $this->util->normalize_path(site_url(), $ret);
|
253 |
+
}
|
254 |
+
$get = wp_safe_remote_get($ret);
|
255 |
+
$ret = ( !is_wp_error($get) && 200 == $get['response']['code'] ) ? $get['body'] : '';
|
256 |
+
break;
|
257 |
}
|
258 |
}
|
259 |
return $ret;
|
273 |
* Retrieve stylesheet files
|
274 |
* @return array Stylesheet files
|
275 |
*/
|
276 |
+
public function get_styles($opts = null) {
|
277 |
+
$files = $this->get_files('styles');
|
278 |
+
if ( is_array($opts) ) {
|
279 |
+
$opts = (object) $opts;
|
280 |
+
}
|
281 |
+
if ( is_object($opts) && !empty($opts) ) {
|
282 |
+
// Parse options
|
283 |
+
// URI Format
|
284 |
+
if ( isset($opts->uri_format) ) {
|
285 |
+
foreach ( $files as $hdl => $props ) {
|
286 |
+
switch ( $opts->uri_format ) {
|
287 |
+
case 'full':
|
288 |
+
if ( !$this->util->is_uri($props['uri']) ) {
|
289 |
+
$files[$hdl]['uri'] = $this->util->normalize_path(site_url(), $props['uri']);
|
290 |
+
}
|
291 |
+
break;
|
292 |
+
}
|
293 |
+
}
|
294 |
+
}
|
295 |
+
}
|
296 |
+
return $files;
|
297 |
}
|
298 |
|
299 |
/**
|
includes/class.component.php
CHANGED
@@ -40,6 +40,77 @@ class SLB_Component extends SLB_Base_Object {
|
|
40 |
return $this->name;
|
41 |
}
|
42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
/* Helpers */
|
44 |
|
45 |
/**
|
@@ -50,7 +121,7 @@ class SLB_Component extends SLB_Base_Object {
|
|
50 |
public function is_valid() {
|
51 |
$ret = parent::is_valid();
|
52 |
if ( $ret ) {
|
53 |
-
//Check required component properties
|
54 |
$props = array_merge($this->props_required_base, $this->props_required);
|
55 |
foreach ( $props as $prop ) {
|
56 |
if ( !isset($this->{$prop}) || empty($this->{$prop}) ) {
|
@@ -61,29 +132,4 @@ class SLB_Component extends SLB_Base_Object {
|
|
61 |
}
|
62 |
return $ret;
|
63 |
}
|
64 |
-
|
65 |
-
/* Client */
|
66 |
-
|
67 |
-
/**
|
68 |
-
* Set client script file
|
69 |
-
* @see Base_Object::add_script()
|
70 |
-
* @param string $src Script URI
|
71 |
-
* @param array $deps (optional) File dependencies
|
72 |
-
*/
|
73 |
-
public function set_client_script($src, $deps = array()) {
|
74 |
-
if ( is_array($src) ) {
|
75 |
-
list($src, $deps) = func_get_arg(0);
|
76 |
-
}
|
77 |
-
return $this->add_script('client', $src, $deps);
|
78 |
-
}
|
79 |
-
|
80 |
-
/**
|
81 |
-
* Retrieve client script
|
82 |
-
* @see Base_Object::get_script()
|
83 |
-
* @param string $format (optional) Data format of return value
|
84 |
-
* @return mixed Client script data (formatted according to $format parameter)
|
85 |
-
*/
|
86 |
-
public function get_client_script($format = null) {
|
87 |
-
return $this->get_script('client', $format);
|
88 |
-
}
|
89 |
}
|
40 |
return $this->name;
|
41 |
}
|
42 |
|
43 |
+
public function set_scripts($scripts) {
|
44 |
+
$this->add_files('scripts', $scripts);
|
45 |
+
}
|
46 |
+
|
47 |
+
public function set_styles($styles) {
|
48 |
+
$this->add_files('styles', $styles);
|
49 |
+
}
|
50 |
+
|
51 |
+
/* Assets */
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Get formatted handle for file
|
55 |
+
* @param string $base_handle Base handle to format
|
56 |
+
* @return string Formatted handle
|
57 |
+
*/
|
58 |
+
public function get_handle($base_handle) {
|
59 |
+
return $this->add_prefix( array('asset', $this->get_id(), $base_handle), '-');
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Enqueue files in client
|
64 |
+
* @param string $type (optional) Type of file to load (singular) (Default: All client file types)
|
65 |
+
*/
|
66 |
+
public function enqueue_client_files($type = null) {
|
67 |
+
if ( empty($type) ) {
|
68 |
+
$type = array ( 'script', 'style');
|
69 |
+
}
|
70 |
+
if ( !is_array($type) ) {
|
71 |
+
$type = array ( $type );
|
72 |
+
}
|
73 |
+
foreach ( $type as $t ) {
|
74 |
+
$m = (object) array (
|
75 |
+
'get' => $this->m('get_' . $t . 's'),
|
76 |
+
'enqueue' => 'wp_enqueue_' . $t,
|
77 |
+
);
|
78 |
+
$v = $this->util->get_plugin_version();
|
79 |
+
$files = call_user_func($m->get);
|
80 |
+
$param_final = ( 'script' == $t ) ? true : 'all';
|
81 |
+
foreach ( $files as $f ) {
|
82 |
+
$f = (object) $f;
|
83 |
+
// Format handle
|
84 |
+
$handle = $this->get_handle($f->handle);
|
85 |
+
|
86 |
+
// Format dependencies
|
87 |
+
$deps = array();
|
88 |
+
foreach ( $f->deps as $dep ) {
|
89 |
+
if ( $this->util->has_wrapper($dep) ) {
|
90 |
+
$dep = $this->get_handle( $this->util->remove_wrapper($dep) );
|
91 |
+
}
|
92 |
+
$deps[] = $dep;
|
93 |
+
}
|
94 |
+
call_user_func($m->enqueue, $handle, $f->uri, $deps, $v, $param_final);
|
95 |
+
}
|
96 |
+
unset($files, $f, $param_final, $handle, $deps, $dep);
|
97 |
+
}
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Enqueue scripts
|
102 |
+
*/
|
103 |
+
public function enqueue_scripts() {
|
104 |
+
$this->enqueue_client_files('script');
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Enqueue styles
|
109 |
+
*/
|
110 |
+
public function enqueue_styles() {
|
111 |
+
$this->enqueue_client_files('style');
|
112 |
+
}
|
113 |
+
|
114 |
/* Helpers */
|
115 |
|
116 |
/**
|
121 |
public function is_valid() {
|
122 |
$ret = parent::is_valid();
|
123 |
if ( $ret ) {
|
124 |
+
// Check required component properties
|
125 |
$props = array_merge($this->props_required_base, $this->props_required);
|
126 |
foreach ( $props as $prop ) {
|
127 |
if ( !isset($this->{$prop}) || empty($this->{$prop}) ) {
|
132 |
}
|
133 |
return $ret;
|
134 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
135 |
}
|
includes/class.content_handler.php
CHANGED
@@ -15,6 +15,12 @@ class SLB_Content_Handler extends SLB_Component {
|
|
15 |
*/
|
16 |
protected $match;
|
17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
/* Matching */
|
19 |
|
20 |
/**
|
@@ -47,11 +53,30 @@ class SLB_Content_Handler extends SLB_Component {
|
|
47 |
* @param string $uri URI to check for match
|
48 |
* @return bool TRUE if handler matches URI
|
49 |
*/
|
50 |
-
public function match($uri) {
|
51 |
$ret = false;
|
52 |
if ( !!$uri && is_string($uri) && $this->has_match() ) {
|
53 |
-
$ret = call_user_func($this->get_match(), $uri);
|
54 |
}
|
55 |
return $ret;
|
56 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
}
|
15 |
*/
|
16 |
protected $match;
|
17 |
|
18 |
+
/**
|
19 |
+
* Custom attributes
|
20 |
+
* @var callback
|
21 |
+
*/
|
22 |
+
protected $attributes;
|
23 |
+
|
24 |
/* Matching */
|
25 |
|
26 |
/**
|
53 |
* @param string $uri URI to check for match
|
54 |
* @return bool TRUE if handler matches URI
|
55 |
*/
|
56 |
+
public function match($uri, $uri_raw = null) {
|
57 |
$ret = false;
|
58 |
if ( !!$uri && is_string($uri) && $this->has_match() ) {
|
59 |
+
$ret = call_user_func($this->get_match(), $uri, $uri_raw);
|
60 |
}
|
61 |
return $ret;
|
62 |
}
|
63 |
+
|
64 |
+
/* Attributes */
|
65 |
+
|
66 |
+
public function set_attributes($callback) {
|
67 |
+
$this->attributes = ( is_callable($callback) ) ? $callback : null;
|
68 |
+
return $this;
|
69 |
+
}
|
70 |
+
|
71 |
+
public function get_attributes() {
|
72 |
+
$ret = array();
|
73 |
+
// Callback
|
74 |
+
if ( !is_null($this->attributes) ) {
|
75 |
+
$ret = call_user_func($this->attributes);
|
76 |
+
}
|
77 |
+
// Filter
|
78 |
+
$hook = sprintf('content_handler_%s_attributes', $this->get_id());
|
79 |
+
$ret = $this->util->apply_filters($hook, $ret);
|
80 |
+
return ( is_array($ret) ) ? $ret : array();
|
81 |
+
}
|
82 |
}
|
includes/class.content_handlers.php
CHANGED
@@ -31,9 +31,9 @@ class SLB_Content_Handlers extends SLB_Collection_Controller {
|
|
31 |
|
32 |
protected function _hooks() {
|
33 |
parent::_hooks();
|
34 |
-
$this->util->add_action('init', $this->m('init_defaults'));
|
35 |
-
|
36 |
-
|
37 |
}
|
38 |
|
39 |
/* Collection Management */
|
@@ -50,10 +50,10 @@ class SLB_Content_Handlers extends SLB_Collection_Controller {
|
|
50 |
public function add($id, $props = array(), $priority = 10) {
|
51 |
$this->clear_cache();
|
52 |
if ( is_string($id) ) {
|
53 |
-
//Initialize new handler
|
54 |
$handler = new $this->item_type($id, $props);
|
55 |
} else {
|
56 |
-
//Remap parameters
|
57 |
$handler = func_get_arg(0);
|
58 |
if ( func_num_args() == 2 ) {
|
59 |
$priority = func_get_arg(1);
|
@@ -62,7 +62,7 @@ class SLB_Content_Handlers extends SLB_Collection_Controller {
|
|
62 |
if ( !is_int($priority) ) {
|
63 |
$priority = 10;
|
64 |
}
|
65 |
-
//Add to collection
|
66 |
return parent::add($handler, array('priority' => $priority));
|
67 |
}
|
68 |
|
@@ -92,12 +92,13 @@ class SLB_Content_Handlers extends SLB_Collection_Controller {
|
|
92 |
* Retrieves handlers sorted by priority
|
93 |
* @see parent::get()
|
94 |
* @uses get_cache()
|
|
|
95 |
* @return array Handlers
|
96 |
*/
|
97 |
-
public function get() {
|
98 |
$items = $this->get_cache();
|
99 |
if ( empty($items) ) {
|
100 |
-
//Retrieve items
|
101 |
$items = parent::get( array( 'orderby' => array('meta' => 'priority') ) );
|
102 |
$this->update_cache($items);
|
103 |
}
|
@@ -107,20 +108,30 @@ class SLB_Content_Handlers extends SLB_Collection_Controller {
|
|
107 |
/**
|
108 |
* Get matching handler for URI
|
109 |
* @param string $uri URI to find match for
|
110 |
-
* @return
|
|
|
|
|
|
|
111 |
*/
|
112 |
public function match($uri) {
|
|
|
113 |
foreach ( $this->get() as $handler ) {
|
114 |
-
|
115 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
$hid = $handler->get_id();
|
117 |
if ( !isset($this->request_matches[$hid]) ) {
|
118 |
$this->request_matches[$hid] = $handler;
|
119 |
}
|
120 |
-
|
121 |
}
|
122 |
}
|
123 |
-
return
|
124 |
}
|
125 |
|
126 |
/* Cache */
|
@@ -175,54 +186,92 @@ class SLB_Content_Handlers extends SLB_Collection_Controller {
|
|
175 |
|
176 |
/**
|
177 |
* Initialize default handlers
|
178 |
-
* @param SLB_Content_Handlers $
|
179 |
*/
|
180 |
-
public function init_defaults($
|
181 |
-
$
|
|
|
|
|
|
|
182 |
'image' => array (
|
183 |
'match' => $this->m('match_image'),
|
184 |
-
'
|
185 |
-
|
|
|
|
|
186 |
);
|
187 |
-
foreach ( $
|
188 |
-
$
|
189 |
}
|
190 |
}
|
191 |
|
192 |
/**
|
193 |
* Matches image URIs
|
194 |
* @param string $uri URI to match
|
195 |
-
* @return bool TRUE if URI is image
|
196 |
*/
|
197 |
-
public function match_image($uri) {
|
198 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
199 |
}
|
200 |
|
201 |
/* Output */
|
202 |
|
203 |
/**
|
204 |
-
*
|
|
|
205 |
*/
|
206 |
public function client_output() {
|
207 |
-
//
|
208 |
-
|
209 |
-
|
210 |
}
|
211 |
-
|
212 |
-
|
213 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
214 |
$code = array();
|
215 |
-
|
216 |
foreach ( $this->request_matches as $handler ) {
|
217 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
218 |
$params = array(
|
219 |
sprintf("'%s'", $handler->get_id()),
|
220 |
-
|
221 |
);
|
222 |
-
|
|
|
|
|
|
|
|
|
|
|
223 |
}
|
224 |
-
|
225 |
-
$out[] = '<!-- /SLB-HDL -->' . PHP_EOL;
|
226 |
-
echo implode('', $out);
|
227 |
}
|
228 |
}
|
31 |
|
32 |
protected function _hooks() {
|
33 |
parent::_hooks();
|
34 |
+
$this->util->add_action('init', $this->m('init_defaults'), 5);
|
35 |
+
$this->util->add_action('footer', $this->m('client_output'), 1, 0, false);
|
36 |
+
$this->util->add_filter('footer_script', $this->m('client_output_script'), $this->util->priority('client_footer_output'), 1, false);
|
37 |
}
|
38 |
|
39 |
/* Collection Management */
|
50 |
public function add($id, $props = array(), $priority = 10) {
|
51 |
$this->clear_cache();
|
52 |
if ( is_string($id) ) {
|
53 |
+
// Initialize new handler
|
54 |
$handler = new $this->item_type($id, $props);
|
55 |
} else {
|
56 |
+
// Remap parameters
|
57 |
$handler = func_get_arg(0);
|
58 |
if ( func_num_args() == 2 ) {
|
59 |
$priority = func_get_arg(1);
|
62 |
if ( !is_int($priority) ) {
|
63 |
$priority = 10;
|
64 |
}
|
65 |
+
// Add to collection
|
66 |
return parent::add($handler, array('priority' => $priority));
|
67 |
}
|
68 |
|
92 |
* Retrieves handlers sorted by priority
|
93 |
* @see parent::get()
|
94 |
* @uses get_cache()
|
95 |
+
* @param mixed $args Unused
|
96 |
* @return array Handlers
|
97 |
*/
|
98 |
+
public function get($args = null) {
|
99 |
$items = $this->get_cache();
|
100 |
if ( empty($items) ) {
|
101 |
+
// Retrieve items
|
102 |
$items = parent::get( array( 'orderby' => array('meta' => 'priority') ) );
|
103 |
$this->update_cache($items);
|
104 |
}
|
108 |
/**
|
109 |
* Get matching handler for URI
|
110 |
* @param string $uri URI to find match for
|
111 |
+
* @return object Handler package (FALSE if no match found)
|
112 |
+
* Package members
|
113 |
+
* > handler (Content_Handler) Matching handler instance (Default: NULL)
|
114 |
+
* > props (array) Properties returned from matching handler (May be empty depending on handler)
|
115 |
*/
|
116 |
public function match($uri) {
|
117 |
+
$ret = (object) array('handler' => null, 'props' => array());
|
118 |
foreach ( $this->get() as $handler ) {
|
119 |
+
$props = $handler->match($uri, $this);
|
120 |
+
if ( !!$props ) {
|
121 |
+
$ret->handler = $handler;
|
122 |
+
// Add handler props
|
123 |
+
if ( is_array($props) ) {
|
124 |
+
$ret->props = $props;
|
125 |
+
}
|
126 |
+
// Save match
|
127 |
$hid = $handler->get_id();
|
128 |
if ( !isset($this->request_matches[$hid]) ) {
|
129 |
$this->request_matches[$hid] = $handler;
|
130 |
}
|
131 |
+
break;
|
132 |
}
|
133 |
}
|
134 |
+
return $ret;
|
135 |
}
|
136 |
|
137 |
/* Cache */
|
186 |
|
187 |
/**
|
188 |
* Initialize default handlers
|
189 |
+
* @param SLB_Content_Handlers $handlers Handlers controller
|
190 |
*/
|
191 |
+
public function init_defaults($handlers) {
|
192 |
+
$src_base = $this->util->get_file_url('content-handlers', true);
|
193 |
+
$js_path = 'js/';
|
194 |
+
$js_path .= ( SLB_DEV ) ? 'dev' : 'prod';
|
195 |
+
$defaults = array (
|
196 |
'image' => array (
|
197 |
'match' => $this->m('match_image'),
|
198 |
+
'scripts' => array (
|
199 |
+
array ( 'base', "$src_base/image/$js_path/handler.image.js" ),
|
200 |
+
),
|
201 |
+
)
|
202 |
);
|
203 |
+
foreach ( $defaults as $id => $props ) {
|
204 |
+
$handlers->add($id, $props);
|
205 |
}
|
206 |
}
|
207 |
|
208 |
/**
|
209 |
* Matches image URIs
|
210 |
* @param string $uri URI to match
|
211 |
+
* @return bool|array TRUE if URI is image (array is used if extra data needs to be sent)
|
212 |
*/
|
213 |
+
public function match_image($uri, $handlers) {
|
214 |
+
// Basic matching
|
215 |
+
$match = ( $this->util->has_file_extension($uri, array('jpg', 'jpeg', 'jpe', 'jfif', 'jif', 'gif', 'png')) ) ? true : false;
|
216 |
+
|
217 |
+
// Filter result
|
218 |
+
$extra = new stdClass();
|
219 |
+
$match = $this->util->apply_filters('image_match', $match, $uri, $extra);
|
220 |
+
|
221 |
+
// Handle extra data passed from filters
|
222 |
+
// Currently only `uri` supported
|
223 |
+
if ( $match && isset($extra->uri) && is_string($extra->uri) ) {
|
224 |
+
$match = array('uri' => $extra->uri);
|
225 |
+
}
|
226 |
+
|
227 |
+
return $match;
|
228 |
}
|
229 |
|
230 |
/* Output */
|
231 |
|
232 |
/**
|
233 |
+
* Build client output
|
234 |
+
* Load handler files in client
|
235 |
*/
|
236 |
public function client_output() {
|
237 |
+
// Get handlers for current request
|
238 |
+
foreach ( $this->request_matches as $handler ) {
|
239 |
+
$handler->enqueue_scripts();
|
240 |
}
|
241 |
+
}
|
242 |
+
|
243 |
+
/**
|
244 |
+
* Client output script
|
245 |
+
* @param array $commands Client script commands
|
246 |
+
* @return array Modified script commands
|
247 |
+
*/
|
248 |
+
public function client_output_script($commands) {
|
249 |
+
$out = array('/* CHDL */');
|
250 |
$code = array();
|
251 |
+
|
252 |
foreach ( $this->request_matches as $handler ) {
|
253 |
+
// Attributes
|
254 |
+
$attrs = $handler->get_attributes();
|
255 |
+
// Styles
|
256 |
+
$styles = $handler->get_styles(array('uri_format'=>'full'));
|
257 |
+
if ( !empty($styles) ) {
|
258 |
+
$attrs['styles'] = array_values($styles);
|
259 |
+
}
|
260 |
+
if ( empty($attrs) ) {
|
261 |
+
continue;
|
262 |
+
}
|
263 |
+
// Setup client parameters
|
264 |
$params = array(
|
265 |
sprintf("'%s'", $handler->get_id()),
|
266 |
+
json_encode($attrs),
|
267 |
);
|
268 |
+
// Extend handler in client
|
269 |
+
$code[] = $this->util->call_client_method('View.extend_content_handler', $params, false);
|
270 |
+
}
|
271 |
+
if ( !empty($code) ) {
|
272 |
+
$out[] = implode('', $code);
|
273 |
+
$commands[] = implode(PHP_EOL, $out);
|
274 |
}
|
275 |
+
return $commands;
|
|
|
|
|
276 |
}
|
277 |
}
|
includes/class.field.php
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class SLB_Field extends SLB_Field_Type {}
|
includes/class.field_base.php
ADDED
@@ -0,0 +1,1048 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Fields - Base class
|
5 |
+
* Core properties/methods for fields
|
6 |
+
* @package Simple Lightbox
|
7 |
+
* @subpackage Fields
|
8 |
+
* @author Archetyped
|
9 |
+
*/
|
10 |
+
class SLB_Field_Base extends SLB_Base {
|
11 |
+
/*-** Config **-*/
|
12 |
+
protected $mode = 'object';
|
13 |
+
protected $shared = false;
|
14 |
+
|
15 |
+
/*-** Properties **-*/
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var string Unique name
|
19 |
+
*/
|
20 |
+
var $id = '';
|
21 |
+
|
22 |
+
/**
|
23 |
+
* ID formatting options
|
24 |
+
* Merged with defaults during initialization
|
25 |
+
* @see $id_formats_default
|
26 |
+
* @var array
|
27 |
+
*/
|
28 |
+
var $id_formats = null;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Default ID Formatting options
|
32 |
+
* Structure:
|
33 |
+
* > Key (string): Format name
|
34 |
+
* > Val (array): Options
|
35 |
+
* @var array
|
36 |
+
*/
|
37 |
+
var $id_formats_default = array(
|
38 |
+
'attr_id' => array(
|
39 |
+
'wrap' => array('open' => '_', 'segment_open' => '_'),
|
40 |
+
'prefix' => array('get_container', 'get_id', 'add_prefix'),
|
41 |
+
'recursive' => true
|
42 |
+
),
|
43 |
+
'attr_name' => array(
|
44 |
+
'wrap' => array('open' => '[', 'close' => ']', 'segment_open' => '[', 'segment_close' => ']'),
|
45 |
+
'recursive' => true,
|
46 |
+
'prefix' => array('get_container', 'get_id', 'add_prefix')
|
47 |
+
)
|
48 |
+
);
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Special characters/phrases
|
52 |
+
* Used for preserving special characters during formatting
|
53 |
+
* Merged with $special_chars_default
|
54 |
+
* Array Structure
|
55 |
+
* > Key: Special character/phrase
|
56 |
+
* > Value: Placeholder for special character
|
57 |
+
* @var array
|
58 |
+
*/
|
59 |
+
var $special_chars = null;
|
60 |
+
|
61 |
+
var $special_chars_default = array(
|
62 |
+
'{' => '%SQB_L%',
|
63 |
+
'}' => '%SQB_R%',
|
64 |
+
);
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Reference to parent object that current instance inherits from
|
68 |
+
* @var object
|
69 |
+
*/
|
70 |
+
var $parent = null;
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Title
|
74 |
+
* @var string
|
75 |
+
*/
|
76 |
+
var $title = '';
|
77 |
+
|
78 |
+
/**
|
79 |
+
* @var string Short description
|
80 |
+
*/
|
81 |
+
var $description = '';
|
82 |
+
|
83 |
+
/**
|
84 |
+
* @var array Object Properties
|
85 |
+
*/
|
86 |
+
var $properties = array();
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Initialization properties
|
90 |
+
* @var array
|
91 |
+
*/
|
92 |
+
protected $properties_init = null;
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Structure: Property names stored as keys in group
|
96 |
+
* Root
|
97 |
+
* -> Group Name
|
98 |
+
* -> Property Name => Null
|
99 |
+
* Reason: Faster searching over large arrays
|
100 |
+
* @var array Groupings of Properties
|
101 |
+
*/
|
102 |
+
var $property_groups = array();
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Keys to filter out of properties array before setting properties
|
106 |
+
* @var array
|
107 |
+
*/
|
108 |
+
var $property_filter = array('group');
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Define order of properties
|
112 |
+
* Useful when processing order is important (e.g. one property depends on another)
|
113 |
+
* @var array
|
114 |
+
*/
|
115 |
+
var $property_priority = array();
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Data for object
|
119 |
+
* May also contain data for nested objects
|
120 |
+
* @var mixed
|
121 |
+
*/
|
122 |
+
var $data = null;
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Whether data has been fetched or not
|
126 |
+
* @var bool
|
127 |
+
*/
|
128 |
+
var $data_loaded = false;
|
129 |
+
|
130 |
+
/**
|
131 |
+
* @var array Script resources to include for object
|
132 |
+
*/
|
133 |
+
var $scripts = array();
|
134 |
+
|
135 |
+
/**
|
136 |
+
* @var array CSS style resources to include for object
|
137 |
+
*/
|
138 |
+
var $styles = array();
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Hooks (Filters/Actions) for object
|
142 |
+
* @var array
|
143 |
+
*/
|
144 |
+
var $hooks = array();
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Mapping of child properties to parent members
|
148 |
+
* Allows more flexibility when creating new instances of child objects using property arrays
|
149 |
+
* Associative array structure:
|
150 |
+
* > Key: Child property to map FROM
|
151 |
+
* > Val: Parent property to map TO
|
152 |
+
* @var array
|
153 |
+
*/
|
154 |
+
var $map = null;
|
155 |
+
|
156 |
+
/**
|
157 |
+
* Options used when building collection (callbacks, etc.)
|
158 |
+
* Associative array
|
159 |
+
* > Key: Option name
|
160 |
+
* > Value: Option value
|
161 |
+
* @var array
|
162 |
+
*/
|
163 |
+
var $build_vars = array();
|
164 |
+
|
165 |
+
var $build_vars_default = array();
|
166 |
+
|
167 |
+
/**
|
168 |
+
* Constructor
|
169 |
+
*/
|
170 |
+
function __construct($id = '', $properties = null) {
|
171 |
+
parent::__construct();
|
172 |
+
// Normalize Properties
|
173 |
+
$args = func_get_args();
|
174 |
+
$defaults = $this->integrate_id($id);
|
175 |
+
$properties = $this->make_properties($args, $defaults);
|
176 |
+
// Save init properties
|
177 |
+
$this->properties_init = $properties;
|
178 |
+
// Set Properties
|
179 |
+
$this->set_properties($properties);
|
180 |
+
}
|
181 |
+
|
182 |
+
/* Getters/Setters */
|
183 |
+
|
184 |
+
/**
|
185 |
+
* Checks if the specified path exists in the object
|
186 |
+
* @param array $path Path to check for
|
187 |
+
* @return bool TRUE if path exists in object, FALSE otherwise
|
188 |
+
*/
|
189 |
+
function path_isset($path = '') {
|
190 |
+
// Stop execution if no path is supplied
|
191 |
+
if ( empty($path) )
|
192 |
+
return false;
|
193 |
+
$args = func_get_args();
|
194 |
+
$path = $this->util->build_path($args);
|
195 |
+
$item =& $this;
|
196 |
+
// Iterate over path and check if each level exists before moving on to the next
|
197 |
+
for ($x = 0; $x < count($path); $x++) {
|
198 |
+
if ( $this->util->property_exists($item, $path[$x]) ) {
|
199 |
+
// Set $item as reference to next level in path for next iteration
|
200 |
+
$item =& $this->util->get_property($item, $path[$x]);
|
201 |
+
// $item =& $item[ $path[$x] ];
|
202 |
+
} else {
|
203 |
+
return false;
|
204 |
+
}
|
205 |
+
}
|
206 |
+
return true;
|
207 |
+
}
|
208 |
+
|
209 |
+
/**
|
210 |
+
* Retrieves a value from object using a specified path
|
211 |
+
* Checks to make sure path exists in object before retrieving value
|
212 |
+
* @param array $path Path to retrieve value from. Each item in array is a deeper dimension
|
213 |
+
* @return mixed Value at specified path
|
214 |
+
*/
|
215 |
+
function &get_path_value($path = '') {
|
216 |
+
$ret = '';
|
217 |
+
$path = $this->util->build_path(func_get_args());
|
218 |
+
if ( $this->path_isset($path) ) {
|
219 |
+
$ret =& $this;
|
220 |
+
for ($x = 0; $x < count($path); $x++) {
|
221 |
+
if ( 0 == $x )
|
222 |
+
$ret =& $ret->{ $path[$x] };
|
223 |
+
else
|
224 |
+
$ret =& $ret[ $path[$x] ];
|
225 |
+
}
|
226 |
+
}
|
227 |
+
return $ret;
|
228 |
+
}
|
229 |
+
|
230 |
+
/**
|
231 |
+
* Search for specified member value in field type ancestors
|
232 |
+
* @param string $member Name of object member to search (e.g. properties, layout, etc.)
|
233 |
+
* @param string $name Value to retrieve from member
|
234 |
+
* @return mixed Member value if found (Default: empty string)
|
235 |
+
*/
|
236 |
+
function get_parent_value($member, $name = '', $default = '') {
|
237 |
+
$parent = $this->get_parent();
|
238 |
+
return $this->get_object_value($parent, $member, $name, $default, 'parent');
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Retrieves specified member value
|
243 |
+
* Handles inherited values
|
244 |
+
* Merging corresponding parents if value is an array (e.g. for property groups)
|
245 |
+
* @param string|array $member Member to search. May also contain a path to the desired member
|
246 |
+
* @param string $name Value to retrieve from member
|
247 |
+
* @param mixed $default Default value if no value found (Default: empty string)
|
248 |
+
* @param string $dir Direction to move through hierarchy to find value
|
249 |
+
* Possible Values:
|
250 |
+
* parent (default) - Search through field parents
|
251 |
+
* current - Do not search through connected objects
|
252 |
+
* container - Search through field containers
|
253 |
+
* caller - Search through field callers
|
254 |
+
* @return mixed Specified member value
|
255 |
+
* @todo Return reference
|
256 |
+
*/
|
257 |
+
function &get_member_value($member, $name = '', $default = '', $dir = 'parent') {
|
258 |
+
// Check if path to member is supplied
|
259 |
+
$path = array();
|
260 |
+
if ( is_array($member) && isset($member['tag']) ) {
|
261 |
+
if ( isset($member['attributes']['ref_base']) ) {
|
262 |
+
if ( 'root' != $member['attributes']['ref_base'] )
|
263 |
+
$path[] = $member['attributes']['ref_base'];
|
264 |
+
} else {
|
265 |
+
$path[] = 'properties';
|
266 |
+
}
|
267 |
+
|
268 |
+
$path[] = $member['tag'];
|
269 |
+
} else {
|
270 |
+
$path = $member;
|
271 |
+
}
|
272 |
+
|
273 |
+
$path = $this->util->build_path($path, $name);
|
274 |
+
// Set defaults and prepare data
|
275 |
+
$val = $default;
|
276 |
+
$inherit = false;
|
277 |
+
$inherit_tag = '{inherit}';
|
278 |
+
|
279 |
+
/* Determine whether the value must be retrieved from a parent/container object
|
280 |
+
* Conditions:
|
281 |
+
* > Path does not exist in current field
|
282 |
+
* > Path exists and is not an object, but at least one of the following is true:
|
283 |
+
* > Value at path is an array (e.g. properties, elements, etc. array)
|
284 |
+
* > Parent/container values should be merged with retrieved array
|
285 |
+
* > Value at path is a string that inherits from another field
|
286 |
+
* > Value from other field will be retrieved and will replace inheritance placeholder in retrieved value
|
287 |
+
*/
|
288 |
+
|
289 |
+
$deeper = false;
|
290 |
+
|
291 |
+
if ( !$this->path_isset($path) )
|
292 |
+
$deeper = true;
|
293 |
+
else {
|
294 |
+
$val = $this->get_path_value($path);
|
295 |
+
if ( !is_object($val) && ( is_array($val) || ($inherit = strpos($val, $inherit_tag)) !== false ) )
|
296 |
+
$deeper = true;
|
297 |
+
else
|
298 |
+
$deeper = false;
|
299 |
+
}
|
300 |
+
if ( $deeper && 'current' != $dir ) {
|
301 |
+
$ex_val = '';
|
302 |
+
// Get Parent value (recursive)
|
303 |
+
if ( 'parent' == $dir )
|
304 |
+
$ex_val = $this->get_parent_value($member, $name, $default);
|
305 |
+
elseif ( method_exists($this, 'get_container_value') )
|
306 |
+
$ex_val = $this->get_container_value($member, $name, $default);
|
307 |
+
// Handle inheritance
|
308 |
+
if ( is_array($val) ) {
|
309 |
+
// Combine Arrays
|
310 |
+
if ( is_array($ex_val) )
|
311 |
+
$val = array_merge($ex_val, $val);
|
312 |
+
} elseif ( $inherit !== false ) {
|
313 |
+
// Replace placeholder with inherited string
|
314 |
+
$val = str_replace($inherit_tag, $ex_val, $val);
|
315 |
+
} else {
|
316 |
+
// Default: Set parent value as value
|
317 |
+
$val = $ex_val;
|
318 |
+
}
|
319 |
+
}
|
320 |
+
|
321 |
+
return $val;
|
322 |
+
}
|
323 |
+
|
324 |
+
/**
|
325 |
+
* Search for specified member value in an object
|
326 |
+
* @param object $object Reference to object to retrieve value from
|
327 |
+
* @param string $member Name of object member to search (e.g. properties, layout, etc.)
|
328 |
+
* @param string $name (optional) Value to retrieve from member
|
329 |
+
* @param mixed $default (optional) Default value to use if no value found (Default: empty string)
|
330 |
+
* @param string $dir Direction to move through hierarchy to find value @see SLB_Field_Type::get_member_value() for possible values
|
331 |
+
* @return mixed Member value if found (Default: $default)
|
332 |
+
*/
|
333 |
+
function get_object_value(&$object, $member, $name = '', $default = '', $dir = 'parent') {
|
334 |
+
$ret = $default;
|
335 |
+
if ( is_object($object) && method_exists($object, 'get_member_value') )
|
336 |
+
$ret = $object->get_member_value($member, $name, $default, $dir);
|
337 |
+
return $ret;
|
338 |
+
}
|
339 |
+
|
340 |
+
/**
|
341 |
+
* Set item ID
|
342 |
+
* @param string $id Unique item ID
|
343 |
+
*/
|
344 |
+
function set_id($id) {
|
345 |
+
if ( empty($id) || !is_string($id) )
|
346 |
+
return false;
|
347 |
+
$this->id = trim($id);
|
348 |
+
}
|
349 |
+
|
350 |
+
/**
|
351 |
+
* Retrieves field ID
|
352 |
+
* @param array|string $options (optional) Options or ID of format to use
|
353 |
+
* @return string item ID
|
354 |
+
*/
|
355 |
+
function get_id($options = array()) {
|
356 |
+
$item_id = trim($this->id);
|
357 |
+
$formats = $this->get_id_formats();
|
358 |
+
|
359 |
+
// Setup options
|
360 |
+
$wrap_default = array('open' => '', 'close' => '', 'segment_open' => '', 'segment_close' => '');
|
361 |
+
|
362 |
+
$options_default = array(
|
363 |
+
'format' => null,
|
364 |
+
'wrap' => array(),
|
365 |
+
'segments_pre' => null,
|
366 |
+
'prefix' => '',
|
367 |
+
'recursive' => false
|
368 |
+
);
|
369 |
+
|
370 |
+
// Load options based on format
|
371 |
+
if ( !is_array($options) )
|
372 |
+
$options = array('format' => $options);
|
373 |
+
if ( isset($options['format']) && is_string($options['format']) && isset($formats[$options['format']]) )
|
374 |
+
$options_default = wp_parse_args($formats[$options['format']], $options_default);
|
375 |
+
else
|
376 |
+
unset($options['format']);
|
377 |
+
$options = wp_parse_args($options, $options_default);
|
378 |
+
// Import options into function
|
379 |
+
extract($options);
|
380 |
+
|
381 |
+
// Validate options
|
382 |
+
$wrap = wp_parse_args($wrap, $wrap_default);
|
383 |
+
|
384 |
+
if ( !is_array($segments_pre) )
|
385 |
+
$segments_pre = array($segments_pre);
|
386 |
+
$segments_pre = array_reverse($segments_pre);
|
387 |
+
|
388 |
+
// Format ID based on options
|
389 |
+
$item_id = array($item_id);
|
390 |
+
|
391 |
+
// Add parent objects to ID
|
392 |
+
if ( !!$recursive ) {
|
393 |
+
// Create array of ID components
|
394 |
+
$m = 'get_caller';
|
395 |
+
$c = ( method_exists($this, $m) ) ? $this->{$m}() : null;
|
396 |
+
while ( !!$c ) {
|
397 |
+
// Add ID of current caller to array
|
398 |
+
if ( method_exists($c, 'get_id') && ( $itemp = $c->get_id() ) && !empty($itemp) )
|
399 |
+
$item_id = $itemp;
|
400 |
+
// Get parent object
|
401 |
+
$c = ( method_exists($c, $m) ) ? $c->{$m}() : null;
|
402 |
+
$itemp = '';
|
403 |
+
}
|
404 |
+
unset($c);
|
405 |
+
}
|
406 |
+
|
407 |
+
// Additional segments (Pre)
|
408 |
+
foreach ( $segments_pre as $seg ) {
|
409 |
+
if ( is_null($seg) )
|
410 |
+
continue;
|
411 |
+
if ( is_object($seg) )
|
412 |
+
$seg = (array)$seg;
|
413 |
+
if ( is_array($seg) )
|
414 |
+
$item_id = array_merge($item_id, array_reverse($seg));
|
415 |
+
elseif ( '' != strval($seg) )
|
416 |
+
$item_id[] = strval($seg);
|
417 |
+
}
|
418 |
+
|
419 |
+
// Prefix
|
420 |
+
if ( is_array($prefix) ) {
|
421 |
+
// Array is sequence of instance methods to call on object
|
422 |
+
// Last array member can be an array of parameters to pass to methods
|
423 |
+
$count = count($prefix);
|
424 |
+
$args = ( $count > 1 && is_array($prefix[$count - 1]) ) ? array_pop($prefix) : array();
|
425 |
+
$p = $this;
|
426 |
+
$val = '';
|
427 |
+
// Iterate through methods
|
428 |
+
foreach ( $prefix as $m ) {
|
429 |
+
if ( !method_exists($p, $m) )
|
430 |
+
continue;
|
431 |
+
// Build callback
|
432 |
+
$m = $this->util->m($p, $m);
|
433 |
+
// Call callback
|
434 |
+
$val = call_user_func_array($m, $args);
|
435 |
+
// Returned value may be an instance object
|
436 |
+
if ( is_object($val) )
|
437 |
+
$p = $val; // Use returned object in next round
|
438 |
+
else
|
439 |
+
array_unshift($args, $val); // Pass returned value as parameter to next method on using current object
|
440 |
+
}
|
441 |
+
$prefix = $val;
|
442 |
+
unset($p, $val);
|
443 |
+
}
|
444 |
+
if ( is_numeric($prefix) )
|
445 |
+
$prefix = strval($prefix);
|
446 |
+
if ( empty($prefix) || !is_string($prefix) )
|
447 |
+
$prefix = '';
|
448 |
+
|
449 |
+
// Convert array to string
|
450 |
+
$item_id = $prefix . $wrap['open'] . implode($wrap['segment_close'] . $wrap['segment_open'], array_reverse($item_id)) . $wrap['close'];
|
451 |
+
return $item_id;
|
452 |
+
}
|
453 |
+
|
454 |
+
/**
|
455 |
+
* Retrieve ID formatting options for class
|
456 |
+
* Format options arrays are merged together and saved to $id_formats
|
457 |
+
* @uses $id_formats
|
458 |
+
* @uses $id_formats_default
|
459 |
+
* @return array ID Formatting options
|
460 |
+
*/
|
461 |
+
function &get_id_formats() {
|
462 |
+
if ( is_null($this->id_formats) ) {
|
463 |
+
$this->id_formats = wp_parse_args($this->id_formats, $this->id_formats_default);
|
464 |
+
}
|
465 |
+
return $this->id_formats;
|
466 |
+
}
|
467 |
+
|
468 |
+
/**
|
469 |
+
* Retrieve value from data member
|
470 |
+
* @param string $context Context to format data for
|
471 |
+
* @param bool $top (optional) Whether to traverse through the field hierarchy to get data for field (Default: TRUE)
|
472 |
+
* @return mixed Value at specified path
|
473 |
+
*/
|
474 |
+
function get_data($context = '', $top = true) {
|
475 |
+
$opt_d = array('context' => '', 'top' => true);
|
476 |
+
$args = func_get_args();
|
477 |
+
$a = false;
|
478 |
+
if ( count($args) == 1 && is_array($args[0]) && !empty($args[0]) ) {
|
479 |
+
$a = true;
|
480 |
+
$args = wp_parse_args($args[0], $opt_d);
|
481 |
+
extract($args);
|
482 |
+
}
|
483 |
+
|
484 |
+
if ( is_string($top) ) {
|
485 |
+
if ( 'false' == $top )
|
486 |
+
$top = false;
|
487 |
+
elseif ( 'true' == $top )
|
488 |
+
$top = true;
|
489 |
+
elseif ( is_numeric($top) )
|
490 |
+
$top = intval($top);
|
491 |
+
}
|
492 |
+
$top = !!$top;
|
493 |
+
$obj =& $this;
|
494 |
+
$obj_path = array($this);
|
495 |
+
$path = array();
|
496 |
+
if ( $top ) {
|
497 |
+
// Iterate through hiearchy to get top-most object
|
498 |
+
while ( !empty($obj) ) {
|
499 |
+
$new = null;
|
500 |
+
// Try to get caller first
|
501 |
+
if ( method_exists($obj, 'get_caller') ) {
|
502 |
+
$checked = true;
|
503 |
+
$new =& $obj->get_caller();
|
504 |
+
}
|
505 |
+
// Try to get container if no caller found
|
506 |
+
if ( empty($new) && method_exists($obj, 'get_container') ) {
|
507 |
+
$checked = true;
|
508 |
+
$new =& $obj->get_container();
|
509 |
+
// Load data
|
510 |
+
if ( method_exists($new, 'load_data') ) {
|
511 |
+
$new->load_data();
|
512 |
+
}
|
513 |
+
}
|
514 |
+
|
515 |
+
$obj =& $new;
|
516 |
+
unset($new);
|
517 |
+
// Stop iteration
|
518 |
+
if ( !empty($obj) ) {
|
519 |
+
// Add object to path if it is valid
|
520 |
+
$obj_path[] =& $obj;
|
521 |
+
}
|
522 |
+
}
|
523 |
+
unset($obj);
|
524 |
+
}
|
525 |
+
|
526 |
+
// Check each object (starting with top-most) for matching data for current field
|
527 |
+
|
528 |
+
// Reverse array
|
529 |
+
$obj_path = array_reverse($obj_path);
|
530 |
+
// Build path for data location
|
531 |
+
foreach ( $obj_path as $obj ) {
|
532 |
+
if ( method_exists($obj, 'get_id') )
|
533 |
+
$path[] = $obj->get_id();
|
534 |
+
}
|
535 |
+
// Iterate through objects
|
536 |
+
while ( !empty($obj_path) ) {
|
537 |
+
// Get next object
|
538 |
+
$obj = array_shift($obj_path);
|
539 |
+
// Shorten path
|
540 |
+
array_shift($path);
|
541 |
+
// Check for value in object and stop iteration if matching data found
|
542 |
+
$val = $this->get_object_value($obj, 'data', $path, null, 'current');
|
543 |
+
if ( !is_null($val) ) {
|
544 |
+
break;
|
545 |
+
}
|
546 |
+
}
|
547 |
+
return $this->format($val, $context);
|
548 |
+
}
|
549 |
+
|
550 |
+
/**
|
551 |
+
* Sets value in data member
|
552 |
+
* Sets value to data member itself by default
|
553 |
+
* @param mixed $value Value to set
|
554 |
+
* @param string|array $name Name of value to set (Can also be path to value)
|
555 |
+
*/
|
556 |
+
function set_data($value, $name = '') {
|
557 |
+
$ref =& $this->get_path_value('data', $name);
|
558 |
+
$ref = $value;
|
559 |
+
}
|
560 |
+
|
561 |
+
/**
|
562 |
+
* Sets parent object of current instance
|
563 |
+
* Parent objects must be the same object type as current instance
|
564 |
+
* @uses SLB to get field type definition
|
565 |
+
* @uses SLB_Fields::has() to check if field type exists
|
566 |
+
* @uses SLB_Fields::get() to retrieve field type object reference
|
567 |
+
* @param string|object $parent Parent ID or reference
|
568 |
+
*/
|
569 |
+
function set_parent($parent = null) {
|
570 |
+
// Stop processing if parent empty
|
571 |
+
if ( empty($parent) && !is_string($this->parent) )
|
572 |
+
return false;
|
573 |
+
// Parent passed as object reference wrapped in array
|
574 |
+
if ( is_array($parent) && isset($parent[0]) && is_object($parent[0]) )
|
575 |
+
$parent = $parent[0];
|
576 |
+
|
577 |
+
// No parent set but parent ID (previously) set in object
|
578 |
+
if ( empty($parent) && is_string($this->parent) )
|
579 |
+
$parent = $this->parent;
|
580 |
+
|
581 |
+
// Retrieve reference object if ID was supplied
|
582 |
+
if ( is_string($parent) ) {
|
583 |
+
$parent = trim($parent);
|
584 |
+
// Get parent object reference
|
585 |
+
/**
|
586 |
+
* @var SLB
|
587 |
+
*/
|
588 |
+
$b = $this->get_base();
|
589 |
+
if ( !!$b && isset($b->fields) && $b->fields->has($parent) ) {
|
590 |
+
$parent = $b->fields->get($parent);
|
591 |
+
}
|
592 |
+
}
|
593 |
+
|
594 |
+
// Set parent value on object
|
595 |
+
if ( is_string($parent) || is_object($parent) )
|
596 |
+
$this->parent = $parent;
|
597 |
+
}
|
598 |
+
|
599 |
+
/**
|
600 |
+
* Retrieve field type parent
|
601 |
+
* @return SLB_Field_Type Parent field
|
602 |
+
*/
|
603 |
+
function get_parent() {
|
604 |
+
return $this->parent;
|
605 |
+
}
|
606 |
+
|
607 |
+
/**
|
608 |
+
* Set object title
|
609 |
+
* @param string $title Title for object
|
610 |
+
* @param string $plural Plural form of title
|
611 |
+
*/
|
612 |
+
function set_title($title = '') {
|
613 |
+
if ( is_scalar($title) )
|
614 |
+
$this->title = strip_tags(trim($title));
|
615 |
+
}
|
616 |
+
|
617 |
+
/**
|
618 |
+
* Retrieve object title
|
619 |
+
*/
|
620 |
+
function get_title() {
|
621 |
+
return $this->get_member_value('title', '','', 'current');
|
622 |
+
}
|
623 |
+
|
624 |
+
/**
|
625 |
+
* Set object description
|
626 |
+
* @param string $description Description for object
|
627 |
+
*/
|
628 |
+
function set_description($description = '') {
|
629 |
+
$this->description = strip_tags(trim($description));
|
630 |
+
}
|
631 |
+
|
632 |
+
/**
|
633 |
+
* Retrieve object description
|
634 |
+
* @return string Object description
|
635 |
+
*/
|
636 |
+
function get_description() {
|
637 |
+
$dir = 'current';
|
638 |
+
return $this->get_member_value('description', '','', $dir);
|
639 |
+
return $desc;
|
640 |
+
}
|
641 |
+
|
642 |
+
/**
|
643 |
+
* Sets multiple properties on field type at once
|
644 |
+
* @param array $properties Properties. Each element is an array containing the arguments to set a new property
|
645 |
+
* @return boolean TRUE if successful, FALSE otherwise
|
646 |
+
*/
|
647 |
+
function set_properties($properties) {
|
648 |
+
if ( !is_array($properties) ) {
|
649 |
+
return false;
|
650 |
+
}
|
651 |
+
// Normalize properties
|
652 |
+
$properties = $this->remap_properties($properties);
|
653 |
+
$properties = $this->sort_properties($properties);
|
654 |
+
// Set Member properties
|
655 |
+
foreach ( $properties as $prop => $val ) {
|
656 |
+
if ( ( $m = 'set_' . $prop ) && method_exists($this, $m) ) {
|
657 |
+
$this->{$m}($val);
|
658 |
+
// Remove member property from array
|
659 |
+
unset($properties[$prop]);
|
660 |
+
}
|
661 |
+
}
|
662 |
+
|
663 |
+
// Filter properties
|
664 |
+
$properties = $this->filter_properties($properties);
|
665 |
+
// Set additional instance properties
|
666 |
+
foreach ( $properties as $name => $val) {
|
667 |
+
$this->set_property($name, $val);
|
668 |
+
}
|
669 |
+
}
|
670 |
+
|
671 |
+
/**
|
672 |
+
* Remap properties based on $map
|
673 |
+
* @uses $map For determine how child properties should map to parent properties
|
674 |
+
* @uses SLB_Utlities::array_remap() to perform array remapping
|
675 |
+
* @param array $properties Associative array of properties
|
676 |
+
* @return array Remapped properties
|
677 |
+
*/
|
678 |
+
function remap_properties($properties) {
|
679 |
+
// Return remapped properties
|
680 |
+
return $this->util->array_remap($properties, $this->map);
|
681 |
+
}
|
682 |
+
|
683 |
+
/**
|
684 |
+
* Sort properties based on priority
|
685 |
+
* @uses this::property_priority
|
686 |
+
* @return array Sorted priorities
|
687 |
+
*/
|
688 |
+
function sort_properties($properties) {
|
689 |
+
// Stop if sorting not necessary
|
690 |
+
if ( empty($properties) || !is_array($properties) || empty($this->property_priority) || !is_array($this->property_priority) )
|
691 |
+
return $properties;
|
692 |
+
$props = array();
|
693 |
+
foreach ( $this->property_priority as $prop ) {
|
694 |
+
if ( !array_key_exists($prop, $properties) )
|
695 |
+
continue;
|
696 |
+
// Add to new array
|
697 |
+
$props[$prop] = $properties[$prop];
|
698 |
+
// Remove from old array
|
699 |
+
unset($properties[$prop]);
|
700 |
+
}
|
701 |
+
// Append any remaining properties
|
702 |
+
$props = array_merge($props, $properties);
|
703 |
+
return $props;
|
704 |
+
}
|
705 |
+
|
706 |
+
/**
|
707 |
+
* Build properties array
|
708 |
+
* @param array $props Instance properties
|
709 |
+
* @param array $signature (optional) Default properties
|
710 |
+
* @return array Normalized properties
|
711 |
+
*/
|
712 |
+
function make_properties($props, $signature = array()) {
|
713 |
+
$p = array();
|
714 |
+
if ( is_array($props) ) {
|
715 |
+
foreach ( $props as $prop ) {
|
716 |
+
if ( is_array($prop) ) {
|
717 |
+
$p = array_merge($prop, $p);
|
718 |
+
}
|
719 |
+
}
|
720 |
+
}
|
721 |
+
$props = $p;
|
722 |
+
if ( is_array($signature) ) {
|
723 |
+
$props = array_merge($signature, $props);
|
724 |
+
}
|
725 |
+
return $props;
|
726 |
+
}
|
727 |
+
|
728 |
+
function validate_id($id) {
|
729 |
+
return ( is_scalar($id) && !empty($id) ) ? true : false;
|
730 |
+
}
|
731 |
+
|
732 |
+
function integrate_id($id) {
|
733 |
+
return ( $this->validate_id($id) ) ? array('id' => $id) : array();
|
734 |
+
}
|
735 |
+
|
736 |
+
/**
|
737 |
+
* Filter property members
|
738 |
+
* @uses $property_filter to remove define members to remove from $properties
|
739 |
+
* @param array $props Properties
|
740 |
+
* @return array Filtered properties
|
741 |
+
*/
|
742 |
+
function filter_properties($props = array()) {
|
743 |
+
return $this->util->array_filter_keys($props, $this->property_filter);
|
744 |
+
}
|
745 |
+
|
746 |
+
/**
|
747 |
+
* Add/Set a property on the field definition
|
748 |
+
* @param string $name Name of property
|
749 |
+
* @param mixed $value Default value for property
|
750 |
+
* @param string|array $group Group(s) property belongs to
|
751 |
+
* @return boolean TRUE if property is successfully added to field type, FALSE otherwise
|
752 |
+
*/
|
753 |
+
function set_property($name, $value = '', $group = null) {
|
754 |
+
// Do not add if property name is not a string
|
755 |
+
if ( !is_string($name) )
|
756 |
+
return false;
|
757 |
+
// Create property array
|
758 |
+
$prop_arr = array();
|
759 |
+
$prop_arr['value'] = $value;
|
760 |
+
// Add to properties array
|
761 |
+
$this->properties[$name] = $value;
|
762 |
+
// Add property to specified groups
|
763 |
+
if ( !empty($group) ) {
|
764 |
+
$this->set_group_property($group, $name);
|
765 |
+
}
|
766 |
+
return true;
|
767 |
+
}
|
768 |
+
|
769 |
+
/**
|
770 |
+
* Retreives property from field type
|
771 |
+
* @param string $name Name of property to retrieve
|
772 |
+
* @return mixed Specified Property if exists (Default: Empty string)
|
773 |
+
*/
|
774 |
+
function get_property($name) {
|
775 |
+
$val = $this->get_member_value('properties', $name);
|
776 |
+
return $val;
|
777 |
+
}
|
778 |
+
|
779 |
+
/**
|
780 |
+
* Removes a property from item
|
781 |
+
* @param string $name Property ID
|
782 |
+
*/
|
783 |
+
function remove_property($name) {
|
784 |
+
// Remove property
|
785 |
+
if ( isset($this->properties[$name]) )
|
786 |
+
unset($this->properties[$name]);
|
787 |
+
// Remove from group
|
788 |
+
foreach ( array_keys($this->property_groups) as $g ) {
|
789 |
+
if ( isset($this->property_groups[$g][$name]) ) {
|
790 |
+
unset($this->property_groups[$g][$name]);
|
791 |
+
break;
|
792 |
+
}
|
793 |
+
}
|
794 |
+
}
|
795 |
+
|
796 |
+
/**
|
797 |
+
* Adds Specified Property to a Group
|
798 |
+
* @param string|array $group Group(s) to add property to
|
799 |
+
* @param string $property Property to add to group
|
800 |
+
*/
|
801 |
+
function set_group_property($group, $property) {
|
802 |
+
if ( is_string($group) && isset($this->property_groups[$group][$property]) )
|
803 |
+
return;
|
804 |
+
if ( !is_array($group) ) {
|
805 |
+
$group = array($group);
|
806 |
+
}
|
807 |
+
|
808 |
+
foreach ($group as $g) {
|
809 |
+
$g = trim($g);
|
810 |
+
// Initialize group if it doesn't already exist
|
811 |
+
if ( !isset($this->property_groups[$g]) )
|
812 |
+
$this->property_groups[$g] = array();
|
813 |
+
|
814 |
+
// Add property to group
|
815 |
+
$this->property_groups[$g][$property] = null;
|
816 |
+
}
|
817 |
+
}
|
818 |
+
|
819 |
+
/**
|
820 |
+
* Retrieve property group
|
821 |
+
* @param string $group Group to retrieve
|
822 |
+
* @return array Array of properties in specified group
|
823 |
+
*/
|
824 |
+
function get_group($group) {
|
825 |
+
return $this->get_member_value('property_groups', $group, array());
|
826 |
+
}
|
827 |
+
|
828 |
+
/**
|
829 |
+
* Save field data
|
830 |
+
* Child classes will define their own
|
831 |
+
* functionality for this method
|
832 |
+
* @return bool TRUE if save was successful (FALSE otherwise)
|
833 |
+
*/
|
834 |
+
function save() {
|
835 |
+
return true;
|
836 |
+
}
|
837 |
+
|
838 |
+
/*-** Hooks **-*/
|
839 |
+
|
840 |
+
/**
|
841 |
+
* Retrieve hooks added to object
|
842 |
+
* @return array Hooks
|
843 |
+
*/
|
844 |
+
function get_hooks() {
|
845 |
+
return $this->get_member_value('hooks', '', array());
|
846 |
+
}
|
847 |
+
|
848 |
+
/**
|
849 |
+
* Add hook for object
|
850 |
+
* @see add_filter() for parameter defaults
|
851 |
+
* @param $tag
|
852 |
+
* @param $function_to_add
|
853 |
+
* @param $priority
|
854 |
+
* @param $accepted_args
|
855 |
+
*/
|
856 |
+
function add_hook($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
|
857 |
+
// Create new array for tag (if not already set)
|
858 |
+
if ( !isset($this->hooks[$tag]) )
|
859 |
+
$this->hooks[$tag] = array();
|
860 |
+
// Build Unique ID
|
861 |
+
if ( is_string($function_to_add) )
|
862 |
+
$id = $function_to_add;
|
863 |
+
elseif ( is_array($function_to_add) && !empty($function_to_add) )
|
864 |
+
$id = strval($function_to_add[count($function_to_add) - 1]);
|
865 |
+
else
|
866 |
+
$id = 'function_' . ( count($this->hooks[$tag]) + 1 );
|
867 |
+
// Add hook
|
868 |
+
$this->hooks[$tag][$id] = func_get_args();
|
869 |
+
}
|
870 |
+
|
871 |
+
/**
|
872 |
+
* Convenience method for adding an action for object
|
873 |
+
* @see add_filter() for parameter defaults
|
874 |
+
* @param $tag
|
875 |
+
* @param $function_to_add
|
876 |
+
* @param $priority
|
877 |
+
* @param $accepted_args
|
878 |
+
*/
|
879 |
+
function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
|
880 |
+
$this->add_hook($tag, $function_to_add, $priority, $accepted_args);
|
881 |
+
}
|
882 |
+
|
883 |
+
/**
|
884 |
+
* Convenience method for adding a filter for object
|
885 |
+
* @see add_filter() for parameter defaults
|
886 |
+
* @param $tag
|
887 |
+
* @param $function_to_add
|
888 |
+
* @param $priority
|
889 |
+
* @param $accepted_args
|
890 |
+
*/
|
891 |
+
function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
|
892 |
+
$this->add_hook($tag, $function_to_add, $priority, $accepted_args);
|
893 |
+
}
|
894 |
+
|
895 |
+
/*-** Dependencies **-*/
|
896 |
+
|
897 |
+
/**
|
898 |
+
* Adds dependency to object
|
899 |
+
* @param string $type Type of dependency to add (script, style)
|
900 |
+
* @param array|string $context When dependency will be added (@see SLB_Utilities::get_action() for possible contexts)
|
901 |
+
* @see wp_enqueue_script for the following of the parameters
|
902 |
+
* @param $handle
|
903 |
+
* @param $src
|
904 |
+
* @param $deps
|
905 |
+
* @param $ver
|
906 |
+
* @param $ex
|
907 |
+
*/
|
908 |
+
function add_dependency($type, $context, $handle, $src = false, $deps = array(), $ver = false, $ex = false) {
|
909 |
+
$args = func_get_args();
|
910 |
+
// Remove type/context from arguments
|
911 |
+
$args = array_slice($args, 2);
|
912 |
+
|
913 |
+
// Set context
|
914 |
+
if ( !is_array($context) ) {
|
915 |
+
// Wrap single contexts in an array
|
916 |
+
if ( is_string($context) )
|
917 |
+
$context = array($context);
|
918 |
+
else
|
919 |
+
$context = array();
|
920 |
+
}
|
921 |
+
// Add file to instance property
|
922 |
+
if ( isset($this->{$type}) && is_array($this->{$type}) )
|
923 |
+
$this->{$type}[$handle] = array('context' => $context, 'params' => $args);
|
924 |
+
}
|
925 |
+
|
926 |
+
/**
|
927 |
+
* Add script to object to be added in specified contexts
|
928 |
+
* @param array|string $context Array of contexts to add script to page
|
929 |
+
* @see wp_enqueue_script for the following of the parameters
|
930 |
+
* @param $handle
|
931 |
+
* @param $src
|
932 |
+
* @param $deps
|
933 |
+
* @param $ver
|
934 |
+
* @param $in_footer
|
935 |
+
*/
|
936 |
+
function add_script( $context, $handle, $src = false, $deps = array(), $ver = false, $in_footer = false ) {
|
937 |
+
$args = func_get_args();
|
938 |
+
// Add file type to front of arguments array
|
939 |
+
array_unshift($args, 'scripts');
|
940 |
+
call_user_func_array($this->m('add_dependency'), $args);
|
941 |
+
}
|
942 |
+
|
943 |
+
/**
|
944 |
+
* Retrieve script dependencies for object
|
945 |
+
* @return array Script dependencies
|
946 |
+
*/
|
947 |
+
function get_scripts() {
|
948 |
+
return $this->get_member_value('scripts', '', array());
|
949 |
+
}
|
950 |
+
|
951 |
+
/**
|
952 |
+
* Add style to object to be added in specified contexts
|
953 |
+
* @param array|string $context Array of contexts to add style to page
|
954 |
+
* @see wp_enqueue_style for the following of the parameters
|
955 |
+
* @param $handle
|
956 |
+
* @param $src
|
957 |
+
* @param $deps
|
958 |
+
* @param $ver
|
959 |
+
* @param $in_footer
|
960 |
+
*/
|
961 |
+
function add_style( $handle, $src = false, $deps = array(), $ver = false, $media = false ) {
|
962 |
+
$args = func_get_args();
|
963 |
+
array_unshift($args, 'styles');
|
964 |
+
call_user_func_array($this->m('add_dependency'), $args);
|
965 |
+
}
|
966 |
+
|
967 |
+
/**
|
968 |
+
* Retrieve Style dependencies for object
|
969 |
+
* @return array Style dependencies
|
970 |
+
*/
|
971 |
+
function get_styles() {
|
972 |
+
return $this->get_member_value('styles', '', array());
|
973 |
+
}
|
974 |
+
|
975 |
+
/* Helpers */
|
976 |
+
|
977 |
+
/**
|
978 |
+
* Format value based on specified context
|
979 |
+
* @param mixed $value Value to format
|
980 |
+
* @param string $context Current context
|
981 |
+
* @return mixed Formatted value
|
982 |
+
*/
|
983 |
+
function format($value, $context = '') {
|
984 |
+
if ( is_scalar($context) && !empty($context) ) {
|
985 |
+
$handler = 'format_' . trim(strval($context));
|
986 |
+
// Only process if context is valid and has a handler
|
987 |
+
if ( !empty($context) && method_exists($this, $handler) ) {
|
988 |
+
// Pass value to handler
|
989 |
+
$value = $this->{$handler}($value, $context);
|
990 |
+
}
|
991 |
+
}
|
992 |
+
// Return formatted value
|
993 |
+
return $value;
|
994 |
+
}
|
995 |
+
|
996 |
+
/**
|
997 |
+
* Format value for output in form field
|
998 |
+
* @param mixed $value Value to format
|
999 |
+
* @return mixed Formatted value
|
1000 |
+
*/
|
1001 |
+
function format_form($value) {
|
1002 |
+
if ( is_string($value) )
|
1003 |
+
$value = htmlspecialchars($value);
|
1004 |
+
return $value;
|
1005 |
+
}
|
1006 |
+
|
1007 |
+
/**
|
1008 |
+
* Final formatting before output
|
1009 |
+
* Restores special characters, etc.
|
1010 |
+
* @uses $special_chars
|
1011 |
+
* @uses $special_chars_default
|
1012 |
+
* @param mixed $value Pre-final field output
|
1013 |
+
* @param string $context (Optional) Formatting context
|
1014 |
+
* @return mixed Formatted value
|
1015 |
+
*/
|
1016 |
+
function format_final($value, $context = '') {
|
1017 |
+
if ( !is_string($value) )
|
1018 |
+
return $value;
|
1019 |
+
|
1020 |
+
// Restore special chars
|
1021 |
+
return $this->restore_special_chars($value, $context);
|
1022 |
+
}
|
1023 |
+
|
1024 |
+
function preserve_special_chars($value, $context = '') {
|
1025 |
+
if ( !is_string($value) )
|
1026 |
+
return $value;
|
1027 |
+
$specials = $this->get_special_chars();
|
1028 |
+
return str_replace(array_keys($specials), $specials, $value);
|
1029 |
+
}
|
1030 |
+
|
1031 |
+
function restore_special_chars($value, $context = '') {
|
1032 |
+
if ( !is_string($value) )
|
1033 |
+
return $value;
|
1034 |
+
$specials = $this->get_special_chars();
|
1035 |
+
return str_replace($specials, array_keys($specials), $value);
|
1036 |
+
}
|
1037 |
+
|
1038 |
+
/**
|
1039 |
+
* Retrieve special characters/placeholders
|
1040 |
+
* Merges defaults with class-specific characters
|
1041 |
+
* @uses $special_chars
|
1042 |
+
* @uses $special_chars_default
|
1043 |
+
* @return array Special characters/placeholders
|
1044 |
+
*/
|
1045 |
+
function get_special_chars() {
|
1046 |
+
return wp_parse_args($this->special_chars, $this->special_chars_default);
|
1047 |
+
}
|
1048 |
+
}
|
includes/class.field_collection.php
ADDED
@@ -0,0 +1,764 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Managed collection of fields
|
4 |
+
* @package Simple Lightbox
|
5 |
+
* @subpackage Fields
|
6 |
+
* @author Archetyped
|
7 |
+
*/
|
8 |
+
class SLB_Field_Collection extends SLB_Field_Base {
|
9 |
+
|
10 |
+
/* Configuration */
|
11 |
+
|
12 |
+
protected $mode = 'sub';
|
13 |
+
|
14 |
+
/* Properties */
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Item type
|
18 |
+
* @var string
|
19 |
+
*/
|
20 |
+
var $item_type = 'SLB_Field';
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Indexed array of items in collection
|
24 |
+
* @var array
|
25 |
+
*/
|
26 |
+
var $items = array();
|
27 |
+
|
28 |
+
var $id_formats = array (
|
29 |
+
'formatted' => array(
|
30 |
+
'wrap' => array ( 'open' => '_' ),
|
31 |
+
'recursive' => false,
|
32 |
+
'prefix' => array('get_prefix')
|
33 |
+
)
|
34 |
+
);
|
35 |
+
|
36 |
+
var $build_vars_default = array (
|
37 |
+
'groups' => array(),
|
38 |
+
'context' => '',
|
39 |
+
'layout' => 'form',
|
40 |
+
'build' => true,
|
41 |
+
'build_groups' => true,
|
42 |
+
);
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Associative array of groups in collection
|
46 |
+
* Key: Group ID
|
47 |
+
* Value: object of group properties
|
48 |
+
* > id
|
49 |
+
* > title
|
50 |
+
* > description string Group description
|
51 |
+
* > items array Items in group
|
52 |
+
* @var array
|
53 |
+
*/
|
54 |
+
var $groups = array();
|
55 |
+
|
56 |
+
protected $properties_init = null;
|
57 |
+
|
58 |
+
/* Constructors */
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Class constructor
|
62 |
+
* @uses parent::__construct()
|
63 |
+
* @uses self::make_properties()
|
64 |
+
* @uses self::init()
|
65 |
+
* @uses self::add_groups()
|
66 |
+
* @uses self::add_items()
|
67 |
+
* @param string $id Collection ID
|
68 |
+
* @param array $properties (optional) Properties to set for collection (Default: none)
|
69 |
+
*/
|
70 |
+
public function __construct($id, $properties = null) {
|
71 |
+
$args = func_get_args();
|
72 |
+
$properties = $this->make_properties($args);
|
73 |
+
// Parent constructor
|
74 |
+
parent::__construct($properties);
|
75 |
+
|
76 |
+
// Save initial properties
|
77 |
+
$this->properties_init = $properties;
|
78 |
+
}
|
79 |
+
|
80 |
+
public function _init() {
|
81 |
+
parent::_init();
|
82 |
+
$this->load($this->properties_init, false);
|
83 |
+
}
|
84 |
+
|
85 |
+
/*-** Getters/Setters **-*/
|
86 |
+
|
87 |
+
/* Setup */
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Load collection with specified properties
|
91 |
+
* Updates existing properties
|
92 |
+
* @param array $properties Properties to load
|
93 |
+
* @param bool $update (optional) Update (TRUE) or overwrite (FALSE) items/groups (Default: TRUE)
|
94 |
+
* @return object Current instance
|
95 |
+
*/
|
96 |
+
public function load($properties, $update = true) {
|
97 |
+
$args = func_get_args();
|
98 |
+
$properties = $this->make_properties($args);
|
99 |
+
if ( !empty($properties) ) {
|
100 |
+
// Groups
|
101 |
+
if ( isset($properties['groups']) ) {
|
102 |
+
$this->add_groups($properties['groups'], $update);
|
103 |
+
}
|
104 |
+
// Items
|
105 |
+
if ( isset($properties['items']) ) {
|
106 |
+
$this->add_items($properties['items'], $update);
|
107 |
+
}
|
108 |
+
}
|
109 |
+
return $this;
|
110 |
+
}
|
111 |
+
|
112 |
+
/* Data */
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Retrieve external data for items in collection
|
116 |
+
* Retrieved data is saved to the collection's $data property
|
117 |
+
* Uses class properties to determine how data is retrieved
|
118 |
+
* Examples:
|
119 |
+
* > DB
|
120 |
+
* > XML
|
121 |
+
* > JSON
|
122 |
+
* @return void
|
123 |
+
*/
|
124 |
+
function load_data() {
|
125 |
+
$this->data_loaded = true;
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Set data for an item
|
130 |
+
* @param mixed $item Field to set data for
|
131 |
+
* > string Field ID
|
132 |
+
* > object Field Reference
|
133 |
+
* > array Data for multiple items (associative array [field ID => data])
|
134 |
+
* @param mixed $value Data to set
|
135 |
+
* @param bool $save (optional) Whether or not data should be saved to DB (Default: Yes)
|
136 |
+
*/
|
137 |
+
function set_data($item, $value = '', $save = true, $force_set = false) {
|
138 |
+
// Set data for entire collection
|
139 |
+
if ( is_array($item) ) {
|
140 |
+
$this->data = wp_parse_args($item, $this->data);
|
141 |
+
// Update save option
|
142 |
+
$args = func_get_args();
|
143 |
+
if ( 2 == count($args) && is_bool($args[1]) ) {
|
144 |
+
$save = $args[1];
|
145 |
+
}
|
146 |
+
}
|
147 |
+
// Get $item's ID
|
148 |
+
elseif ( is_object($item) && method_exists($item, 'get_id') )
|
149 |
+
$item = $item->get_id();
|
150 |
+
// Set data
|
151 |
+
if ( is_string($item) && !empty($item) && ( isset($this->items[$item]) || !!$force_set ) )
|
152 |
+
$this->data[$item] = $value;
|
153 |
+
if ( !!$save )
|
154 |
+
$this->save();
|
155 |
+
}
|
156 |
+
|
157 |
+
/* Item */
|
158 |
+
|
159 |
+
/**
|
160 |
+
* Adds item to collection
|
161 |
+
* @param string|obj $id Unique name for item or item instance
|
162 |
+
* @param array $properties (optional) Item properties
|
163 |
+
* @param bool $update (optional) Update or overwrite existing item (Default: FALSE)
|
164 |
+
* @return object Newly-added item
|
165 |
+
*/
|
166 |
+
function add($id, $properties = array(), $update = false) {
|
167 |
+
$item;
|
168 |
+
$args = func_get_args();
|
169 |
+
// Properties
|
170 |
+
foreach ( array_reverse($args) as $arg ) {
|
171 |
+
if ( is_array($arg) ) {
|
172 |
+
$properties = $arg;
|
173 |
+
break;
|
174 |
+
}
|
175 |
+
}
|
176 |
+
if ( !is_array($properties) ) {
|
177 |
+
$properties = array();
|
178 |
+
}
|
179 |
+
|
180 |
+
// Handle item instance
|
181 |
+
if ( $id instanceof $this->item_type ) {
|
182 |
+
$item = $id;
|
183 |
+
$item->set_properties($properties);
|
184 |
+
} elseif ( class_exists($this->item_type) ) {
|
185 |
+
$defaults = array (
|
186 |
+
'parent' => null,
|
187 |
+
'group' => null
|
188 |
+
);
|
189 |
+
$properties = array_merge($defaults, $properties);
|
190 |
+
if ( is_string($id) ) {
|
191 |
+
$properties['id'] = $id;
|
192 |
+
}
|
193 |
+
if ( !!$update && $this->has($properties['id']) ) {
|
194 |
+
// Update existing item
|
195 |
+
$item = $this->get($properties['id']);
|
196 |
+
$item->set_properties($properties);
|
197 |
+
} else {
|
198 |
+
// Init item
|
199 |
+
$type = $this->item_type;
|
200 |
+
$item = new $type($properties);
|
201 |
+
}
|
202 |
+
}
|
203 |
+
|
204 |
+
if ( empty($item) || 0 == strlen($item->get_id()) ) {
|
205 |
+
return false;
|
206 |
+
}
|
207 |
+
|
208 |
+
// Set container
|
209 |
+
$item->set_container($this);
|
210 |
+
|
211 |
+
// Add item to collection
|
212 |
+
$this->items[$item->get_id()] = $item;
|
213 |
+
|
214 |
+
if ( isset($properties['group']) ) {
|
215 |
+
$this->add_to_group($properties['group'], $item->get_id());
|
216 |
+
}
|
217 |
+
|
218 |
+
return $item;
|
219 |
+
}
|
220 |
+
|
221 |
+
/**
|
222 |
+
* Removes item from collection
|
223 |
+
* @param string|object $item Object or item ID to remove
|
224 |
+
* @param bool $save (optional) Whether to save the collection after removing item (Default: YES)
|
225 |
+
*/
|
226 |
+
function remove($item, $save = true) {
|
227 |
+
// Remove item
|
228 |
+
if ( $this->has($item) ) {
|
229 |
+
$item = $this->get($item);
|
230 |
+
$item = $item->get_id();
|
231 |
+
// Remove from items array
|
232 |
+
unset($this->items[$item]);
|
233 |
+
// Remove item from groups
|
234 |
+
$this->remove_from_group($item);
|
235 |
+
}
|
236 |
+
// Remove item data from collection
|
237 |
+
$this->remove_data($item, false);
|
238 |
+
|
239 |
+
if ( !!$save )
|
240 |
+
$this->save();
|
241 |
+
}
|
242 |
+
|
243 |
+
/**
|
244 |
+
* Remove item data from collection
|
245 |
+
* @param string|object $item Object or item ID to remove
|
246 |
+
* @param bool $save (optional) Whether to save the collection after removing item (Default: YES)
|
247 |
+
*/
|
248 |
+
function remove_data($item, $save = true) {
|
249 |
+
// Get item ID from object
|
250 |
+
if ( $this->has($item) ) {
|
251 |
+
$item = $this->get($item);
|
252 |
+
$item = $item->get_id();
|
253 |
+
}
|
254 |
+
|
255 |
+
// Remove data from data member
|
256 |
+
if ( is_string($item) && is_array($this->data) ) {
|
257 |
+
unset($this->data[$item]);
|
258 |
+
if ( !!$save )
|
259 |
+
$this->save();
|
260 |
+
}
|
261 |
+
}
|
262 |
+
|
263 |
+
/**
|
264 |
+
* Checks if item exists in the collection
|
265 |
+
* @param string $item Item ID
|
266 |
+
* @return bool TRUE if item exists, FALSE otherwise
|
267 |
+
*/
|
268 |
+
function has($item) {
|
269 |
+
return ( !is_string($item) || empty($item) || is_null($this->get_member_value('items', $item, null)) ) ? false : true;
|
270 |
+
}
|
271 |
+
|
272 |
+
/**
|
273 |
+
* Retrieve specified item in collection
|
274 |
+
* @param string|object $item Item object or ID to retrieve
|
275 |
+
* @return SLB_Field Specified item
|
276 |
+
*/
|
277 |
+
function get($item, $safe_mode = false) {
|
278 |
+
if ( $this->has($item) ) {
|
279 |
+
if ( !is_object($item) || !($item instanceof $this->item_type) ) {
|
280 |
+
if ( is_string($item) ) {
|
281 |
+
$item = trim($item);
|
282 |
+
$item =& $this->items[$item];
|
283 |
+
}
|
284 |
+
else {
|
285 |
+
$item = false;
|
286 |
+
}
|
287 |
+
}
|
288 |
+
} else {
|
289 |
+
$item = false;
|
290 |
+
}
|
291 |
+
|
292 |
+
if ( !!$safe_mode && !is_object($item) ) {
|
293 |
+
// Fallback: Return empty item if no item exists
|
294 |
+
$type = $this->item_type;
|
295 |
+
$item = new $type('');
|
296 |
+
}
|
297 |
+
return $item;
|
298 |
+
}
|
299 |
+
|
300 |
+
/**
|
301 |
+
* Retrieve item data
|
302 |
+
* @param $item Item to get data for
|
303 |
+
* @param $context (optional) Context
|
304 |
+
* @param $top (optional) Iterate through ancestors to get data (Default: Yes)
|
305 |
+
* @return mixed Item data
|
306 |
+
*/
|
307 |
+
function get_data($item = null, $context = '', $top = true) {
|
308 |
+
$this->load_data();
|
309 |
+
$ret = null;
|
310 |
+
if ( $this->has($item) ) {
|
311 |
+
$item = $this->get($item);
|
312 |
+
$ret = $item->get_data($context, $top);
|
313 |
+
} else {
|
314 |
+
$ret = parent::get_data($context, $top);
|
315 |
+
}
|
316 |
+
|
317 |
+
if ( is_string($item) && is_array($ret) && isset($ret[$item]) )
|
318 |
+
$ret = $ret[$item];
|
319 |
+
return $ret;
|
320 |
+
}
|
321 |
+
|
322 |
+
/* Items (Collection) */
|
323 |
+
|
324 |
+
/**
|
325 |
+
* Add multiple items to collection
|
326 |
+
* @param array $items Items to add to collection
|
327 |
+
* Array Structure:
|
328 |
+
* > Key (string): Item ID
|
329 |
+
* > Val (array): Item properties
|
330 |
+
* @return void
|
331 |
+
*/
|
332 |
+
function add_items($items = array(), $update = false) {
|
333 |
+
// Validate
|
334 |
+
if ( !is_array($items) || empty($items) ) {
|
335 |
+
return false;
|
336 |
+
}
|
337 |
+
// Add items
|
338 |
+
foreach ( $items as $id => $props ) {
|
339 |
+
$this->add($id, $props, $update);
|
340 |
+
}
|
341 |
+
}
|
342 |
+
|
343 |
+
/**
|
344 |
+
* Retrieve reference to items in collection
|
345 |
+
* @return array Collection items (reference)
|
346 |
+
*/
|
347 |
+
function &get_items($group = null, $sort = 'priority') {
|
348 |
+
$gset = $this->group_exists($group);
|
349 |
+
if ( $gset ) {
|
350 |
+
$items = $this->get_group_items($group);
|
351 |
+
} elseif ( !empty($group) ) {
|
352 |
+
$items = array();
|
353 |
+
} else {
|
354 |
+
$items = $this->items;
|
355 |
+
}
|
356 |
+
if ( !empty($items) ) {
|
357 |
+
// Sort items
|
358 |
+
if ( !empty($sort) && is_string($sort) ) {
|
359 |
+
if ( 'priority' == $sort ) {
|
360 |
+
if ( $gset ) {
|
361 |
+
// Sort by priority
|
362 |
+
ksort($items, SORT_NUMERIC);
|
363 |
+
}
|
364 |
+
}
|
365 |
+
}
|
366 |
+
// Release from buckets
|
367 |
+
if ( $gset ) {
|
368 |
+
$items = call_user_func_array('array_merge', $items);
|
369 |
+
}
|
370 |
+
}
|
371 |
+
return $items;
|
372 |
+
}
|
373 |
+
|
374 |
+
/**
|
375 |
+
* Build output for items in specified group
|
376 |
+
* If no group specified, all items in collection are built
|
377 |
+
* @param string|object $group (optional) Group to build items for (ID or instance object)
|
378 |
+
*/
|
379 |
+
function build_items($group = null) {
|
380 |
+
// Get group items
|
381 |
+
$items =& $this->get_items($group);
|
382 |
+
if ( empty($items) ) {
|
383 |
+
return false;
|
384 |
+
}
|
385 |
+
|
386 |
+
$this->util->do_action_ref_array('build_items_pre', array($this));
|
387 |
+
foreach ( $items as $item ) {
|
388 |
+
$item->build();
|
389 |
+
}
|
390 |
+
$this->util->do_action_ref_array('build_items_post', array($this));
|
391 |
+
}
|
392 |
+
|
393 |
+
/* Group */
|
394 |
+
|
395 |
+
/**
|
396 |
+
* Add groups to collection
|
397 |
+
* @param array $groups Associative array of group properties
|
398 |
+
* Array structure:
|
399 |
+
* > Key (string): group ID
|
400 |
+
* > Val (string): Group Title
|
401 |
+
*/
|
402 |
+
function add_groups($groups = array(), $update = false) {
|
403 |
+
// Validate
|
404 |
+
if ( !is_array($groups) || empty($groups) ) {
|
405 |
+
return false;
|
406 |
+
}
|
407 |
+
// Iterate
|
408 |
+
foreach ( $groups as $id => $props ) {
|
409 |
+
$this->add_group($id, $props, null, $update);
|
410 |
+
}
|
411 |
+
}
|
412 |
+
|
413 |
+
/**
|
414 |
+
* Adds group to collection
|
415 |
+
* Groups are used to display related items in the UI
|
416 |
+
* @param string $id Unique name for group
|
417 |
+
* @param string $title Group title
|
418 |
+
* @param string $description Short description of group's purpose
|
419 |
+
* @param array $items (optional) ID's of existing items to add to group
|
420 |
+
* @return object Group object
|
421 |
+
*/
|
422 |
+
function &add_group($id, $properties = array(), $items = array(), $update = false) {
|
423 |
+
// Create new group and set properties
|
424 |
+
$default = array (
|
425 |
+
'title' => '',
|
426 |
+
'description' => '',
|
427 |
+
'priority' => 10
|
428 |
+
);
|
429 |
+
$p = ( is_array($properties) ) ? array_merge($default, $properties) : $default;
|
430 |
+
if ( !is_int($p['priority']) || $p['priority'] < 0 ) {
|
431 |
+
$p['priority'] = $default['priority'];
|
432 |
+
}
|
433 |
+
$id = trim($id);
|
434 |
+
// Retrieve or init group
|
435 |
+
if ( !!$update && $this->group_exists($id) ) {
|
436 |
+
$grp = $this->get_group($id);
|
437 |
+
$grp->title = $p['title'];
|
438 |
+
$grp->description = $p['description'];
|
439 |
+
$grp->priority = $p['priority'];
|
440 |
+
} else {
|
441 |
+
$this->groups[$id] =& $this->create_group($id, $p['title'], $p['description'], $p['priority']);
|
442 |
+
}
|
443 |
+
// Add items to group (if supplied)
|
444 |
+
if ( !empty($items) && is_array($items) ) {
|
445 |
+
$this->add_to_group($id, $items);
|
446 |
+
}
|
447 |
+
return $this->groups[$id];
|
448 |
+
}
|
449 |
+
|
450 |
+
/**
|
451 |
+
* Remove specified group from collection
|
452 |
+
* @param string $id Group ID to remove
|
453 |
+
*/
|
454 |
+
function remove_group($id) {
|
455 |
+
$id = trim($id);
|
456 |
+
if ( $this->group_exists($id) ) {
|
457 |
+
unset($this->groups[$id]);
|
458 |
+
}
|
459 |
+
}
|
460 |
+
|
461 |
+
/**
|
462 |
+
* Standardized method to create a new item group
|
463 |
+
* @param string $title Group title (used in meta boxes, etc.)
|
464 |
+
* @param string $description Short description of group's purpose
|
465 |
+
* @param int $priority (optional) Group priority (e.g. used to sort groups during output)
|
466 |
+
* @return object Group object
|
467 |
+
*/
|
468 |
+
function &create_group($id = '', $title = '', $description = '', $priority = 10) {
|
469 |
+
// Create new group object
|
470 |
+
$group = new stdClass();
|
471 |
+
/* Set group properties */
|
472 |
+
// Set ID
|
473 |
+
$id = ( is_scalar($id) ) ? trim($id) : '';
|
474 |
+
$group->id = $id;
|
475 |
+
// Set Title
|
476 |
+
$title = ( is_scalar($title) ) ? trim($title) : '';
|
477 |
+
$group->title = $title;
|
478 |
+
// Set Description
|
479 |
+
$description = ( is_scalar($description) ) ? trim($description) : '';
|
480 |
+
$group->description = $description;
|
481 |
+
// Priority
|
482 |
+
$group->priority = ( is_int($priority) ) ? $priority : 10;
|
483 |
+
// Create array to hold items
|
484 |
+
$group->items = array();
|
485 |
+
return $group;
|
486 |
+
}
|
487 |
+
|
488 |
+
/**
|
489 |
+
* Checks if group exists in collection
|
490 |
+
* @param string $id Group name
|
491 |
+
* @return bool TRUE if group exists, FALSE otherwise
|
492 |
+
*/
|
493 |
+
function group_exists($group) {
|
494 |
+
$ret = false;
|
495 |
+
if ( is_object($group) ) {
|
496 |
+
$ret = true;
|
497 |
+
} elseif ( is_string($group) && ($group = trim($group)) && strlen($group) > 0 ) {
|
498 |
+
$group = trim($group);
|
499 |
+
// Check if group exists
|
500 |
+
$ret = !is_null($this->get_member_value('groups', $group, null));
|
501 |
+
}
|
502 |
+
return $ret;
|
503 |
+
}
|
504 |
+
|
505 |
+
/**
|
506 |
+
* Adds item to a group in the collection
|
507 |
+
* Group is created if it does not already exist
|
508 |
+
* @param string|array $group ID of group (or group parameters if new group) to add item to
|
509 |
+
* @param string|array $items Name or array of item(s) to add to group
|
510 |
+
*/
|
511 |
+
function add_to_group($group, $items, $priority = 10) {
|
512 |
+
// Validate
|
513 |
+
if ( empty($items) || empty($group) || ( !is_string($group) && !is_array($group) ) ) {
|
514 |
+
return false;
|
515 |
+
}
|
516 |
+
|
517 |
+
// Get group ID
|
518 |
+
if ( is_string($group) ) {
|
519 |
+
$group = array($group, $priority);
|
520 |
+
}
|
521 |
+
list($gid, $priority) = $group;
|
522 |
+
$gid = trim(sanitize_title_with_dashes($gid));
|
523 |
+
if ( empty($gid) ) {
|
524 |
+
return false;
|
525 |
+
}
|
526 |
+
// Item priority
|
527 |
+
if ( !is_int($priority) ) {
|
528 |
+
$priority = 10;
|
529 |
+
}
|
530 |
+
|
531 |
+
// Prepare group
|
532 |
+
if ( !$this->group_exists($gid) ) {
|
533 |
+
// TODO Follow
|
534 |
+
call_user_func($this->m('add_group'), $gid, $group);
|
535 |
+
}
|
536 |
+
// Prepare items
|
537 |
+
if ( !is_array($items) ) {
|
538 |
+
$items = array($items);
|
539 |
+
}
|
540 |
+
// Add Items
|
541 |
+
foreach ( $items as $item ) {
|
542 |
+
// Skip if not in current collection
|
543 |
+
$itm_ref = $this->get($item);
|
544 |
+
if ( !$itm_ref ) {
|
545 |
+
continue;
|
546 |
+
}
|
547 |
+
$itm_id = $itm_ref->get_id();
|
548 |
+
// Remove item from any other group it's in (items can only be in one group)
|
549 |
+
foreach ( $this->get_groups() as $group ) {
|
550 |
+
foreach ( $group->items as $tmp_pri => $tmp_items ) {
|
551 |
+
if ( isset($group->items[$tmp_pri][$itm_id]) ) {
|
552 |
+
unset($group->items[$tmp_pri][$itm_id]);
|
553 |
+
}
|
554 |
+
}
|
555 |
+
}
|
556 |
+
// Add reference to item in group
|
557 |
+
$items =& $this->get_group($gid)->items;
|
558 |
+
if ( !isset($items[$priority]) ) {
|
559 |
+
$items[$priority] = array();
|
560 |
+
}
|
561 |
+
$items[$priority][$itm_id] = $itm_ref;
|
562 |
+
}
|
563 |
+
unset($itm_ref);
|
564 |
+
}
|
565 |
+
|
566 |
+
/**
|
567 |
+
* Remove item from a group
|
568 |
+
* If no group is specified, then item is removed from all groups
|
569 |
+
* @param string|object $item Object or ID of item to remove from group
|
570 |
+
* @param string $group (optional) Group ID to remove item from
|
571 |
+
*/
|
572 |
+
function remove_from_group($item, $group = '') {
|
573 |
+
// Get ID of item to remove or stop execution if item invalid
|
574 |
+
$item = $this->get($item);
|
575 |
+
$item = $item->get_id();
|
576 |
+
if ( !$item )
|
577 |
+
return false;
|
578 |
+
|
579 |
+
// Remove item from group
|
580 |
+
if ( !empty($group) ) {
|
581 |
+
// Remove item from single group
|
582 |
+
if ( ($group =& $this->get_group($group)) && isset($group->items[$item]) ) {
|
583 |
+
unset($group->items[$item]);
|
584 |
+
}
|
585 |
+
} else {
|
586 |
+
// Remove item from all groups
|
587 |
+
foreach ( array_keys($this->groups) as $group ) {
|
588 |
+
if ( ($group =& $this->get_group($group)) && isset($group->items[$item]) ) {
|
589 |
+
unset($group->items[$item]);
|
590 |
+
}
|
591 |
+
}
|
592 |
+
}
|
593 |
+
}
|
594 |
+
|
595 |
+
/**
|
596 |
+
* Retrieve specified group
|
597 |
+
* @param string $group ID of group to retrieve
|
598 |
+
* @return object Reference to specified group
|
599 |
+
*/
|
600 |
+
function &get_group($group) {
|
601 |
+
if ( is_object($group) ) {
|
602 |
+
return $group;
|
603 |
+
}
|
604 |
+
if ( is_string($group) ) {
|
605 |
+
$group = trim($group);
|
606 |
+
}
|
607 |
+
// Create group if it doesn't already exist
|
608 |
+
if ( ! $this->group_exists($group) ) {
|
609 |
+
$this->add_group($group);
|
610 |
+
}
|
611 |
+
return $this->get_member_value('groups', $group);
|
612 |
+
}
|
613 |
+
|
614 |
+
/**
|
615 |
+
* Retrieve a group's items
|
616 |
+
* @uses SLB_Field_Collection::get_group() to retrieve group object
|
617 |
+
* @param object|string $group Group object or group ID
|
618 |
+
* @return array Group's items
|
619 |
+
*/
|
620 |
+
function &get_group_items($group) {
|
621 |
+
$group =& $this->get_group($group);
|
622 |
+
return $group->items;
|
623 |
+
}
|
624 |
+
|
625 |
+
/**
|
626 |
+
* Retrieve all groups in collection
|
627 |
+
* @return array Reference to group objects
|
628 |
+
*/
|
629 |
+
function &get_groups($opts = array()) {
|
630 |
+
$groups =& $this->get_member_value('groups');
|
631 |
+
if ( is_array($opts) && !empty($opts) ) {
|
632 |
+
extract($opts, EXTR_SKIP);
|
633 |
+
if ( !empty($groups) && !empty($sort) && is_string($sort) ) {
|
634 |
+
if ( property_exists(current($groups), $sort) ) {
|
635 |
+
// Sort groups by property
|
636 |
+
$sfunc = function ( $a, $b ) use ($sort) {
|
637 |
+
$ap = $a->$sort;
|
638 |
+
$bp = $b->$sort;
|
639 |
+
if ( $ap == $bp ) {
|
640 |
+
return 0;
|
641 |
+
}
|
642 |
+
return ( $ap > $bp ) ? 1 : -1;
|
643 |
+
};
|
644 |
+
uasort($groups, $sfunc);
|
645 |
+
}
|
646 |
+
}
|
647 |
+
}
|
648 |
+
return $groups;
|
649 |
+
}
|
650 |
+
|
651 |
+
/**
|
652 |
+
* Output groups
|
653 |
+
* @uses self::build_vars to determine groups to build
|
654 |
+
*/
|
655 |
+
function build_groups() {
|
656 |
+
$this->util->do_action_ref_array('build_groups_pre', array($this));
|
657 |
+
|
658 |
+
// Get groups to build
|
659 |
+
$groups = ( !empty($this->build_vars['groups']) ) ? $this->build_vars['groups'] : array_keys($this->get_groups(array('sort' => 'priority')));
|
660 |
+
// Check options
|
661 |
+
if ( is_callable($this->build_vars['build_groups']) ) {
|
662 |
+
// Pass groups to callback to build output
|
663 |
+
call_user_func_array($this->build_vars['build_groups'], array($this, $groups));
|
664 |
+
} elseif ( !!$this->build_vars['build_groups'] ) {
|
665 |
+
// Build groups
|
666 |
+
foreach ( $groups as $group ) {
|
667 |
+
$this->build_group($group);
|
668 |
+
}
|
669 |
+
}
|
670 |
+
|
671 |
+
$this->util->do_action_ref_array('build_groups_post', array($this));
|
672 |
+
}
|
673 |
+
|
674 |
+
/**
|
675 |
+
* Build group
|
676 |
+
*/
|
677 |
+
function build_group($group) {
|
678 |
+
if ( !$this->group_exists($group) ) {
|
679 |
+
return false;
|
680 |
+
}
|
681 |
+
$group =& $this->get_group($group);
|
682 |
+
// Stop processing if group contains no items
|
683 |
+
if ( !count($this->get_items($group)) ) {
|
684 |
+
return false;
|
685 |
+
}
|
686 |
+
|
687 |
+
// Pre action
|
688 |
+
$this->util->do_action_ref_array('build_group_pre', array($this, $group));
|
689 |
+
|
690 |
+
// Build items
|
691 |
+
$this->build_items($group);
|
692 |
+
|
693 |
+
// Post action
|
694 |
+
$this->util->do_action_ref_array('build_group_post', array($this, $group));
|
695 |
+
}
|
696 |
+
|
697 |
+
/* Collection */
|
698 |
+
|
699 |
+
/**
|
700 |
+
* Build entire collection of items
|
701 |
+
* Prints output
|
702 |
+
*/
|
703 |
+
function build($build_vars = array()) {
|
704 |
+
// Parse vars
|
705 |
+
$this->parse_build_vars($build_vars);
|
706 |
+
$this->util->do_action_ref_array('build_init', array($this));
|
707 |
+
// Pre-build output
|
708 |
+
$this->util->do_action_ref_array('build_pre', array($this));
|
709 |
+
// Build groups
|
710 |
+
$this->build_groups();
|
711 |
+
// Post-build output
|
712 |
+
$this->util->do_action_ref_array('build_post', array($this));
|
713 |
+
}
|
714 |
+
|
715 |
+
/**
|
716 |
+
* Set build variable
|
717 |
+
* @param string $key Variable name
|
718 |
+
* @param mixed $val Variable value
|
719 |
+
*/
|
720 |
+
function set_build_var($key, $val) {
|
721 |
+
$this->build_vars[$key] = $val;
|
722 |
+
}
|
723 |
+
|
724 |
+
/**
|
725 |
+
* Retrieve build variable
|
726 |
+
* @param string $key Variable name
|
727 |
+
* @param mixed $default Value if variable is not set
|
728 |
+
* @return mixed Variable value
|
729 |
+
*/
|
730 |
+
function get_build_var($key, $default = null) {
|
731 |
+
return ( array_key_exists($key, $this->build_vars) ) ? $this->build_vars[$key] : $default;
|
732 |
+
}
|
733 |
+
|
734 |
+
/**
|
735 |
+
* Delete build variable
|
736 |
+
* @param string $key Variable name to delete
|
737 |
+
*/
|
738 |
+
function delete_build_var($key) {
|
739 |
+
if ( array_key_exists($key, $this->build_vars) ) {
|
740 |
+
unset($this->build_vars[$key]);
|
741 |
+
}
|
742 |
+
}
|
743 |
+
|
744 |
+
/**
|
745 |
+
* Parses build variables prior to use
|
746 |
+
* @uses this->reset_build_vars() to reset build variables for each request
|
747 |
+
* @param array $build_vars Variables to use for current request
|
748 |
+
*/
|
749 |
+
function parse_build_vars($build_vars = array()) {
|
750 |
+
$this->reset_build_vars();
|
751 |
+
$this->build_vars = $this->util->apply_filters('parse_build_vars', wp_parse_args($build_vars, $this->build_vars), $this);
|
752 |
+
}
|
753 |
+
|
754 |
+
/**
|
755 |
+
* Reset build variables to defaults
|
756 |
+
* Default Variables
|
757 |
+
* > groups - array - Names of groups to build
|
758 |
+
* > context - string - Context of current request
|
759 |
+
* > layout - string - Name of default layout to use
|
760 |
+
*/
|
761 |
+
function reset_build_vars() {
|
762 |
+
$this->build_vars = wp_parse_args($this->build_vars, $this->build_vars_default);
|
763 |
+
}
|
764 |
+
}
|
includes/class.field_type.php
ADDED
@@ -0,0 +1,405 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Field Types
|
4 |
+
* Stores properties for a specific field
|
5 |
+
* @package Simple Lightbox
|
6 |
+
* @subpackage Fields
|
7 |
+
* @author Archetyped
|
8 |
+
*/
|
9 |
+
class SLB_Field_Type extends SLB_Field_Base {
|
10 |
+
/* Properties */
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @var array Array of Field types that make up current Field type
|
14 |
+
*/
|
15 |
+
var $elements = array();
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var array Field type layouts
|
19 |
+
*/
|
20 |
+
var $layout = array();
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @var SLB_Field_Type Parent field type (reference)
|
24 |
+
*/
|
25 |
+
var $parent = null;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Object that field is in
|
29 |
+
* @var SLB_Field|SLB_Field_Type|SLB_Field_Collection
|
30 |
+
*/
|
31 |
+
var $container = null;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Object that called field
|
35 |
+
* Used to determine field hierarchy/nesting
|
36 |
+
* @var SLB_Field|SLB_Field_Type|SLB_Field_Collection
|
37 |
+
*/
|
38 |
+
var $caller = null;
|
39 |
+
|
40 |
+
function __construct($id = '', $parent = null) {
|
41 |
+
$args = func_get_args();
|
42 |
+
$defaults = $this->integrate_id($id);
|
43 |
+
if ( !is_array($parent) )
|
44 |
+
$defaults['parent'] = $parent;
|
45 |
+
|
46 |
+
$props = $this->make_properties($args, $defaults);
|
47 |
+
parent::__construct($props);
|
48 |
+
}
|
49 |
+
|
50 |
+
/* Getters/Setters */
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Search for specified member value in field's container object (if exists)
|
54 |
+
* @param string $member Name of object member to search (e.g. properties, layout, etc.)
|
55 |
+
* @param string $name Value to retrieve from member
|
56 |
+
* @return mixed Member value if found (Default: empty string)
|
57 |
+
*/
|
58 |
+
function get_container_value($member, $name = '', $default = '') {
|
59 |
+
$container =& $this->get_container();
|
60 |
+
return $this->get_object_value($container, $member, $name, $default, 'container');
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Search for specified member value in field's container object (if exists)
|
65 |
+
* @param string $member Name of object member to search (e.g. properties, layout, etc.)
|
66 |
+
* @param string $name Value to retrieve from member
|
67 |
+
* @return mixed Member value if found (Default: empty string)
|
68 |
+
*/
|
69 |
+
function get_caller_value($member, $name = '', $default = '') {
|
70 |
+
$caller =& $this->get_caller();
|
71 |
+
return $this->get_object_value($caller, $member, $name, $default, 'caller');
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Sets reference to container object of current field
|
76 |
+
* Reference is cleared if no valid object is passed to method
|
77 |
+
* @param object $container
|
78 |
+
*/
|
79 |
+
function set_container(&$container) {
|
80 |
+
if ( !empty($container) && is_object($container) ) {
|
81 |
+
// Set as param as container for current field
|
82 |
+
$this->container =& $container;
|
83 |
+
} else {
|
84 |
+
// Clear container member if argument is invalid
|
85 |
+
$this->clear_container();
|
86 |
+
}
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Clears reference to container object of current field
|
91 |
+
*/
|
92 |
+
function clear_container() {
|
93 |
+
$this->container = null;
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Retrieves reference to container object of current field
|
98 |
+
* @return object Reference to container object
|
99 |
+
*/
|
100 |
+
function &get_container() {
|
101 |
+
$ret = null;
|
102 |
+
if ( $this->has_container() )
|
103 |
+
$ret =& $this->container;
|
104 |
+
return $ret;
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Checks if field has a container reference
|
109 |
+
* @return bool TRUE if field is contained, FALSE otherwise
|
110 |
+
*/
|
111 |
+
function has_container() {
|
112 |
+
return !empty($this->container);
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Sets reference to calling object of current field
|
117 |
+
* Any existing reference is cleared if no valid object is passed to method
|
118 |
+
* @param object $caller Calling object
|
119 |
+
*/
|
120 |
+
function set_caller(&$caller) {
|
121 |
+
if ( !empty($caller) && is_object($caller) )
|
122 |
+
$this->caller =& $caller;
|
123 |
+
else
|
124 |
+
$this->clear_caller();
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Clears reference to calling object of current field
|
129 |
+
*/
|
130 |
+
function clear_caller() {
|
131 |
+
unset($this->caller);
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Retrieves reference to caller object of current field
|
136 |
+
* @return object Reference to caller object
|
137 |
+
*/
|
138 |
+
function &get_caller() {
|
139 |
+
$ret = null;
|
140 |
+
if ( $this->has_caller() )
|
141 |
+
$ret =& $this->caller;
|
142 |
+
return $ret;
|
143 |
+
}
|
144 |
+
|
145 |
+
/**
|
146 |
+
* Checks if field has a caller reference
|
147 |
+
* @return bool TRUE if field is called by another field, FALSE otherwise
|
148 |
+
*/
|
149 |
+
function has_caller() {
|
150 |
+
return !empty($this->caller);
|
151 |
+
}
|
152 |
+
|
153 |
+
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Sets an element for the field type
|
157 |
+
* @param string $name Name of element
|
158 |
+
* @param SLB_Field_Type $type Reference of field type to use for element
|
159 |
+
* @param array $properties Properties for element (passed as keyed associative array)
|
160 |
+
* @param string $id_prop Name of property to set $name to (e.g. ID, etc.)
|
161 |
+
*/
|
162 |
+
function set_element($name, $type, $properties = array(), $id_prop = 'id') {
|
163 |
+
$name = trim(strval($name));
|
164 |
+
if ( empty($name) )
|
165 |
+
return false;
|
166 |
+
// Create new field for element
|
167 |
+
$el = new SLB_Field($name, $type);
|
168 |
+
// Set container to current field instance
|
169 |
+
$el->set_container($this);
|
170 |
+
// Add properties to element
|
171 |
+
$el->set_properties($properties);
|
172 |
+
// Save element to current instance
|
173 |
+
$this->elements[$name] =& $el;
|
174 |
+
}
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Add a layout to the field
|
178 |
+
* @param string $name Name of layout
|
179 |
+
* @param string $value Layout text
|
180 |
+
*/
|
181 |
+
function set_layout($name, $value = '') {
|
182 |
+
if ( !is_string($name) )
|
183 |
+
return false;
|
184 |
+
$name = trim($name);
|
185 |
+
$this->layout[$name] = $value;
|
186 |
+
return true;
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* Retrieve specified layout
|
191 |
+
* @param string $name Layout name
|
192 |
+
* @param bool $parse_nested (optional) Whether nested layouts should be expanded in retreived layout or not (Default: TRUE)
|
193 |
+
* @return string Specified layout text
|
194 |
+
*/
|
195 |
+
function get_layout($name = 'form', $parse_nested = true) {
|
196 |
+
// Retrieve specified layout (use $name value if no layout by that name exists)
|
197 |
+
if ( empty($name) )
|
198 |
+
$name = $this->get_container_value('build_vars', 'layout', 'form');
|
199 |
+
$layout = $this->get_member_value('layout', $name, $name);
|
200 |
+
|
201 |
+
// Find all nested layouts in current layout
|
202 |
+
if ( !empty($layout) && !!$parse_nested ) {
|
203 |
+
$ph = $this->get_placeholder_defaults();
|
204 |
+
|
205 |
+
while ($ph->match = $this->parse_layout($layout, $ph->pattern_layout)) {
|
206 |
+
// Iterate through the different types of layout placeholders
|
207 |
+
foreach ($ph->match as $tag => $instances) {
|
208 |
+
// Iterate through instances of a specific type of layout placeholder
|
209 |
+
foreach ($instances as $instance) {
|
210 |
+
// Get nested layout
|
211 |
+
$nested_layout = $this->get_member_value($instance);
|
212 |
+
|
213 |
+
// Replace layout placeholder with retrieved item data
|
214 |
+
if ( !empty($nested_layout) )
|
215 |
+
$layout = str_replace($ph->start . $instance['match'] . $ph->end, $nested_layout, $layout);
|
216 |
+
}
|
217 |
+
}
|
218 |
+
}
|
219 |
+
}
|
220 |
+
|
221 |
+
return $layout;
|
222 |
+
}
|
223 |
+
|
224 |
+
/**
|
225 |
+
* Checks if specified layout exists
|
226 |
+
* Finds layout if it exists in current object or any of its parents
|
227 |
+
* @param string $layout Name of layout to check for
|
228 |
+
* @return bool TRUE if layout exists, FALSE otherwise
|
229 |
+
*/
|
230 |
+
function has_layout($layout) {
|
231 |
+
$ret = false;
|
232 |
+
if ( is_string($layout) && ($layout = trim($layout)) && !empty($layout) ) {
|
233 |
+
$layout = $this->get_member_value('layout', $layout, false);
|
234 |
+
if ( $layout !== false )
|
235 |
+
$ret = true;
|
236 |
+
}
|
237 |
+
|
238 |
+
return $ret;
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Checks if layout content is valid
|
243 |
+
* Layouts need to have placeholders to be valid
|
244 |
+
* @param string $layout_content Layout content (markup)
|
245 |
+
* @return bool TRUE if layout is valid, FALSE otherwise
|
246 |
+
*/
|
247 |
+
function is_valid_layout($layout_content) {
|
248 |
+
$ph = $this->get_placeholder_defaults();
|
249 |
+
return preg_match($ph->pattern_general, $layout_content);
|
250 |
+
}
|
251 |
+
|
252 |
+
/**
|
253 |
+
* Parse field layout with a regular expression
|
254 |
+
* @param string $layout Layout data
|
255 |
+
* @param string $search Regular expression pattern to search layout for
|
256 |
+
* @return array Associative array containing all of the regular expression matches in the layout data
|
257 |
+
* Array Structure:
|
258 |
+
* root => placeholder tags
|
259 |
+
* => Tag instances (array)
|
260 |
+
* 'tag' => (string) tag name
|
261 |
+
* 'match' => (string) placeholder match
|
262 |
+
* 'attributes' => (array) attributes
|
263 |
+
*/
|
264 |
+
function parse_layout($layout, $search) {
|
265 |
+
$ph_xml = '';
|
266 |
+
$parse_match = '';
|
267 |
+
$ph_root_tag = 'ph_root_element';
|
268 |
+
$ph_start_xml = '<';
|
269 |
+
$ph_end_xml = ' />';
|
270 |
+
$ph_wrap_start = '<' . $ph_root_tag . '>';
|
271 |
+
$ph_wrap_end = '</' . $ph_root_tag . '>';
|
272 |
+
$parse_result = false;
|
273 |
+
|
274 |
+
// Find all nested layouts in layout
|
275 |
+
$match_value = preg_match_all($search, $layout, $parse_match, PREG_PATTERN_ORDER);
|
276 |
+
|
277 |
+
if ($match_value !== false && $match_value > 0) {
|
278 |
+
$parse_result = array();
|
279 |
+
// Get all matched elements
|
280 |
+
$parse_match = $parse_match[1];
|
281 |
+
|
282 |
+
// Build XML string from placeholders
|
283 |
+
foreach ($parse_match as $ph) {
|
284 |
+
$ph_xml .= $ph_start_xml . $ph . $ph_end_xml . ' ';
|
285 |
+
}
|
286 |
+
$ph_xml = $ph_wrap_start . $ph_xml . $ph_wrap_end;
|
287 |
+
// Parse XML data
|
288 |
+
$ph_prs = xml_parser_create();
|
289 |
+
xml_parser_set_option($ph_prs, XML_OPTION_SKIP_WHITE, 1);
|
290 |
+
xml_parser_set_option($ph_prs, XML_OPTION_CASE_FOLDING, 0);
|
291 |
+
$ret = xml_parse_into_struct($ph_prs, $ph_xml, $parse_result['values'], $parse_result['index']);
|
292 |
+
xml_parser_free($ph_prs);
|
293 |
+
|
294 |
+
// Build structured array with all parsed data
|
295 |
+
|
296 |
+
unset($parse_result['index'][$ph_root_tag]);
|
297 |
+
|
298 |
+
// Build structured array
|
299 |
+
$result = array();
|
300 |
+
foreach ($parse_result['index'] as $tag => $instances) {
|
301 |
+
$result[$tag] = array();
|
302 |
+
// Instances
|
303 |
+
foreach ($instances as $instance) {
|
304 |
+
// Skip instance if it doesn't exist in parse results
|
305 |
+
if (!isset($parse_result['values'][$instance]))
|
306 |
+
continue;
|
307 |
+
|
308 |
+
// Stop processing instance if a previously-saved instance with the same options already exists
|
309 |
+
foreach ($result[$tag] as $tag_match) {
|
310 |
+
if ($tag_match['match'] == $parse_match[$instance - 1])
|
311 |
+
continue 2;
|
312 |
+
}
|
313 |
+
|
314 |
+
// Init instance data array
|
315 |
+
$inst_data = array();
|
316 |
+
|
317 |
+
// Add Tag to array
|
318 |
+
$inst_data['tag'] = $parse_result['values'][$instance]['tag'];
|
319 |
+
|
320 |
+
// Add instance data to array
|
321 |
+
$inst_data['attributes'] = (isset($parse_result['values'][$instance]['attributes'])) ? $inst_data['attributes'] = $parse_result['values'][$instance]['attributes'] : '';
|
322 |
+
|
323 |
+
// Add match to array
|
324 |
+
$inst_data['match'] = $parse_match[$instance - 1];
|
325 |
+
|
326 |
+
// Add to result array
|
327 |
+
$result[$tag][] = $inst_data;
|
328 |
+
}
|
329 |
+
}
|
330 |
+
$parse_result = $result;
|
331 |
+
}
|
332 |
+
|
333 |
+
return $parse_result;
|
334 |
+
}
|
335 |
+
|
336 |
+
/**
|
337 |
+
* Retrieves default properties to use when evaluating layout placeholders
|
338 |
+
* @return object Object with properties for evaluating layout placeholders
|
339 |
+
*/
|
340 |
+
function get_placeholder_defaults() {
|
341 |
+
$ph = new stdClass();
|
342 |
+
$ph->start = '{';
|
343 |
+
$ph->end = '}';
|
344 |
+
$ph->reserved = array('ref' => 'ref_base');
|
345 |
+
$ph->pattern_general = '/' . $ph->start . '([a-zA-Z0-9_].*?)' . $ph->end . '/i';
|
346 |
+
$ph->pattern_layout = '/' . $ph->start . '([a-zA-Z0-9].*?\s+' . $ph->reserved['ref'] . '="layout.*?".*?)' . $ph->end . '/i';
|
347 |
+
return $ph;
|
348 |
+
}
|
349 |
+
|
350 |
+
/**
|
351 |
+
* Build item output
|
352 |
+
* @param string $layout (optional) Layout to build
|
353 |
+
* @param string $data Data to pass to layout
|
354 |
+
*/
|
355 |
+
function build($layout = null, $data = null) {
|
356 |
+
$this->util->do_action_ref_array('build_pre', array($this));
|
357 |
+
echo $this->build_layout($layout, $data);
|
358 |
+
$this->util->do_action_ref_array('build_post', array($this));
|
359 |
+
}
|
360 |
+
|
361 |
+
/**
|
362 |
+
* Builds HTML for a field based on its properties
|
363 |
+
* @param string $layout (optional) Name of layout to build
|
364 |
+
* @param array $data Additional data for current item
|
365 |
+
*/
|
366 |
+
function build_layout($layout = 'form', $data = null) {
|
367 |
+
$out_default = '';
|
368 |
+
// Get base layout
|
369 |
+
$out = $this->get_layout($layout);
|
370 |
+
// Only parse valid layouts
|
371 |
+
if ( $this->is_valid_layout($out) ) {
|
372 |
+
// Parse Layout
|
373 |
+
$ph = $this->get_placeholder_defaults();
|
374 |
+
|
375 |
+
// Search layout for placeholders
|
376 |
+
while ( $ph->match = $this->parse_layout($out, $ph->pattern_general) ) {
|
377 |
+
// Iterate through placeholders (tag, id, etc.)
|
378 |
+
foreach ( $ph->match as $tag => $instances ) {
|
379 |
+
// Iterate through instances of current placeholder
|
380 |
+
foreach ( $instances as $instance ) {
|
381 |
+
// Process value based on placeholder name
|
382 |
+
$target_property = $this->util->apply_filters(array('process_placeholder_' . $tag, false), '', $this, $instance, $layout, $data);
|
383 |
+
// Process value using default processors (if necessary)
|
384 |
+
if ( '' == $target_property ) {
|
385 |
+
$target_property = $this->util->apply_filters(array('process_placeholder', false), $target_property, $this, $instance, $layout, $data);
|
386 |
+
}
|
387 |
+
|
388 |
+
// Clear value if value not a string
|
389 |
+
if ( !is_scalar($target_property) ) {
|
390 |
+
$target_property = '';
|
391 |
+
}
|
392 |
+
|
393 |
+
// Replace layout placeholder with retrieved item data
|
394 |
+
$out = str_replace($ph->start . $instance['match'] . $ph->end, $target_property, $out);
|
395 |
+
}
|
396 |
+
}
|
397 |
+
}
|
398 |
+
} else {
|
399 |
+
$out = $out_default;
|
400 |
+
}
|
401 |
+
/* Return generated value */
|
402 |
+
$out = $this->format_final($out);
|
403 |
+
return $out;
|
404 |
+
}
|
405 |
+
}
|
includes/class.fields.php
CHANGED
@@ -1,2182 +1,4 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Fields - Base class
|
5 |
-
* Core properties/methods for fields
|
6 |
-
* @package Simple Lightbox
|
7 |
-
* @subpackage Fields
|
8 |
-
* @author Archetyped
|
9 |
-
*/
|
10 |
-
class SLB_Field_Base extends SLB_Base {
|
11 |
-
/*-** Config **-*/
|
12 |
-
protected $mode = 'object';
|
13 |
-
protected $shared = false;
|
14 |
-
|
15 |
-
/*-** Properties **-*/
|
16 |
-
|
17 |
-
/**
|
18 |
-
* @var string Unique name
|
19 |
-
*/
|
20 |
-
var $id = '';
|
21 |
-
|
22 |
-
/**
|
23 |
-
* ID formatting options
|
24 |
-
* Merged with defaults during initialization
|
25 |
-
* @see $id_formats_default
|
26 |
-
* @var array
|
27 |
-
*/
|
28 |
-
var $id_formats = null;
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Default ID Formatting options
|
32 |
-
* Structure:
|
33 |
-
* > Key (string): Format name
|
34 |
-
* > Val (array): Options
|
35 |
-
* @var array
|
36 |
-
*/
|
37 |
-
var $id_formats_default = array(
|
38 |
-
'attr_id' => array(
|
39 |
-
'wrap' => array('open' => '_', 'segment_open' => '_'),
|
40 |
-
'prefix' => array('get_container', 'get_id', 'add_prefix'),
|
41 |
-
'recursive' => true
|
42 |
-
),
|
43 |
-
'attr_name' => array(
|
44 |
-
'wrap' => array('open' => '[', 'close' => ']', 'segment_open' => '[', 'segment_close' => ']'),
|
45 |
-
'recursive' => true,
|
46 |
-
'prefix' => array('get_container', 'get_id', 'add_prefix')
|
47 |
-
)
|
48 |
-
);
|
49 |
-
|
50 |
-
/**
|
51 |
-
* Special characters/phrases
|
52 |
-
* Used for preserving special characters during formatting
|
53 |
-
* Merged with $special_chars_default
|
54 |
-
* Array Structure
|
55 |
-
* > Key: Special character/phrase
|
56 |
-
* > Value: Placeholder for special character
|
57 |
-
* @var array
|
58 |
-
*/
|
59 |
-
var $special_chars = null;
|
60 |
-
|
61 |
-
var $special_chars_default = array(
|
62 |
-
'{' => '%SQB_L%',
|
63 |
-
'}' => '%SQB_R%',
|
64 |
-
);
|
65 |
-
|
66 |
-
/**
|
67 |
-
* Reference to parent object that current instance inherits from
|
68 |
-
* @var object
|
69 |
-
*/
|
70 |
-
var $parent = null;
|
71 |
-
|
72 |
-
/**
|
73 |
-
* Title
|
74 |
-
* @var string
|
75 |
-
*/
|
76 |
-
var $title = '';
|
77 |
-
|
78 |
-
/**
|
79 |
-
* @var string Short description
|
80 |
-
*/
|
81 |
-
var $description = '';
|
82 |
-
|
83 |
-
/**
|
84 |
-
* @var array Object Properties
|
85 |
-
*/
|
86 |
-
var $properties = array();
|
87 |
-
|
88 |
-
/**
|
89 |
-
* Initialization properties
|
90 |
-
* @var array
|
91 |
-
*/
|
92 |
-
protected $properties_init = null;
|
93 |
-
|
94 |
-
/**
|
95 |
-
* Structure: Property names stored as keys in group
|
96 |
-
* Root
|
97 |
-
* -> Group Name
|
98 |
-
* -> Property Name => Null
|
99 |
-
* Reason: Faster searching over large arrays
|
100 |
-
* @var array Groupings of Properties
|
101 |
-
*/
|
102 |
-
var $property_groups = array();
|
103 |
-
|
104 |
-
/**
|
105 |
-
* Keys to filter out of properties array before setting properties
|
106 |
-
* @var array
|
107 |
-
*/
|
108 |
-
var $property_filter = array('group');
|
109 |
-
|
110 |
-
/**
|
111 |
-
* Define order of properties
|
112 |
-
* Useful when processing order is important (e.g. one property depends on another)
|
113 |
-
* @var array
|
114 |
-
*/
|
115 |
-
var $property_priority = array();
|
116 |
-
|
117 |
-
/**
|
118 |
-
* Data for object
|
119 |
-
* May also contain data for nested objects
|
120 |
-
* @var mixed
|
121 |
-
*/
|
122 |
-
var $data = null;
|
123 |
-
|
124 |
-
/**
|
125 |
-
* Whether data has been fetched or not
|
126 |
-
* @var bool
|
127 |
-
*/
|
128 |
-
var $data_loaded = false;
|
129 |
-
|
130 |
-
/**
|
131 |
-
* @var array Script resources to include for object
|
132 |
-
*/
|
133 |
-
var $scripts = array();
|
134 |
-
|
135 |
-
/**
|
136 |
-
* @var array CSS style resources to include for object
|
137 |
-
*/
|
138 |
-
var $styles = array();
|
139 |
-
|
140 |
-
/**
|
141 |
-
* Hooks (Filters/Actions) for object
|
142 |
-
* @var array
|
143 |
-
*/
|
144 |
-
var $hooks = array();
|
145 |
-
|
146 |
-
/**
|
147 |
-
* Mapping of child properties to parent members
|
148 |
-
* Allows more flexibility when creating new instances of child objects using property arrays
|
149 |
-
* Associative array structure:
|
150 |
-
* > Key: Child property to map FROM
|
151 |
-
* > Val: Parent property to map TO
|
152 |
-
* @var array
|
153 |
-
*/
|
154 |
-
var $map = null;
|
155 |
-
|
156 |
-
/**
|
157 |
-
* Options used when building collection (callbacks, etc.)
|
158 |
-
* Associative array
|
159 |
-
* > Key: Option name
|
160 |
-
* > Value: Option value
|
161 |
-
* @var array
|
162 |
-
*/
|
163 |
-
var $build_vars = array();
|
164 |
-
|
165 |
-
var $build_vars_default = array();
|
166 |
-
|
167 |
-
/**
|
168 |
-
* Constructor
|
169 |
-
*/
|
170 |
-
function __construct($id = '', $properties = null) {
|
171 |
-
parent::__construct();
|
172 |
-
//Normalize Properties
|
173 |
-
$args = func_get_args();
|
174 |
-
$defaults = $this->integrate_id($id);
|
175 |
-
$properties = $this->make_properties($args, $defaults);
|
176 |
-
//Save init properties
|
177 |
-
$this->properties_init = $properties;
|
178 |
-
//Set Properties
|
179 |
-
$this->set_properties($properties);
|
180 |
-
}
|
181 |
-
|
182 |
-
/* Getters/Setters */
|
183 |
-
|
184 |
-
/**
|
185 |
-
* Checks if the specified path exists in the object
|
186 |
-
* @param array $path Path to check for
|
187 |
-
* @return bool TRUE if path exists in object, FALSE otherwise
|
188 |
-
*/
|
189 |
-
function path_isset($path = '') {
|
190 |
-
//Stop execution if no path is supplied
|
191 |
-
if ( empty($path) )
|
192 |
-
return false;
|
193 |
-
$args = func_get_args();
|
194 |
-
$path = $this->util->build_path($args);
|
195 |
-
$item =& $this;
|
196 |
-
//Iterate over path and check if each level exists before moving on to the next
|
197 |
-
for ($x = 0; $x < count($path); $x++) {
|
198 |
-
if ( $this->util->property_exists($item, $path[$x]) ) {
|
199 |
-
//Set $item as reference to next level in path for next iteration
|
200 |
-
$item =& $this->util->get_property($item, $path[$x]);
|
201 |
-
//$item =& $item[ $path[$x] ];
|
202 |
-
} else {
|
203 |
-
return false;
|
204 |
-
}
|
205 |
-
}
|
206 |
-
return true;
|
207 |
-
}
|
208 |
-
|
209 |
-
/**
|
210 |
-
* Retrieves a value from object using a specified path
|
211 |
-
* Checks to make sure path exists in object before retrieving value
|
212 |
-
* @param array $path Path to retrieve value from. Each item in array is a deeper dimension
|
213 |
-
* @return mixed Value at specified path
|
214 |
-
*/
|
215 |
-
function &get_path_value($path = '') {
|
216 |
-
$ret = '';
|
217 |
-
$path = $this->util->build_path(func_get_args());
|
218 |
-
if ( $this->path_isset($path) ) {
|
219 |
-
$ret =& $this;
|
220 |
-
for ($x = 0; $x < count($path); $x++) {
|
221 |
-
if ( 0 == $x )
|
222 |
-
$ret =& $ret->{ $path[$x] };
|
223 |
-
else
|
224 |
-
$ret =& $ret[ $path[$x] ];
|
225 |
-
}
|
226 |
-
}
|
227 |
-
return $ret;
|
228 |
-
}
|
229 |
-
|
230 |
-
/**
|
231 |
-
* Search for specified member value in field type ancestors
|
232 |
-
* @param string $member Name of object member to search (e.g. properties, layout, etc.)
|
233 |
-
* @param string $name Value to retrieve from member
|
234 |
-
* @return mixed Member value if found (Default: empty string)
|
235 |
-
*/
|
236 |
-
function get_parent_value($member, $name = '', $default = '') {
|
237 |
-
$parent =& $this->get_parent();
|
238 |
-
return $this->get_object_value($parent, $member, $name, $default, 'parent');
|
239 |
-
}
|
240 |
-
|
241 |
-
/**
|
242 |
-
* Retrieves specified member value
|
243 |
-
* Handles inherited values
|
244 |
-
* Merging corresponding parents if value is an array (e.g. for property groups)
|
245 |
-
* @param string|array $member Member to search. May also contain a path to the desired member
|
246 |
-
* @param string $name Value to retrieve from member
|
247 |
-
* @param mixed $default Default value if no value found (Default: empty string)
|
248 |
-
* @param string $dir Direction to move through hierarchy to find value
|
249 |
-
* Possible Values:
|
250 |
-
* parent (default) - Search through field parents
|
251 |
-
* current - Do not search through connected objects
|
252 |
-
* container - Search through field containers
|
253 |
-
* caller - Search through field callers
|
254 |
-
* @return mixed Specified member value
|
255 |
-
* @todo Return reference
|
256 |
-
*/
|
257 |
-
function &get_member_value($member, $name = '', $default = '', $dir = 'parent') {
|
258 |
-
//Check if path to member is supplied
|
259 |
-
$path = array();
|
260 |
-
if ( is_array($member) && isset($member['tag']) ) {
|
261 |
-
if ( isset($member['attributes']['ref_base']) ) {
|
262 |
-
if ( 'root' != $member['attributes']['ref_base'] )
|
263 |
-
$path[] = $member['attributes']['ref_base'];
|
264 |
-
} else {
|
265 |
-
$path[] = 'properties';
|
266 |
-
}
|
267 |
-
|
268 |
-
$path[] = $member['tag'];
|
269 |
-
} else {
|
270 |
-
$path = $member;
|
271 |
-
}
|
272 |
-
|
273 |
-
$path = $this->util->build_path($path, $name);
|
274 |
-
//Set defaults and prepare data
|
275 |
-
$val = $default;
|
276 |
-
$inherit = false;
|
277 |
-
$inherit_tag = '{inherit}';
|
278 |
-
|
279 |
-
/* Determine whether the value must be retrieved from a parent/container object
|
280 |
-
* Conditions:
|
281 |
-
* > Path does not exist in current field
|
282 |
-
* > Path exists and is not an object, but at least one of the following is true:
|
283 |
-
* > Value at path is an array (e.g. properties, elements, etc. array)
|
284 |
-
* > Parent/container values should be merged with retrieved array
|
285 |
-
* > Value at path is a string that inherits from another field
|
286 |
-
* > Value from other field will be retrieved and will replace inheritance placeholder in retrieved value
|
287 |
-
*/
|
288 |
-
|
289 |
-
$deeper = false;
|
290 |
-
|
291 |
-
if ( !$this->path_isset($path) )
|
292 |
-
$deeper = true;
|
293 |
-
else {
|
294 |
-
$val = $this->get_path_value($path);
|
295 |
-
if ( !is_object($val) && ( is_array($val) || ($inherit = strpos($val, $inherit_tag)) !== false ) )
|
296 |
-
$deeper = true;
|
297 |
-
else
|
298 |
-
$deeper = false;
|
299 |
-
}
|
300 |
-
if ( $deeper && 'current' != $dir ) {
|
301 |
-
$ex_val = '';
|
302 |
-
//Get Parent value (recursive)
|
303 |
-
if ( 'parent' == $dir )
|
304 |
-
$ex_val = $this->get_parent_value($member, $name, $default);
|
305 |
-
elseif ( method_exists($this, 'get_container_value') )
|
306 |
-
$ex_val = $this->get_container_value($member, $name, $default);
|
307 |
-
//Handle inheritance
|
308 |
-
if ( is_array($val) ) {
|
309 |
-
//Combine Arrays
|
310 |
-
if ( is_array($ex_val) )
|
311 |
-
$val = array_merge($ex_val, $val);
|
312 |
-
} elseif ( $inherit !== false ) {
|
313 |
-
//Replace placeholder with inherited string
|
314 |
-
$val = str_replace($inherit_tag, $ex_val, $val);
|
315 |
-
} else {
|
316 |
-
//Default: Set parent value as value
|
317 |
-
$val = $ex_val;
|
318 |
-
}
|
319 |
-
}
|
320 |
-
|
321 |
-
return $val;
|
322 |
-
}
|
323 |
-
|
324 |
-
/**
|
325 |
-
* Search for specified member value in an object
|
326 |
-
* @param object $object Reference to object to retrieve value from
|
327 |
-
* @param string $member Name of object member to search (e.g. properties, layout, etc.)
|
328 |
-
* @param string $name (optional) Value to retrieve from member
|
329 |
-
* @param mixed $default (optional) Default value to use if no value found (Default: empty string)
|
330 |
-
* @param string $dir Direction to move through hierarchy to find value @see SLB_Field_Type::get_member_value() for possible values
|
331 |
-
* @return mixed Member value if found (Default: $default)
|
332 |
-
*/
|
333 |
-
function get_object_value(&$object, $member, $name = '', $default = '', $dir = 'parent') {
|
334 |
-
$ret = $default;
|
335 |
-
if ( is_object($object) && method_exists($object, 'get_member_value') )
|
336 |
-
$ret = $object->get_member_value($member, $name, $default, $dir);
|
337 |
-
return $ret;
|
338 |
-
}
|
339 |
-
|
340 |
-
/**
|
341 |
-
* Set item ID
|
342 |
-
* @param string $id Unique item ID
|
343 |
-
*/
|
344 |
-
function set_id($id) {
|
345 |
-
if ( empty($id) || !is_string($id) )
|
346 |
-
return false;
|
347 |
-
$this->id = trim($id);
|
348 |
-
}
|
349 |
-
|
350 |
-
/**
|
351 |
-
* Retrieves field ID
|
352 |
-
* @param array|string $options (optional) Options or ID of format to use
|
353 |
-
* @return string item ID
|
354 |
-
*/
|
355 |
-
function get_id($options = array()) {
|
356 |
-
$item_id = trim($this->id);
|
357 |
-
$formats = $this->get_id_formats();
|
358 |
-
|
359 |
-
//Setup options
|
360 |
-
$wrap_default = array('open' => '', 'close' => '', 'segment_open' => '', 'segment_close' => '');
|
361 |
-
|
362 |
-
$options_default = array(
|
363 |
-
'format' => null,
|
364 |
-
'wrap' => array(),
|
365 |
-
'segments_pre' => null,
|
366 |
-
'prefix' => '',
|
367 |
-
'recursive' => false
|
368 |
-
);
|
369 |
-
|
370 |
-
//Load options based on format
|
371 |
-
if ( !is_array($options) )
|
372 |
-
$options = array('format' => $options);
|
373 |
-
if ( isset($options['format']) && is_string($options['format']) && isset($formats[$options['format']]) )
|
374 |
-
$options_default = wp_parse_args($formats[$options['format']], $options_default);
|
375 |
-
else
|
376 |
-
unset($options['format']);
|
377 |
-
$options = wp_parse_args($options, $options_default);
|
378 |
-
//Import options into function
|
379 |
-
extract($options);
|
380 |
-
|
381 |
-
//Validate options
|
382 |
-
$wrap = wp_parse_args($wrap, $wrap_default);
|
383 |
-
|
384 |
-
if ( !is_array($segments_pre) )
|
385 |
-
$segments_pre = array($segments_pre);
|
386 |
-
$segments_pre = array_reverse($segments_pre);
|
387 |
-
|
388 |
-
//Format ID based on options
|
389 |
-
$item_id = array($item_id);
|
390 |
-
|
391 |
-
//Add parent objects to ID
|
392 |
-
if ( !!$recursive ) {
|
393 |
-
//Create array of ID components
|
394 |
-
$m = 'get_caller';
|
395 |
-
$c = ( method_exists($this, $m) ) ? $this->{$m}() : null;
|
396 |
-
while ( !!$c ) {
|
397 |
-
//Add ID of current caller to array
|
398 |
-
if ( method_exists($c, 'get_id') && ( $itemp = $c->get_id() ) && !empty($itemp) )
|
399 |
-
$item_id = $itemp;
|
400 |
-
//Get parent object
|
401 |
-
$c = ( method_exists($c, $m) ) ? $c->{$m}() : null;
|
402 |
-
$itemp = '';
|
403 |
-
}
|
404 |
-
unset($c);
|
405 |
-
}
|
406 |
-
|
407 |
-
//Additional segments (Pre)
|
408 |
-
foreach ( $segments_pre as $seg ) {
|
409 |
-
if ( is_null($seg) )
|
410 |
-
continue;
|
411 |
-
if ( is_object($seg) )
|
412 |
-
$seg = (array)$seg;
|
413 |
-
if ( is_array($seg) )
|
414 |
-
$item_id = array_merge($item_id, array_reverse($seg));
|
415 |
-
elseif ( '' != strval($seg) )
|
416 |
-
$item_id[] = strval($seg);
|
417 |
-
}
|
418 |
-
|
419 |
-
//Prefix
|
420 |
-
if ( is_array($prefix) ) {
|
421 |
-
//Array is sequence of instance methods to call on object
|
422 |
-
//Last array member can be an array of parameters to pass to methods
|
423 |
-
$count = count($prefix);
|
424 |
-
$args = ( $count > 1 && is_array($prefix[$count - 1]) ) ? array_pop($prefix) : array();
|
425 |
-
$p = $this;
|
426 |
-
$val = '';
|
427 |
-
//Iterate through methods
|
428 |
-
foreach ( $prefix as $m ) {
|
429 |
-
if ( !method_exists($p, $m) )
|
430 |
-
continue;
|
431 |
-
//Build callback
|
432 |
-
$m = $this->util->m($p, $m);
|
433 |
-
//Call callback
|
434 |
-
$val = call_user_func_array($m, $args);
|
435 |
-
//Returned value may be an instance object
|
436 |
-
if ( is_object($val) )
|
437 |
-
$p = $val; //Use returned object in next round
|
438 |
-
else
|
439 |
-
array_unshift($args, $val); //Pass returned value as parameter to next method on using current object
|
440 |
-
}
|
441 |
-
$prefix = $val;
|
442 |
-
unset($p, $val);
|
443 |
-
}
|
444 |
-
if ( is_numeric($prefix) )
|
445 |
-
$prefix = strval($prefix);
|
446 |
-
if ( empty($prefix) || !is_string($prefix) )
|
447 |
-
$prefix = '';
|
448 |
-
|
449 |
-
//Convert array to string
|
450 |
-
$item_id = $prefix . $wrap['open'] . implode($wrap['segment_close'] . $wrap['segment_open'], array_reverse($item_id)) . $wrap['close'];
|
451 |
-
return $item_id;
|
452 |
-
}
|
453 |
-
|
454 |
-
/**
|
455 |
-
* Retrieve ID formatting options for class
|
456 |
-
* Format options arrays are merged together and saved to $id_formats
|
457 |
-
* @uses $id_formats
|
458 |
-
* @uses $id_formats_default
|
459 |
-
* @return array ID Formatting options
|
460 |
-
*/
|
461 |
-
function &get_id_formats() {
|
462 |
-
if ( is_null($this->id_formats) ) {
|
463 |
-
$this->id_formats = wp_parse_args($this->id_formats, $this->id_formats_default);
|
464 |
-
}
|
465 |
-
return $this->id_formats;
|
466 |
-
}
|
467 |
-
|
468 |
-
/**
|
469 |
-
* Retrieve value from data member
|
470 |
-
* @param string $context Context to format data for
|
471 |
-
* @param bool $top (optional) Whether to traverse through the field hierarchy to get data for field (Default: TRUE)
|
472 |
-
* @return mixed Value at specified path
|
473 |
-
*/
|
474 |
-
function get_data($context = '', $top = true) {
|
475 |
-
$opt_d = array('context' => '', 'top' => true);
|
476 |
-
$args = func_get_args();
|
477 |
-
$a = false;
|
478 |
-
if ( count($args) == 1 && is_array($args[0]) && !empty($args[0]) ) {
|
479 |
-
$a = true;
|
480 |
-
$args = wp_parse_args($args[0], $opt_d);
|
481 |
-
extract($args);
|
482 |
-
}
|
483 |
-
|
484 |
-
if ( is_string($top) ) {
|
485 |
-
if ( 'false' == $top )
|
486 |
-
$top = false;
|
487 |
-
elseif ( 'true' == $top )
|
488 |
-
$top = true;
|
489 |
-
elseif ( is_numeric($top) )
|
490 |
-
$top = intval($top);
|
491 |
-
}
|
492 |
-
$top = !!$top;
|
493 |
-
$obj =& $this;
|
494 |
-
$obj_path = array(&$this);
|
495 |
-
$path = array();
|
496 |
-
if ( $top ) {
|
497 |
-
//Iterate through hiearchy to get top-most object
|
498 |
-
while ( !empty($obj) ) {
|
499 |
-
$new = null;
|
500 |
-
//Try to get caller first
|
501 |
-
if ( method_exists($obj, 'get_caller') ) {
|
502 |
-
$checked = true;
|
503 |
-
$new =& $obj->get_caller();
|
504 |
-
}
|
505 |
-
//Try to get container if no caller found
|
506 |
-
if ( empty($new) && method_exists($obj, 'get_container') ) {
|
507 |
-
$checked = true;
|
508 |
-
$new =& $obj->get_container();
|
509 |
-
//Load data
|
510 |
-
if ( method_exists($new, 'load_data') ) {
|
511 |
-
$new->load_data();
|
512 |
-
}
|
513 |
-
}
|
514 |
-
|
515 |
-
$obj =& $new;
|
516 |
-
unset($new);
|
517 |
-
//Stop iteration
|
518 |
-
if ( !empty($obj) ) {
|
519 |
-
//Add object to path if it is valid
|
520 |
-
$obj_path[] =& $obj;
|
521 |
-
}
|
522 |
-
}
|
523 |
-
unset($obj);
|
524 |
-
}
|
525 |
-
|
526 |
-
//Check each object (starting with top-most) for matching data for current field
|
527 |
-
|
528 |
-
//Reverse array
|
529 |
-
$obj_path = array_reverse($obj_path);
|
530 |
-
//Build path for data location
|
531 |
-
foreach ( $obj_path as $obj ) {
|
532 |
-
if ( method_exists($obj, 'get_id') )
|
533 |
-
$path[] = $obj->get_id();
|
534 |
-
}
|
535 |
-
//Iterate through objects
|
536 |
-
while ( !empty($obj_path) ) {
|
537 |
-
//Get next object
|
538 |
-
$obj =& array_shift($obj_path);
|
539 |
-
//Shorten path
|
540 |
-
array_shift($path);
|
541 |
-
//Check for value in object and stop iteration if matching data found
|
542 |
-
$val = $this->get_object_value($obj, 'data', $path, null, 'current');
|
543 |
-
if ( !is_null($val) ) {
|
544 |
-
break;
|
545 |
-
}
|
546 |
-
}
|
547 |
-
return $this->format($val, $context);
|
548 |
-
}
|
549 |
-
|
550 |
-
/**
|
551 |
-
* Sets value in data member
|
552 |
-
* Sets value to data member itself by default
|
553 |
-
* @param mixed $value Value to set
|
554 |
-
* @param string|array $name Name of value to set (Can also be path to value)
|
555 |
-
*/
|
556 |
-
function set_data($value, $name = '') {
|
557 |
-
$ref =& $this->get_path_value('data', $name);
|
558 |
-
$ref = $value;
|
559 |
-
}
|
560 |
-
|
561 |
-
/**
|
562 |
-
* Sets parent object of current instance
|
563 |
-
* Parent objects must be the same object type as current instance
|
564 |
-
* @uses SLB to get field type definition
|
565 |
-
* @uses SLB_Fields::has() to check if field type exists
|
566 |
-
* @uses SLB_Fields::get() to retrieve field type object reference
|
567 |
-
* @param string|object $parent Parent ID or reference
|
568 |
-
*/
|
569 |
-
function set_parent($parent = null) {
|
570 |
-
//Stop processing if parent empty
|
571 |
-
if ( empty($parent) && !is_string($this->parent) )
|
572 |
-
return false;
|
573 |
-
//Parent passed as object reference wrapped in array
|
574 |
-
if ( is_array($parent) && isset($parent[0]) && is_object($parent[0]) )
|
575 |
-
$parent =& $parent[0];
|
576 |
-
|
577 |
-
//No parent set but parent ID (previously) set in object
|
578 |
-
if ( empty($parent) && is_string($this->parent) )
|
579 |
-
$parent = $this->parent;
|
580 |
-
|
581 |
-
//Retrieve reference object if ID was supplied
|
582 |
-
if ( is_string($parent) ) {
|
583 |
-
$parent = trim($parent);
|
584 |
-
//Get parent object reference
|
585 |
-
/**
|
586 |
-
* @var SLB
|
587 |
-
*/
|
588 |
-
$b =& $this->get_base();
|
589 |
-
if ( $b && isset($b->fields) && $b->fields->has($parent) ) {
|
590 |
-
$parent =& $b->fields->get($parent);
|
591 |
-
}
|
592 |
-
}
|
593 |
-
|
594 |
-
//Set parent value on object
|
595 |
-
if ( is_string($parent) || is_object($parent) )
|
596 |
-
$this->parent =& $parent;
|
597 |
-
}
|
598 |
-
|
599 |
-
/**
|
600 |
-
* Retrieve field type parent
|
601 |
-
* @return SLB_Field_Type Reference to parent field
|
602 |
-
*/
|
603 |
-
function &get_parent() {
|
604 |
-
return $this->parent;
|
605 |
-
}
|
606 |
-
|
607 |
-
/**
|
608 |
-
* Set object title
|
609 |
-
* @param string $title Title for object
|
610 |
-
* @param string $plural Plural form of title
|
611 |
-
*/
|
612 |
-
function set_title($title = '') {
|
613 |
-
if ( is_scalar($title) )
|
614 |
-
$this->title = strip_tags(trim($title));
|
615 |
-
}
|
616 |
-
|
617 |
-
/**
|
618 |
-
* Retrieve object title
|
619 |
-
*/
|
620 |
-
function get_title() {
|
621 |
-
return $this->get_member_value('title', '','', 'current');
|
622 |
-
}
|
623 |
-
|
624 |
-
/**
|
625 |
-
* Set object description
|
626 |
-
* @param string $description Description for object
|
627 |
-
*/
|
628 |
-
function set_description($description = '') {
|
629 |
-
$this->description = strip_tags(trim($description));
|
630 |
-
}
|
631 |
-
|
632 |
-
/**
|
633 |
-
* Retrieve object description
|
634 |
-
* @return string Object description
|
635 |
-
*/
|
636 |
-
function get_description() {
|
637 |
-
$dir = 'current';
|
638 |
-
return $this->get_member_value('description', '','', $dir);
|
639 |
-
return $desc;
|
640 |
-
}
|
641 |
-
|
642 |
-
/**
|
643 |
-
* Sets multiple properties on field type at once
|
644 |
-
* @param array $properties Properties. Each element is an array containing the arguments to set a new property
|
645 |
-
* @return boolean TRUE if successful, FALSE otherwise
|
646 |
-
*/
|
647 |
-
function set_properties($properties) {
|
648 |
-
if ( !is_array($properties) ) {
|
649 |
-
return false;
|
650 |
-
}
|
651 |
-
//Normalize properties
|
652 |
-
$properties = $this->remap_properties($properties);
|
653 |
-
$properties = $this->sort_properties($properties);
|
654 |
-
//Set Member properties
|
655 |
-
foreach ( $properties as $prop => $val ) {
|
656 |
-
if ( ( $m = 'set_' . $prop ) && method_exists($this, $m) ) {
|
657 |
-
$this->{$m}($val);
|
658 |
-
//Remove member property from array
|
659 |
-
unset($properties[$prop]);
|
660 |
-
}
|
661 |
-
}
|
662 |
-
|
663 |
-
//Filter properties
|
664 |
-
$properties = $this->filter_properties($properties);
|
665 |
-
//Set additional instance properties
|
666 |
-
foreach ( $properties as $name => $val) {
|
667 |
-
$this->set_property($name, $val);
|
668 |
-
}
|
669 |
-
}
|
670 |
-
|
671 |
-
/**
|
672 |
-
* Remap properties based on $map
|
673 |
-
* @uses $map For determine how child properties should map to parent properties
|
674 |
-
* @uses SLB_Utlities::array_remap() to perform array remapping
|
675 |
-
* @param array $properties Associative array of properties
|
676 |
-
* @return array Remapped properties
|
677 |
-
*/
|
678 |
-
function remap_properties($properties) {
|
679 |
-
//Return remapped properties
|
680 |
-
return $this->util->array_remap($properties, $this->map);
|
681 |
-
}
|
682 |
-
|
683 |
-
/**
|
684 |
-
* Sort properties based on priority
|
685 |
-
* @uses this::property_priority
|
686 |
-
* @return array Sorted priorities
|
687 |
-
*/
|
688 |
-
function sort_properties($properties) {
|
689 |
-
//Stop if sorting not necessary
|
690 |
-
if ( empty($properties) || !is_array($properties) || empty($this->property_priority) || !is_array($this->property_priority) )
|
691 |
-
return $properties;
|
692 |
-
$props = array();
|
693 |
-
foreach ( $this->property_priority as $prop ) {
|
694 |
-
if ( !array_key_exists($prop, $properties) )
|
695 |
-
continue;
|
696 |
-
//Add to new array
|
697 |
-
$props[$prop] = $properties[$prop];
|
698 |
-
//Remove from old array
|
699 |
-
unset($properties[$prop]);
|
700 |
-
}
|
701 |
-
//Append any remaining properties
|
702 |
-
$props = array_merge($props, $properties);
|
703 |
-
return $props;
|
704 |
-
}
|
705 |
-
|
706 |
-
/**
|
707 |
-
* Build properties array
|
708 |
-
* @param array $props Instance properties
|
709 |
-
* @param array $signature (optional) Default properties
|
710 |
-
* @return array Normalized properties
|
711 |
-
*/
|
712 |
-
function make_properties($props, $signature = array()) {
|
713 |
-
$p = array();
|
714 |
-
if ( is_array($props) ) {
|
715 |
-
foreach ( $props as $prop ) {
|
716 |
-
if ( is_array($prop) ) {
|
717 |
-
$p = array_merge($prop, $p);
|
718 |
-
}
|
719 |
-
}
|
720 |
-
}
|
721 |
-
$props = $p;
|
722 |
-
if ( is_array($signature) ) {
|
723 |
-
$props = array_merge($signature, $props);
|
724 |
-
}
|
725 |
-
return $props;
|
726 |
-
}
|
727 |
-
|
728 |
-
function validate_id($id) {
|
729 |
-
return ( is_scalar($id) && !empty($id) ) ? true : false;
|
730 |
-
}
|
731 |
-
|
732 |
-
function integrate_id($id) {
|
733 |
-
return ( $this->validate_id($id) ) ? array('id' => $id) : array();
|
734 |
-
}
|
735 |
-
|
736 |
-
/**
|
737 |
-
* Filter property members
|
738 |
-
* @uses $property_filter to remove define members to remove from $properties
|
739 |
-
* @param array $props Properties
|
740 |
-
* @return array Filtered properties
|
741 |
-
*/
|
742 |
-
function filter_properties($props = array()) {
|
743 |
-
return $this->util->array_filter_keys($props, $this->property_filter);
|
744 |
-
}
|
745 |
-
|
746 |
-
/**
|
747 |
-
* Add/Set a property on the field definition
|
748 |
-
* @param string $name Name of property
|
749 |
-
* @param mixed $value Default value for property
|
750 |
-
* @param string|array $group Group(s) property belongs to
|
751 |
-
* @return boolean TRUE if property is successfully added to field type, FALSE otherwise
|
752 |
-
*/
|
753 |
-
function set_property($name, $value = '', $group = null) {
|
754 |
-
//Do not add if property name is not a string
|
755 |
-
if ( !is_string($name) )
|
756 |
-
return false;
|
757 |
-
//Create property array
|
758 |
-
$prop_arr = array();
|
759 |
-
$prop_arr['value'] = $value;
|
760 |
-
//Add to properties array
|
761 |
-
$this->properties[$name] = $value;
|
762 |
-
//Add property to specified groups
|
763 |
-
if ( !empty($group) ) {
|
764 |
-
$this->set_group_property($group, $name);
|
765 |
-
}
|
766 |
-
return true;
|
767 |
-
}
|
768 |
-
|
769 |
-
/**
|
770 |
-
* Retreives property from field type
|
771 |
-
* @param string $name Name of property to retrieve
|
772 |
-
* @return mixed Specified Property if exists (Default: Empty string)
|
773 |
-
*/
|
774 |
-
function get_property($name) {
|
775 |
-
$val = $this->get_member_value('properties', $name);
|
776 |
-
return $val;
|
777 |
-
}
|
778 |
-
|
779 |
-
/**
|
780 |
-
* Removes a property from item
|
781 |
-
* @param string $name Property ID
|
782 |
-
*/
|
783 |
-
function remove_property($name) {
|
784 |
-
//Remove property
|
785 |
-
if ( isset($this->properties[$name]) )
|
786 |
-
unset($this->properties[$name]);
|
787 |
-
//Remove from group
|
788 |
-
foreach ( array_keys($this->property_groups) as $g ) {
|
789 |
-
if ( isset($this->property_groups[$g][$name]) ) {
|
790 |
-
unset($this->property_groups[$g][$name]);
|
791 |
-
break;
|
792 |
-
}
|
793 |
-
}
|
794 |
-
}
|
795 |
-
|
796 |
-
/**
|
797 |
-
* Adds Specified Property to a Group
|
798 |
-
* @param string|array $group Group(s) to add property to
|
799 |
-
* @param string $property Property to add to group
|
800 |
-
*/
|
801 |
-
function set_group_property($group, $property) {
|
802 |
-
if ( is_string($group) && isset($this->property_groups[$group][$property]) )
|
803 |
-
return;
|
804 |
-
if ( !is_array($group) ) {
|
805 |
-
$group = array($group);
|
806 |
-
}
|
807 |
-
|
808 |
-
foreach ($group as $g) {
|
809 |
-
$g = trim($g);
|
810 |
-
//Initialize group if it doesn't already exist
|
811 |
-
if ( !isset($this->property_groups[$g]) )
|
812 |
-
$this->property_groups[$g] = array();
|
813 |
-
|
814 |
-
//Add property to group
|
815 |
-
$this->property_groups[$g][$property] = null;
|
816 |
-
}
|
817 |
-
}
|
818 |
-
|
819 |
-
/**
|
820 |
-
* Retrieve property group
|
821 |
-
* @param string $group Group to retrieve
|
822 |
-
* @return array Array of properties in specified group
|
823 |
-
*/
|
824 |
-
function get_group($group) {
|
825 |
-
return $this->get_member_value('property_groups', $group, array());
|
826 |
-
}
|
827 |
-
|
828 |
-
/**
|
829 |
-
* Save field data
|
830 |
-
* Child classes will define their own
|
831 |
-
* functionality for this method
|
832 |
-
* @return bool TRUE if save was successful (FALSE otherwise)
|
833 |
-
*/
|
834 |
-
function save() {
|
835 |
-
return true;
|
836 |
-
}
|
837 |
-
|
838 |
-
/*-** Hooks **-*/
|
839 |
-
|
840 |
-
/**
|
841 |
-
* Retrieve hooks added to object
|
842 |
-
* @return array Hooks
|
843 |
-
*/
|
844 |
-
function get_hooks() {
|
845 |
-
return $this->get_member_value('hooks', '', array());
|
846 |
-
}
|
847 |
-
|
848 |
-
/**
|
849 |
-
* Add hook for object
|
850 |
-
* @see add_filter() for parameter defaults
|
851 |
-
* @param $tag
|
852 |
-
* @param $function_to_add
|
853 |
-
* @param $priority
|
854 |
-
* @param $accepted_args
|
855 |
-
*/
|
856 |
-
function add_hook($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
|
857 |
-
//Create new array for tag (if not already set)
|
858 |
-
if ( !isset($this->hooks[$tag]) )
|
859 |
-
$this->hooks[$tag] = array();
|
860 |
-
//Build Unique ID
|
861 |
-
if ( is_string($function_to_add) )
|
862 |
-
$id = $function_to_add;
|
863 |
-
elseif ( is_array($function_to_add) && !empty($function_to_add) )
|
864 |
-
$id = strval($function_to_add[count($function_to_add) - 1]);
|
865 |
-
else
|
866 |
-
$id = 'function_' . ( count($this->hooks[$tag]) + 1 );
|
867 |
-
//Add hook
|
868 |
-
$this->hooks[$tag][$id] = func_get_args();
|
869 |
-
}
|
870 |
-
|
871 |
-
/**
|
872 |
-
* Convenience method for adding an action for object
|
873 |
-
* @see add_filter() for parameter defaults
|
874 |
-
* @param $tag
|
875 |
-
* @param $function_to_add
|
876 |
-
* @param $priority
|
877 |
-
* @param $accepted_args
|
878 |
-
*/
|
879 |
-
function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
|
880 |
-
$this->add_hook($tag, $function_to_add, $priority, $accepted_args);
|
881 |
-
}
|
882 |
-
|
883 |
-
/**
|
884 |
-
* Convenience method for adding a filter for object
|
885 |
-
* @see add_filter() for parameter defaults
|
886 |
-
* @param $tag
|
887 |
-
* @param $function_to_add
|
888 |
-
* @param $priority
|
889 |
-
* @param $accepted_args
|
890 |
-
*/
|
891 |
-
function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
|
892 |
-
$this->add_hook($tag, $function_to_add, $priority, $accepted_args);
|
893 |
-
}
|
894 |
-
|
895 |
-
/*-** Dependencies **-*/
|
896 |
-
|
897 |
-
/**
|
898 |
-
* Adds dependency to object
|
899 |
-
* @param string $type Type of dependency to add (script, style)
|
900 |
-
* @param array|string $context When dependency will be added (@see SLB_Utilities::get_action() for possible contexts)
|
901 |
-
* @see wp_enqueue_script for the following of the parameters
|
902 |
-
* @param $handle
|
903 |
-
* @param $src
|
904 |
-
* @param $deps
|
905 |
-
* @param $ver
|
906 |
-
* @param $ex
|
907 |
-
*/
|
908 |
-
function add_dependency($type, $context, $handle, $src = false, $deps = array(), $ver = false, $ex = false) {
|
909 |
-
$args = func_get_args();
|
910 |
-
//Remove type/context from arguments
|
911 |
-
$args = array_slice($args, 2);
|
912 |
-
|
913 |
-
//Set context
|
914 |
-
if ( !is_array($context) ) {
|
915 |
-
//Wrap single contexts in an array
|
916 |
-
if ( is_string($context) )
|
917 |
-
$context = array($context);
|
918 |
-
else
|
919 |
-
$context = array();
|
920 |
-
}
|
921 |
-
//Add file to instance property
|
922 |
-
if ( isset($this->{$type}) && is_array($this->{$type}) )
|
923 |
-
$this->{$type}[$handle] = array('context' => $context, 'params' => $args);
|
924 |
-
}
|
925 |
-
|
926 |
-
/**
|
927 |
-
* Add script to object to be added in specified contexts
|
928 |
-
* @param array|string $context Array of contexts to add script to page
|
929 |
-
* @see wp_enqueue_script for the following of the parameters
|
930 |
-
* @param $handle
|
931 |
-
* @param $src
|
932 |
-
* @param $deps
|
933 |
-
* @param $ver
|
934 |
-
* @param $in_footer
|
935 |
-
*/
|
936 |
-
function add_script( $context, $handle, $src = false, $deps = array(), $ver = false, $in_footer = false ) {
|
937 |
-
$args = func_get_args();
|
938 |
-
//Add file type to front of arguments array
|
939 |
-
array_unshift($args, 'scripts');
|
940 |
-
call_user_func_array($this->m('add_dependency'), $args);
|
941 |
-
}
|
942 |
-
|
943 |
-
/**
|
944 |
-
* Retrieve script dependencies for object
|
945 |
-
* @return array Script dependencies
|
946 |
-
*/
|
947 |
-
function get_scripts() {
|
948 |
-
return $this->get_member_value('scripts', '', array());
|
949 |
-
}
|
950 |
-
|
951 |
-
/**
|
952 |
-
* Add style to object to be added in specified contexts
|
953 |
-
* @param array|string $context Array of contexts to add style to page
|
954 |
-
* @see wp_enqueue_style for the following of the parameters
|
955 |
-
* @param $handle
|
956 |
-
* @param $src
|
957 |
-
* @param $deps
|
958 |
-
* @param $ver
|
959 |
-
* @param $in_footer
|
960 |
-
*/
|
961 |
-
function add_style( $handle, $src = false, $deps = array(), $ver = false, $media = false ) {
|
962 |
-
$args = func_get_args();
|
963 |
-
array_unshift($args, 'styles');
|
964 |
-
call_user_func_array($this->m('add_dependency'), $args);
|
965 |
-
}
|
966 |
-
|
967 |
-
/**
|
968 |
-
* Retrieve Style dependencies for object
|
969 |
-
* @return array Style dependencies
|
970 |
-
*/
|
971 |
-
function get_styles() {
|
972 |
-
return $this->get_member_value('styles', '', array());
|
973 |
-
}
|
974 |
-
|
975 |
-
/* Helpers */
|
976 |
-
|
977 |
-
/**
|
978 |
-
* Format value based on specified context
|
979 |
-
* @param mixed $value Value to format
|
980 |
-
* @param string $context Current context
|
981 |
-
* @return mixed Formatted value
|
982 |
-
*/
|
983 |
-
function format($value, $context = '') {
|
984 |
-
$handler = 'format_' . trim(strval($context));
|
985 |
-
//Only process if context is valid and has a handler
|
986 |
-
if ( !empty($context) && method_exists($this, $handler) ) {
|
987 |
-
//Pass value to handler
|
988 |
-
$value = $this->{$handler}($value, $context);
|
989 |
-
}
|
990 |
-
//Return formatted value
|
991 |
-
return $value;
|
992 |
-
}
|
993 |
-
|
994 |
-
/**
|
995 |
-
* Format value for output in form field
|
996 |
-
* @param mixed $value Value to format
|
997 |
-
* @return mixed Formatted value
|
998 |
-
*/
|
999 |
-
function format_form($value) {
|
1000 |
-
if ( is_string($value) )
|
1001 |
-
$value = htmlspecialchars($value);
|
1002 |
-
return $value;
|
1003 |
-
}
|
1004 |
-
|
1005 |
-
/**
|
1006 |
-
* Final formatting before output
|
1007 |
-
* Restores special characters, etc.
|
1008 |
-
* @uses $special_chars
|
1009 |
-
* @uses $special_chars_default
|
1010 |
-
* @param mixed $value Pre-final field output
|
1011 |
-
* @param string $context (Optional) Formatting context
|
1012 |
-
* @return mixed Formatted value
|
1013 |
-
*/
|
1014 |
-
function format_final($value, $context = '') {
|
1015 |
-
if ( !is_string($value) )
|
1016 |
-
return $value;
|
1017 |
-
|
1018 |
-
//Restore special chars
|
1019 |
-
return $this->restore_special_chars($value, $context);
|
1020 |
-
}
|
1021 |
-
|
1022 |
-
function preserve_special_chars($value, $context = '') {
|
1023 |
-
if ( !is_string($value) )
|
1024 |
-
return $value;
|
1025 |
-
$specials = $this->get_special_chars();
|
1026 |
-
return str_replace(array_keys($specials), $specials, $value);
|
1027 |
-
}
|
1028 |
-
|
1029 |
-
function restore_special_chars($value, $context = '') {
|
1030 |
-
if ( !is_string($value) )
|
1031 |
-
return $value;
|
1032 |
-
$specials = $this->get_special_chars();
|
1033 |
-
return str_replace($specials, array_keys($specials), $value);
|
1034 |
-
}
|
1035 |
-
|
1036 |
-
/**
|
1037 |
-
* Retrieve special characters/placeholders
|
1038 |
-
* Merges defaults with class-specific characters
|
1039 |
-
* @uses $special_chars
|
1040 |
-
* @uses $special_chars_default
|
1041 |
-
* @return array Special characters/placeholders
|
1042 |
-
*/
|
1043 |
-
function get_special_chars() {
|
1044 |
-
return wp_parse_args($this->special_chars, $this->special_chars_default);
|
1045 |
-
}
|
1046 |
-
}
|
1047 |
-
|
1048 |
-
/**
|
1049 |
-
* Field Types
|
1050 |
-
* Stores properties for a specific field
|
1051 |
-
* @package Simple Lightbox
|
1052 |
-
* @subpackage Fields
|
1053 |
-
* @author Archetyped
|
1054 |
-
*/
|
1055 |
-
class SLB_Field_Type extends SLB_Field_Base {
|
1056 |
-
/* Properties */
|
1057 |
-
|
1058 |
-
/**
|
1059 |
-
* @var array Array of Field types that make up current Field type
|
1060 |
-
*/
|
1061 |
-
var $elements = array();
|
1062 |
-
|
1063 |
-
/**
|
1064 |
-
* @var array Field type layouts
|
1065 |
-
*/
|
1066 |
-
var $layout = array();
|
1067 |
-
|
1068 |
-
/**
|
1069 |
-
* @var SLB_Field_Type Parent field type (reference)
|
1070 |
-
*/
|
1071 |
-
var $parent = null;
|
1072 |
-
|
1073 |
-
/**
|
1074 |
-
* Object that field is in
|
1075 |
-
* @var SLB_Field|SLB_Field_Type|SLB_Field_Collection
|
1076 |
-
*/
|
1077 |
-
var $container = null;
|
1078 |
-
|
1079 |
-
/**
|
1080 |
-
* Object that called field
|
1081 |
-
* Used to determine field hierarchy/nesting
|
1082 |
-
* @var SLB_Field|SLB_Field_Type|SLB_Field_Collection
|
1083 |
-
*/
|
1084 |
-
var $caller = null;
|
1085 |
-
|
1086 |
-
function __construct($id = '', $parent = null) {
|
1087 |
-
$args = func_get_args();
|
1088 |
-
$defaults = $this->integrate_id($id);
|
1089 |
-
if ( !is_array($parent) )
|
1090 |
-
$defaults['parent'] = $parent;
|
1091 |
-
|
1092 |
-
$props = $this->make_properties($args, $defaults);
|
1093 |
-
parent::__construct($props);
|
1094 |
-
}
|
1095 |
-
|
1096 |
-
/* Getters/Setters */
|
1097 |
-
|
1098 |
-
/**
|
1099 |
-
* Search for specified member value in field's container object (if exists)
|
1100 |
-
* @param string $member Name of object member to search (e.g. properties, layout, etc.)
|
1101 |
-
* @param string $name Value to retrieve from member
|
1102 |
-
* @return mixed Member value if found (Default: empty string)
|
1103 |
-
*/
|
1104 |
-
function get_container_value($member, $name = '', $default = '') {
|
1105 |
-
$container =& $this->get_container();
|
1106 |
-
return $this->get_object_value($container, $member, $name, $default, 'container');
|
1107 |
-
}
|
1108 |
-
|
1109 |
-
/**
|
1110 |
-
* Search for specified member value in field's container object (if exists)
|
1111 |
-
* @param string $member Name of object member to search (e.g. properties, layout, etc.)
|
1112 |
-
* @param string $name Value to retrieve from member
|
1113 |
-
* @return mixed Member value if found (Default: empty string)
|
1114 |
-
*/
|
1115 |
-
function get_caller_value($member, $name = '', $default = '') {
|
1116 |
-
$caller =& $this->get_caller();
|
1117 |
-
return $this->get_object_value($caller, $member, $name, $default, 'caller');
|
1118 |
-
}
|
1119 |
-
|
1120 |
-
/**
|
1121 |
-
* Sets reference to container object of current field
|
1122 |
-
* Reference is cleared if no valid object is passed to method
|
1123 |
-
* @param object $container
|
1124 |
-
*/
|
1125 |
-
function set_container(&$container) {
|
1126 |
-
if ( !empty($container) && is_object($container) ) {
|
1127 |
-
//Set as param as container for current field
|
1128 |
-
$this->container =& $container;
|
1129 |
-
} else {
|
1130 |
-
//Clear container member if argument is invalid
|
1131 |
-
$this->clear_container();
|
1132 |
-
}
|
1133 |
-
}
|
1134 |
-
|
1135 |
-
/**
|
1136 |
-
* Clears reference to container object of current field
|
1137 |
-
*/
|
1138 |
-
function clear_container() {
|
1139 |
-
$this->container = null;
|
1140 |
-
}
|
1141 |
-
|
1142 |
-
/**
|
1143 |
-
* Retrieves reference to container object of current field
|
1144 |
-
* @return object Reference to container object
|
1145 |
-
*/
|
1146 |
-
function &get_container() {
|
1147 |
-
$ret = null;
|
1148 |
-
if ( $this->has_container() )
|
1149 |
-
$ret =& $this->container;
|
1150 |
-
return $ret;
|
1151 |
-
}
|
1152 |
-
|
1153 |
-
/**
|
1154 |
-
* Checks if field has a container reference
|
1155 |
-
* @return bool TRUE if field is contained, FALSE otherwise
|
1156 |
-
*/
|
1157 |
-
function has_container() {
|
1158 |
-
return !empty($this->container);
|
1159 |
-
}
|
1160 |
-
|
1161 |
-
/**
|
1162 |
-
* Sets reference to calling object of current field
|
1163 |
-
* Any existing reference is cleared if no valid object is passed to method
|
1164 |
-
* @param object $caller Calling object
|
1165 |
-
*/
|
1166 |
-
function set_caller(&$caller) {
|
1167 |
-
if ( !empty($caller) && is_object($caller) )
|
1168 |
-
$this->caller =& $caller;
|
1169 |
-
else
|
1170 |
-
$this->clear_caller();
|
1171 |
-
}
|
1172 |
-
|
1173 |
-
/**
|
1174 |
-
* Clears reference to calling object of current field
|
1175 |
-
*/
|
1176 |
-
function clear_caller() {
|
1177 |
-
unset($this->caller);
|
1178 |
-
}
|
1179 |
-
|
1180 |
-
/**
|
1181 |
-
* Retrieves reference to caller object of current field
|
1182 |
-
* @return object Reference to caller object
|
1183 |
-
*/
|
1184 |
-
function &get_caller() {
|
1185 |
-
$ret = null;
|
1186 |
-
if ( $this->has_caller() )
|
1187 |
-
$ret =& $this->caller;
|
1188 |
-
return $ret;
|
1189 |
-
}
|
1190 |
-
|
1191 |
-
/**
|
1192 |
-
* Checks if field has a caller reference
|
1193 |
-
* @return bool TRUE if field is called by another field, FALSE otherwise
|
1194 |
-
*/
|
1195 |
-
function has_caller() {
|
1196 |
-
return !empty($this->caller);
|
1197 |
-
}
|
1198 |
-
|
1199 |
-
|
1200 |
-
|
1201 |
-
/**
|
1202 |
-
* Sets an element for the field type
|
1203 |
-
* @param string $name Name of element
|
1204 |
-
* @param SLB_Field_Type $type Reference of field type to use for element
|
1205 |
-
* @param array $properties Properties for element (passed as keyed associative array)
|
1206 |
-
* @param string $id_prop Name of property to set $name to (e.g. ID, etc.)
|
1207 |
-
*/
|
1208 |
-
function set_element($name, $type, $properties = array(), $id_prop = 'id') {
|
1209 |
-
$name = trim(strval($name));
|
1210 |
-
if ( empty($name) )
|
1211 |
-
return false;
|
1212 |
-
//Create new field for element
|
1213 |
-
$el = new SLB_Field($name, $type);
|
1214 |
-
//Set container to current field instance
|
1215 |
-
$el->set_container($this);
|
1216 |
-
//Add properties to element
|
1217 |
-
$el->set_properties($properties);
|
1218 |
-
//Save element to current instance
|
1219 |
-
$this->elements[$name] =& $el;
|
1220 |
-
}
|
1221 |
-
|
1222 |
-
/**
|
1223 |
-
* Add a layout to the field
|
1224 |
-
* @param string $name Name of layout
|
1225 |
-
* @param string $value Layout text
|
1226 |
-
*/
|
1227 |
-
function set_layout($name, $value = '') {
|
1228 |
-
if ( !is_string($name) )
|
1229 |
-
return false;
|
1230 |
-
$name = trim($name);
|
1231 |
-
$this->layout[$name] = $value;
|
1232 |
-
return true;
|
1233 |
-
}
|
1234 |
-
|
1235 |
-
/**
|
1236 |
-
* Retrieve specified layout
|
1237 |
-
* @param string $name Layout name
|
1238 |
-
* @param bool $parse_nested (optional) Whether nested layouts should be expanded in retreived layout or not (Default: TRUE)
|
1239 |
-
* @return string Specified layout text
|
1240 |
-
*/
|
1241 |
-
function get_layout($name = 'form', $parse_nested = true) {
|
1242 |
-
//Retrieve specified layout (use $name value if no layout by that name exists)
|
1243 |
-
if ( empty($name) )
|
1244 |
-
$name = $this->get_container_value('build_vars', 'layout', 'form');
|
1245 |
-
$layout = $this->get_member_value('layout', $name, $name);
|
1246 |
-
|
1247 |
-
//Find all nested layouts in current layout
|
1248 |
-
if ( !empty($layout) && !!$parse_nested ) {
|
1249 |
-
$ph = $this->get_placeholder_defaults();
|
1250 |
-
|
1251 |
-
while ($ph->match = $this->parse_layout($layout, $ph->pattern_layout)) {
|
1252 |
-
//Iterate through the different types of layout placeholders
|
1253 |
-
foreach ($ph->match as $tag => $instances) {
|
1254 |
-
//Iterate through instances of a specific type of layout placeholder
|
1255 |
-
foreach ($instances as $instance) {
|
1256 |
-
//Get nested layout
|
1257 |
-
$nested_layout = $this->get_member_value($instance);
|
1258 |
-
|
1259 |
-
//Replace layout placeholder with retrieved item data
|
1260 |
-
if ( !empty($nested_layout) )
|
1261 |
-
$layout = str_replace($ph->start . $instance['match'] . $ph->end, $nested_layout, $layout);
|
1262 |
-
}
|
1263 |
-
}
|
1264 |
-
}
|
1265 |
-
}
|
1266 |
-
|
1267 |
-
return $layout;
|
1268 |
-
}
|
1269 |
-
|
1270 |
-
/**
|
1271 |
-
* Checks if specified layout exists
|
1272 |
-
* Finds layout if it exists in current object or any of its parents
|
1273 |
-
* @param string $layout Name of layout to check for
|
1274 |
-
* @return bool TRUE if layout exists, FALSE otherwise
|
1275 |
-
*/
|
1276 |
-
function has_layout($layout) {
|
1277 |
-
$ret = false;
|
1278 |
-
if ( is_string($layout) && ($layout = trim($layout)) && !empty($layout) ) {
|
1279 |
-
$layout = $this->get_member_value('layout', $layout, false);
|
1280 |
-
if ( $layout !== false )
|
1281 |
-
$ret = true;
|
1282 |
-
}
|
1283 |
-
|
1284 |
-
return $ret;
|
1285 |
-
}
|
1286 |
-
|
1287 |
-
/**
|
1288 |
-
* Checks if layout content is valid
|
1289 |
-
* Layouts need to have placeholders to be valid
|
1290 |
-
* @param string $layout_content Layout content (markup)
|
1291 |
-
* @return bool TRUE if layout is valid, FALSE otherwise
|
1292 |
-
*/
|
1293 |
-
function is_valid_layout($layout_content) {
|
1294 |
-
$ph = $this->get_placeholder_defaults();
|
1295 |
-
return preg_match($ph->pattern_general, $layout_content);
|
1296 |
-
}
|
1297 |
-
|
1298 |
-
/**
|
1299 |
-
* Parse field layout with a regular expression
|
1300 |
-
* @param string $layout Layout data
|
1301 |
-
* @param string $search Regular expression pattern to search layout for
|
1302 |
-
* @return array Associative array containing all of the regular expression matches in the layout data
|
1303 |
-
* Array Structure:
|
1304 |
-
* root => placeholder tags
|
1305 |
-
* => Tag instances (array)
|
1306 |
-
* 'tag' => (string) tag name
|
1307 |
-
* 'match' => (string) placeholder match
|
1308 |
-
* 'attributes' => (array) attributes
|
1309 |
-
*/
|
1310 |
-
function parse_layout($layout, $search) {
|
1311 |
-
$ph_xml = '';
|
1312 |
-
$parse_match = '';
|
1313 |
-
$ph_root_tag = 'ph_root_element';
|
1314 |
-
$ph_start_xml = '<';
|
1315 |
-
$ph_end_xml = ' />';
|
1316 |
-
$ph_wrap_start = '<' . $ph_root_tag . '>';
|
1317 |
-
$ph_wrap_end = '</' . $ph_root_tag . '>';
|
1318 |
-
$parse_result = false;
|
1319 |
-
|
1320 |
-
//Find all nested layouts in layout
|
1321 |
-
$match_value = preg_match_all($search, $layout, $parse_match, PREG_PATTERN_ORDER);
|
1322 |
-
|
1323 |
-
if ($match_value !== false && $match_value > 0) {
|
1324 |
-
$parse_result = array();
|
1325 |
-
//Get all matched elements
|
1326 |
-
$parse_match = $parse_match[1];
|
1327 |
-
|
1328 |
-
//Build XML string from placeholders
|
1329 |
-
foreach ($parse_match as $ph) {
|
1330 |
-
$ph_xml .= $ph_start_xml . $ph . $ph_end_xml . ' ';
|
1331 |
-
}
|
1332 |
-
$ph_xml = $ph_wrap_start . $ph_xml . $ph_wrap_end;
|
1333 |
-
//Parse XML data
|
1334 |
-
$ph_prs = xml_parser_create();
|
1335 |
-
xml_parser_set_option($ph_prs, XML_OPTION_SKIP_WHITE, 1);
|
1336 |
-
xml_parser_set_option($ph_prs, XML_OPTION_CASE_FOLDING, 0);
|
1337 |
-
$ret = xml_parse_into_struct($ph_prs, $ph_xml, $parse_result['values'], $parse_result['index']);
|
1338 |
-
xml_parser_free($ph_prs);
|
1339 |
-
|
1340 |
-
//Build structured array with all parsed data
|
1341 |
-
|
1342 |
-
unset($parse_result['index'][$ph_root_tag]);
|
1343 |
-
|
1344 |
-
//Build structured array
|
1345 |
-
$result = array();
|
1346 |
-
foreach ($parse_result['index'] as $tag => $instances) {
|
1347 |
-
$result[$tag] = array();
|
1348 |
-
//Instances
|
1349 |
-
foreach ($instances as $instance) {
|
1350 |
-
//Skip instance if it doesn't exist in parse results
|
1351 |
-
if (!isset($parse_result['values'][$instance]))
|
1352 |
-
continue;
|
1353 |
-
|
1354 |
-
//Stop processing instance if a previously-saved instance with the same options already exists
|
1355 |
-
foreach ($result[$tag] as $tag_match) {
|
1356 |
-
if ($tag_match['match'] == $parse_match[$instance - 1])
|
1357 |
-
continue 2;
|
1358 |
-
}
|
1359 |
-
|
1360 |
-
//Init instance data array
|
1361 |
-
$inst_data = array();
|
1362 |
-
|
1363 |
-
//Add Tag to array
|
1364 |
-
$inst_data['tag'] = $parse_result['values'][$instance]['tag'];
|
1365 |
-
|
1366 |
-
//Add instance data to array
|
1367 |
-
$inst_data['attributes'] = (isset($parse_result['values'][$instance]['attributes'])) ? $inst_data['attributes'] = $parse_result['values'][$instance]['attributes'] : '';
|
1368 |
-
|
1369 |
-
//Add match to array
|
1370 |
-
$inst_data['match'] = $parse_match[$instance - 1];
|
1371 |
-
|
1372 |
-
//Add to result array
|
1373 |
-
$result[$tag][] = $inst_data;
|
1374 |
-
}
|
1375 |
-
}
|
1376 |
-
$parse_result = $result;
|
1377 |
-
}
|
1378 |
-
|
1379 |
-
return $parse_result;
|
1380 |
-
}
|
1381 |
-
|
1382 |
-
/**
|
1383 |
-
* Retrieves default properties to use when evaluating layout placeholders
|
1384 |
-
* @return object Object with properties for evaluating layout placeholders
|
1385 |
-
*/
|
1386 |
-
function get_placeholder_defaults() {
|
1387 |
-
$ph = new stdClass();
|
1388 |
-
$ph->start = '{';
|
1389 |
-
$ph->end = '}';
|
1390 |
-
$ph->reserved = array('ref' => 'ref_base');
|
1391 |
-
$ph->pattern_general = '/' . $ph->start . '([a-zA-Z0-9_].*?)' . $ph->end . '/i';
|
1392 |
-
$ph->pattern_layout = '/' . $ph->start . '([a-zA-Z0-9].*?\s+' . $ph->reserved['ref'] . '="layout.*?".*?)' . $ph->end . '/i';
|
1393 |
-
return $ph;
|
1394 |
-
}
|
1395 |
-
|
1396 |
-
/**
|
1397 |
-
* Build item output
|
1398 |
-
* @param string $layout (optional) Layout to build
|
1399 |
-
* @param string $data Data to pass to layout
|
1400 |
-
*/
|
1401 |
-
function build($layout = null, $data = null) {
|
1402 |
-
$this->util->do_action_ref_array('build_pre', array(&$this));
|
1403 |
-
echo $this->build_layout($layout, $data);
|
1404 |
-
$this->util->do_action_ref_array('build_post', array(&$this));
|
1405 |
-
}
|
1406 |
-
|
1407 |
-
/**
|
1408 |
-
* Builds HTML for a field based on its properties
|
1409 |
-
* @param string $layout (optional) Name of layout to build
|
1410 |
-
* @param array $data Additional data for current item
|
1411 |
-
*/
|
1412 |
-
function build_layout($layout = 'form', $data = null) {
|
1413 |
-
$out_default = '';
|
1414 |
-
//Get base layout
|
1415 |
-
$out = $this->get_layout($layout);
|
1416 |
-
//Only parse valid layouts
|
1417 |
-
if ( $this->is_valid_layout($out) ) {
|
1418 |
-
//Parse Layout
|
1419 |
-
$ph = $this->get_placeholder_defaults();
|
1420 |
-
|
1421 |
-
//Search layout for placeholders
|
1422 |
-
while ( $ph->match = $this->parse_layout($out, $ph->pattern_general) ) {
|
1423 |
-
//Iterate through placeholders (tag, id, etc.)
|
1424 |
-
foreach ( $ph->match as $tag => $instances ) {
|
1425 |
-
//Iterate through instances of current placeholder
|
1426 |
-
foreach ( $instances as $instance ) {
|
1427 |
-
//Process value based on placeholder name
|
1428 |
-
$target_property = apply_filters($this->add_prefix('process_placeholder_' . $tag), '', $this, $instance, $layout, $data);
|
1429 |
-
//Process value using default processors (if necessary)
|
1430 |
-
if ( '' == $target_property ) {
|
1431 |
-
$target_property = apply_filters($this->add_prefix('process_placeholder'), $target_property, $this, $instance, $layout, $data);
|
1432 |
-
}
|
1433 |
-
|
1434 |
-
//Clear value if value not a string
|
1435 |
-
if ( !is_scalar($target_property) ) {
|
1436 |
-
$target_property = '';
|
1437 |
-
}
|
1438 |
-
|
1439 |
-
//Replace layout placeholder with retrieved item data
|
1440 |
-
$out = str_replace($ph->start . $instance['match'] . $ph->end, $target_property, $out);
|
1441 |
-
}
|
1442 |
-
}
|
1443 |
-
}
|
1444 |
-
} else {
|
1445 |
-
$out = $out_default;
|
1446 |
-
}
|
1447 |
-
/* Return generated value */
|
1448 |
-
$out = $this->format_final($out);
|
1449 |
-
return $out;
|
1450 |
-
}
|
1451 |
-
}
|
1452 |
-
|
1453 |
-
class SLB_Field extends SLB_Field_Type {}
|
1454 |
-
|
1455 |
-
/**
|
1456 |
-
* Managed collection of fields
|
1457 |
-
* @package Simple Lightbox
|
1458 |
-
* @subpackage Fields
|
1459 |
-
* @author Archetyped
|
1460 |
-
*/
|
1461 |
-
class SLB_Field_Collection extends SLB_Field_Base {
|
1462 |
-
|
1463 |
-
/* Configuration */
|
1464 |
-
|
1465 |
-
protected $mode = 'sub';
|
1466 |
-
|
1467 |
-
/* Properties */
|
1468 |
-
|
1469 |
-
/**
|
1470 |
-
* Item type
|
1471 |
-
* @var string
|
1472 |
-
*/
|
1473 |
-
var $item_type = 'SLB_Field';
|
1474 |
-
|
1475 |
-
/**
|
1476 |
-
* Indexed array of items in collection
|
1477 |
-
* @var array
|
1478 |
-
*/
|
1479 |
-
var $items = array();
|
1480 |
-
|
1481 |
-
var $id_formats = array (
|
1482 |
-
'formatted' => array(
|
1483 |
-
'wrap' => array ( 'open' => '_' ),
|
1484 |
-
'recursive' => false,
|
1485 |
-
'prefix' => array('get_prefix')
|
1486 |
-
)
|
1487 |
-
);
|
1488 |
-
|
1489 |
-
var $build_vars_default = array (
|
1490 |
-
'groups' => array(),
|
1491 |
-
'context' => '',
|
1492 |
-
'layout' => 'form',
|
1493 |
-
'build' => true,
|
1494 |
-
'build_groups' => true,
|
1495 |
-
);
|
1496 |
-
|
1497 |
-
/**
|
1498 |
-
* Associative array of groups in collection
|
1499 |
-
* Key: Group name
|
1500 |
-
* Value: object of group properties
|
1501 |
-
* > title
|
1502 |
-
* > description string Group description
|
1503 |
-
* > items array Items in group
|
1504 |
-
* @var array
|
1505 |
-
*/
|
1506 |
-
var $groups = array();
|
1507 |
-
|
1508 |
-
protected $properties_init = null;
|
1509 |
-
|
1510 |
-
/* Constructors */
|
1511 |
-
|
1512 |
-
/**
|
1513 |
-
* Class constructor
|
1514 |
-
* @uses parent::__construct()
|
1515 |
-
* @uses self::make_properties()
|
1516 |
-
* @uses self::init()
|
1517 |
-
* @uses self::add_groups()
|
1518 |
-
* @uses self::add_items()
|
1519 |
-
* @param string $id Collection ID
|
1520 |
-
* @param array $properties (optional) Properties to set for collection (Default: none)
|
1521 |
-
*/
|
1522 |
-
public function __construct($id, $properties = null) {
|
1523 |
-
$args = func_get_args();
|
1524 |
-
$properties = $this->make_properties($args);
|
1525 |
-
//Parent constructor
|
1526 |
-
parent::__construct($properties);
|
1527 |
-
|
1528 |
-
//Save initial properties
|
1529 |
-
$this->properties_init = $properties;
|
1530 |
-
}
|
1531 |
-
|
1532 |
-
public function _init() {
|
1533 |
-
parent::_init();
|
1534 |
-
$this->load($this->properties_init, false);
|
1535 |
-
}
|
1536 |
-
|
1537 |
-
/*-** Getters/Setters **-*/
|
1538 |
-
|
1539 |
-
/* Setup */
|
1540 |
-
|
1541 |
-
/**
|
1542 |
-
* Load collection with specified properties
|
1543 |
-
* Updates existing properties
|
1544 |
-
* @param array $properties Properties to load
|
1545 |
-
* @param bool $update (optional) Update (TRUE) or overwrite (FALSE) items/groups (Default: TRUE)
|
1546 |
-
* @return object Current instance
|
1547 |
-
*/
|
1548 |
-
public function load($properties, $update = true) {
|
1549 |
-
$args = func_get_args();
|
1550 |
-
$properties = $this->make_properties($args);
|
1551 |
-
if ( !empty($properties) ) {
|
1552 |
-
//Groups
|
1553 |
-
if ( isset($properties['groups']) ) {
|
1554 |
-
$this->add_groups($properties['groups'], $update);
|
1555 |
-
}
|
1556 |
-
//Items
|
1557 |
-
if ( isset($properties['items']) ) {
|
1558 |
-
$this->add_items($properties['items'], $update);
|
1559 |
-
}
|
1560 |
-
}
|
1561 |
-
return $this;
|
1562 |
-
}
|
1563 |
-
|
1564 |
-
/* Data */
|
1565 |
-
|
1566 |
-
/**
|
1567 |
-
* Retrieve external data for items in collection
|
1568 |
-
* Retrieved data is saved to the collection's $data property
|
1569 |
-
* Uses class properties to determine how data is retrieved
|
1570 |
-
* Examples:
|
1571 |
-
* > DB
|
1572 |
-
* > XML
|
1573 |
-
* > JSON
|
1574 |
-
* @return void
|
1575 |
-
*/
|
1576 |
-
function load_data() {
|
1577 |
-
$this->data_loaded = true;
|
1578 |
-
}
|
1579 |
-
|
1580 |
-
/**
|
1581 |
-
* Set data for an item
|
1582 |
-
* @param mixed $item Field to set data for
|
1583 |
-
* > string Field ID
|
1584 |
-
* > object Field Reference
|
1585 |
-
* > array Data for multiple items (associative array [field ID => data])
|
1586 |
-
* @param mixed $value Data to set
|
1587 |
-
* @param bool $save (optional) Whether or not data should be saved to DB (Default: Yes)
|
1588 |
-
*/
|
1589 |
-
function set_data($item, $value = '', $save = true, $force_set = false) {
|
1590 |
-
//Set data for entire collection
|
1591 |
-
if ( is_array($item) ) {
|
1592 |
-
$this->data = wp_parse_args($item, $this->data);
|
1593 |
-
//Update save option
|
1594 |
-
$args = func_get_args();
|
1595 |
-
if ( 2 == count($args) && is_bool($args[1]) ) {
|
1596 |
-
$save = $args[1];
|
1597 |
-
}
|
1598 |
-
}
|
1599 |
-
//Get $item's ID
|
1600 |
-
elseif ( is_object($item) && method_exists($item, 'get_id') )
|
1601 |
-
$item = $item->get_id();
|
1602 |
-
//Set data
|
1603 |
-
if ( is_string($item) && !empty($item) && ( isset($this->items[$item]) || !!$force_set ) )
|
1604 |
-
$this->data[$item] = $value;
|
1605 |
-
if ( !!$save )
|
1606 |
-
$this->save();
|
1607 |
-
}
|
1608 |
-
|
1609 |
-
/* Item */
|
1610 |
-
|
1611 |
-
/**
|
1612 |
-
* Adds item to collection
|
1613 |
-
* @param string|obj $id Unique name for item or item instance
|
1614 |
-
* @param array $properties (optional) Item properties
|
1615 |
-
* @param bool $update (optional) Update or overwrite existing item (Default: FALSE)
|
1616 |
-
* @return object Reference to new item
|
1617 |
-
*/
|
1618 |
-
function &add($id, $properties = array(), $update = false) {
|
1619 |
-
$item;
|
1620 |
-
$args = func_get_args();
|
1621 |
-
//Properties
|
1622 |
-
foreach ( array_reverse($args) as $arg ) {
|
1623 |
-
if ( is_array($arg) ) {
|
1624 |
-
$properties = $arg;
|
1625 |
-
break;
|
1626 |
-
}
|
1627 |
-
}
|
1628 |
-
if ( !is_array($properties) ) {
|
1629 |
-
$properties = array();
|
1630 |
-
}
|
1631 |
-
|
1632 |
-
//Handle item instance
|
1633 |
-
if ( $id instanceof $this->item_type ) {
|
1634 |
-
$item = $id;
|
1635 |
-
$item->set_properties($properties);
|
1636 |
-
} elseif ( class_exists($this->item_type) ) {
|
1637 |
-
$defaults = array (
|
1638 |
-
'parent' => null,
|
1639 |
-
'group' => null
|
1640 |
-
);
|
1641 |
-
$properties = array_merge($defaults, $properties);
|
1642 |
-
if ( is_string($id) ) {
|
1643 |
-
$properties['id'] = $id;
|
1644 |
-
}
|
1645 |
-
if ( !!$update && $this->has($properties['id']) ) {
|
1646 |
-
//Update existing item
|
1647 |
-
$item = $this->get($properties['id']);
|
1648 |
-
$item->set_properties($properties);
|
1649 |
-
} else {
|
1650 |
-
//Init item
|
1651 |
-
$type = $this->item_type;
|
1652 |
-
$item = new $type($properties);
|
1653 |
-
}
|
1654 |
-
}
|
1655 |
-
|
1656 |
-
if ( empty($item) || 0 == strlen($item->get_id()) ) {
|
1657 |
-
return false;
|
1658 |
-
}
|
1659 |
-
|
1660 |
-
//Set container
|
1661 |
-
$item->set_container($this);
|
1662 |
-
|
1663 |
-
//Add item to collection
|
1664 |
-
$this->items[$item->get_id()] = $item;
|
1665 |
-
|
1666 |
-
if ( isset($properties['group']) ) {
|
1667 |
-
$this->add_to_group($properties['group'], $item->get_id());
|
1668 |
-
}
|
1669 |
-
|
1670 |
-
return $item;
|
1671 |
-
}
|
1672 |
-
|
1673 |
-
/**
|
1674 |
-
* Removes item from collection
|
1675 |
-
* @param string|object $item Object or item ID to remove
|
1676 |
-
* @param bool $save (optional) Whether to save the collection after removing item (Default: YES)
|
1677 |
-
*/
|
1678 |
-
function remove($item, $save = true) {
|
1679 |
-
//Remove item
|
1680 |
-
if ( $this->has($item) ) {
|
1681 |
-
$item = $this->get($item);
|
1682 |
-
$item = $item->get_id();
|
1683 |
-
//Remove from items array
|
1684 |
-
unset($this->items[$item]);
|
1685 |
-
//Remove item from groups
|
1686 |
-
$this->remove_from_group($item);
|
1687 |
-
}
|
1688 |
-
//Remove item data from collection
|
1689 |
-
$this->remove_data($item, false);
|
1690 |
-
|
1691 |
-
if ( !!$save )
|
1692 |
-
$this->save();
|
1693 |
-
}
|
1694 |
-
|
1695 |
-
/**
|
1696 |
-
* Remove item data from collection
|
1697 |
-
* @param string|object $item Object or item ID to remove
|
1698 |
-
* @param bool $save (optional) Whether to save the collection after removing item (Default: YES)
|
1699 |
-
*/
|
1700 |
-
function remove_data($item, $save = true) {
|
1701 |
-
//Get item ID from object
|
1702 |
-
if ( $this->has($item) ) {
|
1703 |
-
$item = $this->get($item);
|
1704 |
-
$item = $item->get_id();
|
1705 |
-
}
|
1706 |
-
|
1707 |
-
//Remove data from data member
|
1708 |
-
if ( is_string($item) && is_array($this->data) ) {
|
1709 |
-
unset($this->data[$item]);
|
1710 |
-
if ( !!$save )
|
1711 |
-
$this->save();
|
1712 |
-
}
|
1713 |
-
}
|
1714 |
-
|
1715 |
-
/**
|
1716 |
-
* Checks if item exists in the collection
|
1717 |
-
* @param string $item Item ID
|
1718 |
-
* @return bool TRUE if item exists, FALSE otherwise
|
1719 |
-
*/
|
1720 |
-
function has($item) {
|
1721 |
-
return ( !is_string($item) || empty($item) || is_null($this->get_member_value('items', $item, null)) ) ? false : true;
|
1722 |
-
}
|
1723 |
-
|
1724 |
-
/**
|
1725 |
-
* Retrieve specified item in collection
|
1726 |
-
* @param string|object $item Item object or ID to retrieve
|
1727 |
-
* @return SLB_Field Specified item
|
1728 |
-
*/
|
1729 |
-
function get($item, $safe_mode = false) {
|
1730 |
-
if ( $this->has($item) ) {
|
1731 |
-
if ( !is_object($item) || !is_a($item, $this->item_type) ) {
|
1732 |
-
if ( is_string($item) ) {
|
1733 |
-
$item = trim($item);
|
1734 |
-
$item =& $this->items[$item];
|
1735 |
-
}
|
1736 |
-
else {
|
1737 |
-
$item = false;
|
1738 |
-
}
|
1739 |
-
}
|
1740 |
-
} else {
|
1741 |
-
$item = false;
|
1742 |
-
}
|
1743 |
-
|
1744 |
-
if ( !!$safe_mode && !is_object($item) ) {
|
1745 |
-
//Fallback: Return empty item if no item exists
|
1746 |
-
$type = $this->item_type;
|
1747 |
-
$item = new $type('');
|
1748 |
-
}
|
1749 |
-
return $item;
|
1750 |
-
}
|
1751 |
-
|
1752 |
-
/**
|
1753 |
-
* Retrieve item data
|
1754 |
-
* @param $item Item to get data for
|
1755 |
-
* @param $context (optional) Context
|
1756 |
-
* @param $top (optional) Iterate through ancestors to get data (Default: Yes)
|
1757 |
-
* @return mixed Item data
|
1758 |
-
*/
|
1759 |
-
function get_data($item = null, $context = '', $top = true) {
|
1760 |
-
$this->load_data();
|
1761 |
-
$ret = null;
|
1762 |
-
if ( $this->has($item) ) {
|
1763 |
-
$item =& $this->get($item);
|
1764 |
-
$ret = $item->get_data($context, $top);
|
1765 |
-
} else {
|
1766 |
-
$ret = parent::get_data($context, $top);
|
1767 |
-
}
|
1768 |
-
|
1769 |
-
if ( is_string($item) && is_array($ret) && isset($ret[$item]) )
|
1770 |
-
$ret = $ret[$item];
|
1771 |
-
return $ret;
|
1772 |
-
}
|
1773 |
-
|
1774 |
-
/* Items (Collection) */
|
1775 |
-
|
1776 |
-
/**
|
1777 |
-
* Add multiple items to collection
|
1778 |
-
* @param array $items Items to add to collection
|
1779 |
-
* Array Structure:
|
1780 |
-
* > Key (string): Item ID
|
1781 |
-
* > Val (array): Item properties
|
1782 |
-
* @return void
|
1783 |
-
*/
|
1784 |
-
function add_items($items = array(), $update = false) {
|
1785 |
-
//Validate
|
1786 |
-
if ( !is_array($items) || empty($items) ) {
|
1787 |
-
return false;
|
1788 |
-
}
|
1789 |
-
//Add items
|
1790 |
-
foreach ( $items as $id => $props ) {
|
1791 |
-
$this->add($id, $props, $update);
|
1792 |
-
}
|
1793 |
-
}
|
1794 |
-
|
1795 |
-
/**
|
1796 |
-
* Retrieve reference to items in collection
|
1797 |
-
* @return array Collection items (reference)
|
1798 |
-
*/
|
1799 |
-
function get_items($group = null, $sort = 'priority') {
|
1800 |
-
$gset = $this->group_exists($group);
|
1801 |
-
if ( $gset ) {
|
1802 |
-
$items = $this->get_group_items($group);
|
1803 |
-
} elseif ( !empty($group) ) {
|
1804 |
-
$items = array();
|
1805 |
-
} else {
|
1806 |
-
$items = $this->items;
|
1807 |
-
}
|
1808 |
-
if ( !empty($items) ) {
|
1809 |
-
//Sort items
|
1810 |
-
if ( !empty($sort) && is_string($sort) ) {
|
1811 |
-
if ( 'priority' == $sort ) {
|
1812 |
-
if ( $gset ) {
|
1813 |
-
//Sort by priority
|
1814 |
-
ksort($items, SORT_NUMERIC);
|
1815 |
-
}
|
1816 |
-
}
|
1817 |
-
}
|
1818 |
-
//Release from buckets
|
1819 |
-
if ( $gset ) {
|
1820 |
-
$items = call_user_func_array('array_merge', $items);
|
1821 |
-
}
|
1822 |
-
}
|
1823 |
-
return $items;
|
1824 |
-
}
|
1825 |
-
|
1826 |
-
/**
|
1827 |
-
* Build output for items in specified group
|
1828 |
-
* If no group specified, all items in collection are built
|
1829 |
-
* @param string|object $group (optional) Group to build items for (ID or instance object)
|
1830 |
-
*/
|
1831 |
-
function build_items($group = null) {
|
1832 |
-
//Get group items
|
1833 |
-
$items =& $this->get_items($group);
|
1834 |
-
if ( empty($items) ) {
|
1835 |
-
return false;
|
1836 |
-
}
|
1837 |
-
|
1838 |
-
$this->util->do_action_ref_array('build_items_pre', array(&$this));
|
1839 |
-
foreach ( $items as $item ) {
|
1840 |
-
$item->build();
|
1841 |
-
}
|
1842 |
-
$this->util->do_action_ref_array('build_items_post', array(&$this));
|
1843 |
-
}
|
1844 |
-
|
1845 |
-
/* Group */
|
1846 |
-
|
1847 |
-
/**
|
1848 |
-
* Add groups to collection
|
1849 |
-
* @param array $groups Associative array of group properties
|
1850 |
-
* Array structure:
|
1851 |
-
* > Key (string): group ID
|
1852 |
-
* > Val (string): Group Title
|
1853 |
-
*/
|
1854 |
-
function add_groups($groups = array(), $update = false) {
|
1855 |
-
//Validate
|
1856 |
-
if ( !is_array($groups) || empty($groups) ) {
|
1857 |
-
return false;
|
1858 |
-
}
|
1859 |
-
//Iterate
|
1860 |
-
foreach ( $groups as $id => $props ) {
|
1861 |
-
$this->add_group($id, $props, null, $update);
|
1862 |
-
}
|
1863 |
-
}
|
1864 |
-
|
1865 |
-
/**
|
1866 |
-
* Adds group to collection
|
1867 |
-
* Groups are used to display related items in the UI
|
1868 |
-
* @param string $id Unique name for group
|
1869 |
-
* @param string $title Group title
|
1870 |
-
* @param string $description Short description of group's purpose
|
1871 |
-
* @param array $items (optional) ID's of existing items to add to group
|
1872 |
-
* @return object Group object
|
1873 |
-
*/
|
1874 |
-
function &add_group($id, $properties = array(), $items = array(), $update = false) {
|
1875 |
-
//Create new group and set properties
|
1876 |
-
$default = array (
|
1877 |
-
'title' => '',
|
1878 |
-
'description' => '',
|
1879 |
-
'priority' => 10
|
1880 |
-
);
|
1881 |
-
$p = ( is_array($properties) ) ? array_merge($default, $properties) : $default;
|
1882 |
-
if ( !is_int($p['priority']) || $p['priority'] < 0 ) {
|
1883 |
-
$p['priority'] = $default['priority'];
|
1884 |
-
}
|
1885 |
-
$id = trim($id);
|
1886 |
-
//Retrieve or init group
|
1887 |
-
if ( !!$update && $this->group_exists($id) ) {
|
1888 |
-
$grp = $this->get_group($id);
|
1889 |
-
$grp->title = $p['title'];
|
1890 |
-
$grp->description = $p['description'];
|
1891 |
-
$grp->priority = $p['priority'];
|
1892 |
-
} else {
|
1893 |
-
$this->groups[$id] =& $this->create_group($p['title'], $p['description'], $p['priority']);
|
1894 |
-
}
|
1895 |
-
//Add items to group (if supplied)
|
1896 |
-
if ( !empty($items) && is_array($items) ) {
|
1897 |
-
$this->add_to_group($id, $items);
|
1898 |
-
}
|
1899 |
-
return $this->groups[$id];
|
1900 |
-
}
|
1901 |
-
|
1902 |
-
/**
|
1903 |
-
* Remove specified group from collection
|
1904 |
-
* @param string $id Group ID to remove
|
1905 |
-
*/
|
1906 |
-
function remove_group($id) {
|
1907 |
-
$id = trim($id);
|
1908 |
-
if ( $this->group_exists($id) ) {
|
1909 |
-
unset($this->groups[$id]);
|
1910 |
-
}
|
1911 |
-
}
|
1912 |
-
|
1913 |
-
/**
|
1914 |
-
* Standardized method to create a new item group
|
1915 |
-
* @param string $title Group title (used in meta boxes, etc.)
|
1916 |
-
* @param string $description Short description of group's purpose
|
1917 |
-
* @param int $priority (optional) Group priority (e.g. used to sort groups during output)
|
1918 |
-
* @return object Group object
|
1919 |
-
*/
|
1920 |
-
function &create_group($title = '', $description = '', $priority = 10) {
|
1921 |
-
//Create new group object
|
1922 |
-
$group = new stdClass();
|
1923 |
-
/* Set group properties */
|
1924 |
-
|
1925 |
-
//Set Title
|
1926 |
-
$title = ( is_scalar($title) ) ? trim($title) : '';
|
1927 |
-
$group->title = $title;
|
1928 |
-
//Set Description
|
1929 |
-
$description = ( is_scalar($description) ) ? trim($description) : '';
|
1930 |
-
$group->description = $description;
|
1931 |
-
//Priority
|
1932 |
-
$group->priority = ( is_int($priority) ) ? $priority : 10;
|
1933 |
-
//Create array to hold items
|
1934 |
-
$group->items = array();
|
1935 |
-
return $group;
|
1936 |
-
}
|
1937 |
-
|
1938 |
-
/**
|
1939 |
-
* Checks if group exists in collection
|
1940 |
-
* @param string $id Group name
|
1941 |
-
* @return bool TRUE if group exists, FALSE otherwise
|
1942 |
-
*/
|
1943 |
-
function group_exists($group) {
|
1944 |
-
$ret = false;
|
1945 |
-
if ( is_object($group) ) {
|
1946 |
-
$ret = true;
|
1947 |
-
} elseif ( is_string($group) && ($group = trim($group)) && strlen($group) > 0 ) {
|
1948 |
-
$group = trim($group);
|
1949 |
-
//Check if group exists
|
1950 |
-
$ret = !is_null($this->get_member_value('groups', $group, null));
|
1951 |
-
}
|
1952 |
-
return $ret;
|
1953 |
-
}
|
1954 |
-
|
1955 |
-
/**
|
1956 |
-
* Adds item to a group in the collection
|
1957 |
-
* Group is created if it does not already exist
|
1958 |
-
* @param string|array $group ID of group (or group parameters if new group) to add item to
|
1959 |
-
* @param string|array $items Name or array of item(s) to add to group
|
1960 |
-
*/
|
1961 |
-
function add_to_group($group, $items, $priority = 10) {
|
1962 |
-
//Validate
|
1963 |
-
if ( empty($items) || empty($group) || ( !is_string($group) && !is_array($group) ) ) {
|
1964 |
-
return false;
|
1965 |
-
}
|
1966 |
-
|
1967 |
-
//Get group ID
|
1968 |
-
if ( is_string($group) ) {
|
1969 |
-
$group = array($group);
|
1970 |
-
}
|
1971 |
-
list($gid, $priority) = $group;
|
1972 |
-
$gid = trim(sanitize_title_with_dashes($gid));
|
1973 |
-
if ( empty($gid) ) {
|
1974 |
-
return false;
|
1975 |
-
}
|
1976 |
-
//Item priority
|
1977 |
-
if ( !is_int($priority) ) {
|
1978 |
-
$priority = 10;
|
1979 |
-
}
|
1980 |
-
|
1981 |
-
//Prepare group
|
1982 |
-
if ( !$this->group_exists($gid) ) {
|
1983 |
-
//TODO Follow
|
1984 |
-
call_user_func($this->m('add_group'), $gid, $group);
|
1985 |
-
}
|
1986 |
-
//Prepare items
|
1987 |
-
if ( !is_array($items) ) {
|
1988 |
-
$items = array($items);
|
1989 |
-
}
|
1990 |
-
//Add Items
|
1991 |
-
foreach ( $items as $item ) {
|
1992 |
-
//Skip if not in current collection
|
1993 |
-
$itm_ref =& $this->get($item);
|
1994 |
-
if ( !$itm_ref ) {
|
1995 |
-
continue;
|
1996 |
-
}
|
1997 |
-
$itm_id = $itm_ref->get_id();
|
1998 |
-
//Remove item from any other group it's in (items can only be in one group)
|
1999 |
-
foreach ( $this->get_groups() as $group ) {
|
2000 |
-
foreach ( $group->items as $tmp_pri => $tmp_items ) {
|
2001 |
-
if ( isset($group->items[$tmp_pri][$itm_id]) ) {
|
2002 |
-
unset($group->items[$tmp_pri][$itm_id]);
|
2003 |
-
}
|
2004 |
-
}
|
2005 |
-
}
|
2006 |
-
//Add reference to item in group
|
2007 |
-
$items =& $this->get_group($gid)->items;
|
2008 |
-
if ( !isset($items[$priority]) ) {
|
2009 |
-
$items[$priority] = array();
|
2010 |
-
}
|
2011 |
-
$items[$priority][$itm_id] =& $itm_ref;
|
2012 |
-
}
|
2013 |
-
unset($itm_ref);
|
2014 |
-
}
|
2015 |
-
|
2016 |
-
/**
|
2017 |
-
* Remove item from a group
|
2018 |
-
* If no group is specified, then item is removed from all groups
|
2019 |
-
* @param string|object $item Object or ID of item to remove from group
|
2020 |
-
* @param string $group (optional) Group ID to remove item from
|
2021 |
-
*/
|
2022 |
-
function remove_from_group($item, $group = '') {
|
2023 |
-
//Get ID of item to remove or stop execution if item invalid
|
2024 |
-
$item = $this->get($item);
|
2025 |
-
$item = $item->get_id();
|
2026 |
-
if ( !$item )
|
2027 |
-
return false;
|
2028 |
-
|
2029 |
-
//Remove item from group
|
2030 |
-
if ( !empty($group) ) {
|
2031 |
-
//Remove item from single group
|
2032 |
-
if ( ($group =& $this->get_group($group)) && isset($group->items[$item]) ) {
|
2033 |
-
unset($group->items[$item]);
|
2034 |
-
}
|
2035 |
-
} else {
|
2036 |
-
//Remove item from all groups
|
2037 |
-
foreach ( array_keys($this->groups) as $group ) {
|
2038 |
-
if ( ($group =& $this->get_group($group)) && isset($group->items[$item]) ) {
|
2039 |
-
unset($group->items[$item]);
|
2040 |
-
}
|
2041 |
-
}
|
2042 |
-
}
|
2043 |
-
}
|
2044 |
-
|
2045 |
-
/**
|
2046 |
-
* Retrieve specified group
|
2047 |
-
* @param string $group ID of group to retrieve
|
2048 |
-
* @return object Reference to specified group
|
2049 |
-
*/
|
2050 |
-
function &get_group($group) {
|
2051 |
-
if ( is_object($group) ) {
|
2052 |
-
return $group;
|
2053 |
-
}
|
2054 |
-
if ( is_string($group) ) {
|
2055 |
-
$group = trim($group);
|
2056 |
-
}
|
2057 |
-
//Create group if it doesn't already exist
|
2058 |
-
if ( ! $this->group_exists($group) ) {
|
2059 |
-
$this->add_group($group);
|
2060 |
-
}
|
2061 |
-
return $this->get_member_value('groups', $group);
|
2062 |
-
}
|
2063 |
-
|
2064 |
-
/**
|
2065 |
-
* Retrieve a group's items
|
2066 |
-
* @uses SLB_Field_Collection::get_group() to retrieve group object
|
2067 |
-
* @param object|string $group Group object or group ID
|
2068 |
-
* @return array Group's items
|
2069 |
-
*/
|
2070 |
-
function &get_group_items($group) {
|
2071 |
-
$group =& $this->get_group($group);
|
2072 |
-
return $group->items;
|
2073 |
-
}
|
2074 |
-
|
2075 |
-
/**
|
2076 |
-
* Retrieve all groups in collection
|
2077 |
-
* @return array Reference to group objects
|
2078 |
-
*/
|
2079 |
-
function &get_groups($opts = array()) {
|
2080 |
-
$groups =& $this->get_member_value('groups');
|
2081 |
-
if ( is_array($opts) && !empty($opts) ) {
|
2082 |
-
extract($opts, EXTR_SKIP);
|
2083 |
-
if ( !empty($groups) && !empty($sort) && is_string($sort) ) {
|
2084 |
-
if ( property_exists(current($groups), $sort) ) {
|
2085 |
-
//Sort groups by property
|
2086 |
-
$sfunc = create_function('$a,$b', '$ap = $a->' . $sort . '; $bp = $b->' . $sort . '; if ( $ap == $bp ) return 0; return ( $ap > $bp ) ? 1 : -1;');
|
2087 |
-
uasort($groups, $sfunc);
|
2088 |
-
}
|
2089 |
-
}
|
2090 |
-
}
|
2091 |
-
return $groups;
|
2092 |
-
}
|
2093 |
-
|
2094 |
-
/**
|
2095 |
-
* Output groups
|
2096 |
-
* @uses self::build_vars to determine groups to build
|
2097 |
-
*/
|
2098 |
-
function build_groups() {
|
2099 |
-
$this->util->do_action_ref_array('build_groups_pre', array(&$this));
|
2100 |
-
|
2101 |
-
//Get groups to build
|
2102 |
-
$groups = ( !empty($this->build_vars['groups']) ) ? $this->build_vars['groups'] : array_keys($this->get_groups(array('sort' => 'priority')));
|
2103 |
-
//Check options
|
2104 |
-
if ( is_callable($this->build_vars['build_groups']) ) {
|
2105 |
-
//Pass groups to callback to build output
|
2106 |
-
call_user_func_array($this->build_vars['build_groups'], array($this, $groups));
|
2107 |
-
} elseif ( !!$this->build_vars['build_groups'] ) {
|
2108 |
-
//Build groups
|
2109 |
-
foreach ( $groups as $group ) {
|
2110 |
-
$this->build_group($group);
|
2111 |
-
}
|
2112 |
-
}
|
2113 |
-
|
2114 |
-
$this->util->do_action_ref_array('build_groups_post', array(&$this));
|
2115 |
-
}
|
2116 |
-
|
2117 |
-
/**
|
2118 |
-
* Build group
|
2119 |
-
*/
|
2120 |
-
function build_group($group) {
|
2121 |
-
if ( !$this->group_exists($group) ) {
|
2122 |
-
return false;
|
2123 |
-
}
|
2124 |
-
$group =& $this->get_group($group);
|
2125 |
-
//Stop processing if group contains no items
|
2126 |
-
if ( !count($this->get_items($group)) ) {
|
2127 |
-
return false;
|
2128 |
-
}
|
2129 |
-
|
2130 |
-
//Pre action
|
2131 |
-
$this->util->do_action_ref_array('build_group_pre', array(&$this, $group));
|
2132 |
-
|
2133 |
-
//Build items
|
2134 |
-
$this->build_items($group);
|
2135 |
-
|
2136 |
-
//Post action
|
2137 |
-
$this->util->do_action_ref_array('build_group_post', array(&$this, $group));
|
2138 |
-
}
|
2139 |
-
|
2140 |
-
/* Collection */
|
2141 |
-
|
2142 |
-
/**
|
2143 |
-
* Build entire collection of items
|
2144 |
-
* Prints output
|
2145 |
-
*/
|
2146 |
-
function build($build_vars = array()) {
|
2147 |
-
//Parse vars
|
2148 |
-
$this->parse_build_vars($build_vars);
|
2149 |
-
$this->util->do_action_ref_array('build_init', array(&$this));
|
2150 |
-
//Pre-build output
|
2151 |
-
$this->util->do_action_ref_array('build_pre', array(&$this));
|
2152 |
-
//Build groups
|
2153 |
-
$this->build_groups();
|
2154 |
-
//Post-build output
|
2155 |
-
$this->util->do_action_ref_array('build_post', array(&$this));
|
2156 |
-
}
|
2157 |
-
|
2158 |
-
/**
|
2159 |
-
* Parses build variables prior to use
|
2160 |
-
* @uses this->reset_build_vars() to reset build variables for each request
|
2161 |
-
* @param array $build_vars Variables to use for current request
|
2162 |
-
*/
|
2163 |
-
function parse_build_vars($build_vars = array()) {
|
2164 |
-
$this->reset_build_vars();
|
2165 |
-
$this->build_vars = $this->util->apply_filters('parse_build_vars', wp_parse_args($build_vars, $this->build_vars), $this);
|
2166 |
-
}
|
2167 |
-
|
2168 |
-
/**
|
2169 |
-
* Reset build variables to defaults
|
2170 |
-
* Default Variables
|
2171 |
-
* > groups - array - Names of groups to build
|
2172 |
-
* > context - string - Context of current request
|
2173 |
-
* > layout - string - Name of default layout to use
|
2174 |
-
*/
|
2175 |
-
function reset_build_vars() {
|
2176 |
-
$this->build_vars = wp_parse_args($this->build_vars, $this->build_vars_default);
|
2177 |
-
}
|
2178 |
-
}
|
2179 |
-
|
2180 |
/**
|
2181 |
* Collection of default system-wide fields
|
2182 |
* @package Simple Lightbox
|
@@ -2202,9 +24,9 @@ class SLB_Fields extends SLB_Field_Collection {
|
|
2202 |
|
2203 |
protected function _hooks() {
|
2204 |
parent::_hooks();
|
2205 |
-
//Init fields
|
2206 |
add_action('init', $this->m('register_types'));
|
2207 |
-
//Init placeholders
|
2208 |
add_action('init', $this->m('register_placeholders'));
|
2209 |
}
|
2210 |
|
@@ -2216,7 +38,7 @@ class SLB_Fields extends SLB_Field_Collection {
|
|
2216 |
function register_types() {
|
2217 |
/* Field Types */
|
2218 |
|
2219 |
-
//Base
|
2220 |
$base = new SLB_Field_Type('base');
|
2221 |
$base->set_description(__('Default Element', 'simple-lightbox'));
|
2222 |
$base->set_property('tag', 'span');
|
@@ -2227,7 +49,7 @@ class SLB_Fields extends SLB_Field_Collection {
|
|
2227 |
$base->set_layout('display', '{data context="display"}');
|
2228 |
$this->add($base);
|
2229 |
|
2230 |
-
//Base closed
|
2231 |
$base_closed = new SLB_Field_Type('base_closed');
|
2232 |
$base_closed->set_parent('base');
|
2233 |
$base_closed->set_description(__('Default Element (Closed Tag)', 'simple-lightbox'));
|
@@ -2236,7 +58,7 @@ class SLB_Fields extends SLB_Field_Collection {
|
|
2236 |
$base_closed->set_layout('form', '{form_start ref_base="layout"}{data}{form_end ref_base="layout"}');
|
2237 |
$this->add($base_closed);
|
2238 |
|
2239 |
-
//Input
|
2240 |
$input = new SLB_Field_Type('input', 'base');
|
2241 |
$input->set_description(__('Default Input Element', 'simple-lightbox'));
|
2242 |
$input->set_property('tag', 'input');
|
@@ -2244,7 +66,7 @@ class SLB_Fields extends SLB_Field_Collection {
|
|
2244 |
$input->set_property('value', '{data}', 'attr');
|
2245 |
$this->add($input);
|
2246 |
|
2247 |
-
//Text input
|
2248 |
$text = new SLB_Field_Type('text', 'input');
|
2249 |
$text->set_description(__('Text Box', 'simple-lightbox'));
|
2250 |
$text->set_property('size', 15, 'attr');
|
@@ -2252,7 +74,7 @@ class SLB_Fields extends SLB_Field_Collection {
|
|
2252 |
$text->set_layout('form', '{label ref_base="layout"} {inherit}');
|
2253 |
$this->add($text);
|
2254 |
|
2255 |
-
//Checkbox
|
2256 |
$cb = new SLB_Field_Type('checkbox', 'input');
|
2257 |
$cb->set_property('type', 'checkbox');
|
2258 |
$cb->set_property('value', null);
|
@@ -2260,28 +82,28 @@ class SLB_Fields extends SLB_Field_Collection {
|
|
2260 |
$cb->set_layout('form', '{label ref_base="layout"} <{form_attr ref_base="layout"} />');
|
2261 |
$this->add($cb);
|
2262 |
|
2263 |
-
//Textarea
|
2264 |
$ta = new SLB_Field_Type('textarea', 'base_closed');
|
2265 |
$ta->set_property('tag', 'textarea');
|
2266 |
$ta->set_property('cols', 40, 'attr');
|
2267 |
$ta->set_property('rows', 3, 'attr');
|
2268 |
$this->add($ta);
|
2269 |
|
2270 |
-
//Rich Text
|
2271 |
$rt = new SLB_Field_Type('richtext', 'textarea');
|
2272 |
$rt->set_property('class', 'theEditor {inherit}');
|
2273 |
$rt->set_layout('form', '<div class="rt_container">{inherit}</div>');
|
2274 |
$rt->add_action('admin_print_footer_scripts', 'wp_tiny_mce', 25);
|
2275 |
$this->add($rt);
|
2276 |
|
2277 |
-
//Hidden
|
2278 |
$hidden = new SLB_Field_Type('hidden');
|
2279 |
$hidden->set_parent('input');
|
2280 |
$hidden->set_description(__('Hidden Field', 'simple-lightbox'));
|
2281 |
$hidden->set_property('type', 'hidden');
|
2282 |
$this->add($hidden);
|
2283 |
|
2284 |
-
//Select
|
2285 |
$select = new SLB_Field_Type('select', 'base_closed');
|
2286 |
$select->set_description(__('Select tag', 'simple-lightbox'));
|
2287 |
$select->set_property('tag', 'select');
|
@@ -2293,24 +115,24 @@ class SLB_Fields extends SLB_Field_Collection {
|
|
2293 |
$select->set_layout('option_data', '<{tag_option} value="{data_ext id="option_value"}" selected="selected">{data_ext id="option_text"}</{tag_option}>');
|
2294 |
$this->add($select);
|
2295 |
|
2296 |
-
//Span
|
2297 |
$span = new SLB_Field_Type('span', 'base_closed');
|
2298 |
$span->set_description(__('Inline wrapper', 'simple-lightbox'));
|
2299 |
$span->set_property('tag', 'span');
|
2300 |
$span->set_property('value', 'Hello there!');
|
2301 |
$this->add($span);
|
2302 |
|
2303 |
-
//Enable plugins to modify (add, remove, etc.) field types
|
2304 |
-
|
2305 |
|
2306 |
-
//Signal completion of field registration
|
2307 |
-
|
2308 |
}
|
2309 |
|
2310 |
/* Placeholder handlers */
|
2311 |
|
2312 |
function register_placeholders() {
|
2313 |
-
//Default placeholder handlers
|
2314 |
$this->register_placeholder('all', $this->m('process_placeholder_default'), 11);
|
2315 |
$this->register_placeholder('field_id', $this->m('process_placeholder_id'));
|
2316 |
$this->register_placeholder('field_name', $this->m('process_placeholder_name'));
|
@@ -2320,11 +142,11 @@ class SLB_Fields extends SLB_Field_Collection {
|
|
2320 |
$this->register_placeholder('label', $this->m('process_placeholder_label'));
|
2321 |
$this->register_placeholder('checked', $this->m('process_placeholder_checked'));
|
2322 |
|
2323 |
-
//Allow other code to register placeholders
|
2324 |
-
|
2325 |
|
2326 |
-
//Signal completion of field placeholder registration
|
2327 |
-
|
2328 |
}
|
2329 |
|
2330 |
/**
|
@@ -2359,13 +181,13 @@ class SLB_Fields extends SLB_Field_Collection {
|
|
2359 |
* @return string Value to use in place of current placeholder
|
2360 |
*/
|
2361 |
function process_placeholder_default($output, $item, $placeholder, $layout, $data) {
|
2362 |
-
//Validate parameters before processing
|
2363 |
-
if ( empty($output) &&
|
2364 |
-
//Build path to replacement data
|
2365 |
$output = $item->get_member_value($placeholder);
|
2366 |
|
2367 |
-
//Check if value is group (properties, etc.)
|
2368 |
-
//All groups must have additional attributes (beyond reserved attributes) that define how items in group are used
|
2369 |
if (is_array($output)
|
2370 |
&& !empty($placeholder['attributes'])
|
2371 |
&& is_array($placeholder['attributes'])
|
@@ -2374,12 +196,12 @@ class SLB_Fields extends SLB_Field_Collection {
|
|
2374 |
) {
|
2375 |
/* Targeted property is an array, but the placeholder contains additional options on how property is to be used */
|
2376 |
|
2377 |
-
//Find items matching criteria in $output
|
2378 |
-
//Check for group criteria
|
2379 |
if ( 'properties' == $placeholder['tag'] && ($prop_group = $item->get_group($placeholder['attributes']['group'])) && !empty($prop_group) ) {
|
2380 |
/* Process group */
|
2381 |
$group_out = array();
|
2382 |
-
//Iterate through properties in group and build string
|
2383 |
foreach ( array_keys($prop_group) as $prop_key ) {
|
2384 |
$prop_val = $item->get_property($prop_key);
|
2385 |
if ( !is_null($prop_val) )
|
@@ -2387,11 +209,11 @@ class SLB_Fields extends SLB_Field_Collection {
|
|
2387 |
}
|
2388 |
$output = implode(' ', $group_out);
|
2389 |
}
|
2390 |
-
} elseif ( is_object($output) &&
|
2391 |
/* Targeted property is actually a nested item */
|
2392 |
-
//Set caller to current item
|
2393 |
$output->set_caller($item);
|
2394 |
-
//Build layout for nested element
|
2395 |
$output = $output->build_layout($layout);
|
2396 |
}
|
2397 |
}
|
@@ -2405,7 +227,7 @@ class SLB_Fields extends SLB_Field_Collection {
|
|
2405 |
* @return string Placeholder output
|
2406 |
*/
|
2407 |
function process_placeholder_id($output, $item, $placeholder, $layout, $data) {
|
2408 |
-
//Get attributes
|
2409 |
$args = wp_parse_args($placeholder['attributes'], array('format' => 'attr_id'));
|
2410 |
return $item->get_id($args);
|
2411 |
}
|
@@ -2417,7 +239,7 @@ class SLB_Fields extends SLB_Field_Collection {
|
|
2417 |
* @return string Placeholder output
|
2418 |
*/
|
2419 |
function process_placeholder_name($output, $item, $placeholder, $layout, $data) {
|
2420 |
-
//Get attributes
|
2421 |
$args = wp_parse_args($placeholder['attributes'], array('format' => 'attr_name'));
|
2422 |
return $item->get_id($args);
|
2423 |
}
|
@@ -2428,9 +250,9 @@ class SLB_Fields extends SLB_Field_Collection {
|
|
2428 |
* @return string Field label
|
2429 |
*/
|
2430 |
function process_placeholder_label($output, $item, $placeholder, $layout, $data) {
|
2431 |
-
//Check if item has label property (e.g. sub-elements)
|
2432 |
$out = $item->get_property('label');
|
2433 |
-
//If property not set, use item title
|
2434 |
if ( empty($out) )
|
2435 |
$out = $item->get_title();
|
2436 |
return $out;
|
@@ -2446,21 +268,21 @@ class SLB_Fields extends SLB_Field_Collection {
|
|
2446 |
'context' => '',
|
2447 |
);
|
2448 |
$opts = wp_parse_args($placeholder['attributes'], $attr_default);
|
2449 |
-
//Save context to separate variable
|
2450 |
$context = $opts['context'];
|
2451 |
unset($opts['context']);
|
2452 |
-
//Get data
|
2453 |
$out = $item->get_data($opts);
|
2454 |
if ( !is_null($out) ) {
|
2455 |
-
//Get specific member in value (e.g. value from a specific item element)
|
2456 |
if ( isset($opts['element']) && is_array($out) && ( $el = $opts['element'] ) && isset($out[$el]) )
|
2457 |
$out = $out[$el];
|
2458 |
}
|
2459 |
|
2460 |
-
//Format data based on context
|
2461 |
$out = $item->preserve_special_chars($out, $context);
|
2462 |
$out = $item->format($out, $context);
|
2463 |
-
//Return data
|
2464 |
return $out;
|
2465 |
}
|
2466 |
|
@@ -2491,7 +313,7 @@ class SLB_Fields extends SLB_Field_Collection {
|
|
2491 |
* @return string Placeholder output
|
2492 |
*/
|
2493 |
function process_placeholder_loop($output, $item, $placeholder, $layout, $data) {
|
2494 |
-
//Setup loop options
|
2495 |
$attr_defaults = array (
|
2496 |
'layout' => '',
|
2497 |
'layout_data' => null,
|
@@ -2500,33 +322,33 @@ class SLB_Fields extends SLB_Field_Collection {
|
|
2500 |
$attr = wp_parse_args($placeholder['attributes'], $attr_defaults);
|
2501 |
if ( is_null($attr['layout_data']) )
|
2502 |
$attr['layout_data'] =& $attr['layout'];
|
2503 |
-
//Get data for loop
|
2504 |
$path = explode('.', $attr['data']);
|
2505 |
$loop_data = $item->get_member_value($path);
|
2506 |
|
2507 |
-
//Check if data is callback
|
2508 |
if ( is_callable($loop_data) )
|
2509 |
$loop_data = call_user_func($loop_data);
|
2510 |
|
2511 |
-
//Get item data
|
2512 |
$data = $item->get_data();
|
2513 |
|
2514 |
-
//Iterate over data and build output
|
2515 |
$out = array();
|
2516 |
if ( is_array($loop_data) && !empty($loop_data) ) {
|
2517 |
foreach ( $loop_data as $value => $label ) {
|
2518 |
-
//Load appropriate layout based on item value
|
2519 |
$layout = ( ($data === 0 && $value === $data) xor $data == $value ) ? $attr['layout_data'] : $attr['layout'];
|
2520 |
-
//Stop processing if no valid layout is returned
|
2521 |
if ( empty($layout) )
|
2522 |
continue;
|
2523 |
-
//Prep extended item data
|
2524 |
$data_ext = array('option_value' => $value, 'option_text' => $label);
|
2525 |
$out[] = $item->build_layout($layout, $data_ext);
|
2526 |
}
|
2527 |
}
|
2528 |
|
2529 |
-
//Return output
|
2530 |
return implode($out);
|
2531 |
}
|
2532 |
|
@@ -2559,32 +381,32 @@ class SLB_Fields extends SLB_Field_Collection {
|
|
2559 |
'elements' => 'has_elements'
|
2560 |
);
|
2561 |
|
2562 |
-
//Stop execution if group does not exist
|
2563 |
if ( $this->group_exists($group) && $group =& $this->get_group($group) ) {
|
2564 |
$group_items = ( count($group->items) > 1 ) ? $classnames->multi : $classnames->single . ( ( ( $fs = array_keys($group->items) ) && ( $f =& $group->items[$fs[0]] ) && ( $els = $f->get_member_value('elements', '', null) ) && !empty($els) ) ? '_' . $classnames->elements : '' );
|
2565 |
$classname = array($this->add_prefix('attributes_wrap'), $group_items);
|
2566 |
-
$out[] = '<div class="' . implode(' ', $classname) . '">'; //Wrap all items in group
|
2567 |
|
2568 |
-
//Build layout for each item in group
|
2569 |
foreach ( array_keys($group->items) as $item_id ) {
|
2570 |
$item =& $group->items[$item_id];
|
2571 |
$item->set_caller($this);
|
2572 |
-
//Start item output
|
2573 |
$id = $this->add_prefix('field_' . $item->get_id());
|
2574 |
$out[] = '<div id="' . $id . '_wrap" class=' . $this->add_prefix('attribute_wrap') . '>';
|
2575 |
-
//Build item layout
|
2576 |
$out[] = $item->build_layout();
|
2577 |
-
//end item output
|
2578 |
$out[] = '</div>';
|
2579 |
$item->clear_caller();
|
2580 |
}
|
2581 |
-
$out[] = '</div>'; //Close items container
|
2582 |
-
//Add description if exists
|
2583 |
if ( !empty($group->description) )
|
2584 |
$out[] = '<p class=' . $this->add_prefix('group_description') . '>' . $group->description . '</p>';
|
2585 |
}
|
2586 |
|
2587 |
-
//Return group output
|
2588 |
return implode($out);
|
2589 |
}
|
2590 |
}
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
/**
|
3 |
* Collection of default system-wide fields
|
4 |
* @package Simple Lightbox
|
24 |
|
25 |
protected function _hooks() {
|
26 |
parent::_hooks();
|
27 |
+
// Init fields
|
28 |
add_action('init', $this->m('register_types'));
|
29 |
+
// Init placeholders
|
30 |
add_action('init', $this->m('register_placeholders'));
|
31 |
}
|
32 |
|
38 |
function register_types() {
|
39 |
/* Field Types */
|
40 |
|
41 |
+
// Base
|
42 |
$base = new SLB_Field_Type('base');
|
43 |
$base->set_description(__('Default Element', 'simple-lightbox'));
|
44 |
$base->set_property('tag', 'span');
|
49 |
$base->set_layout('display', '{data context="display"}');
|
50 |
$this->add($base);
|
51 |
|
52 |
+
// Base closed
|
53 |
$base_closed = new SLB_Field_Type('base_closed');
|
54 |
$base_closed->set_parent('base');
|
55 |
$base_closed->set_description(__('Default Element (Closed Tag)', 'simple-lightbox'));
|
58 |
$base_closed->set_layout('form', '{form_start ref_base="layout"}{data}{form_end ref_base="layout"}');
|
59 |
$this->add($base_closed);
|
60 |
|
61 |
+
// Input
|
62 |
$input = new SLB_Field_Type('input', 'base');
|
63 |
$input->set_description(__('Default Input Element', 'simple-lightbox'));
|
64 |
$input->set_property('tag', 'input');
|
66 |
$input->set_property('value', '{data}', 'attr');
|
67 |
$this->add($input);
|
68 |
|
69 |
+
// Text input
|
70 |
$text = new SLB_Field_Type('text', 'input');
|
71 |
$text->set_description(__('Text Box', 'simple-lightbox'));
|
72 |
$text->set_property('size', 15, 'attr');
|
74 |
$text->set_layout('form', '{label ref_base="layout"} {inherit}');
|
75 |
$this->add($text);
|
76 |
|
77 |
+
// Checkbox
|
78 |
$cb = new SLB_Field_Type('checkbox', 'input');
|
79 |
$cb->set_property('type', 'checkbox');
|
80 |
$cb->set_property('value', null);
|
82 |
$cb->set_layout('form', '{label ref_base="layout"} <{form_attr ref_base="layout"} />');
|
83 |
$this->add($cb);
|
84 |
|
85 |
+
// Textarea
|
86 |
$ta = new SLB_Field_Type('textarea', 'base_closed');
|
87 |
$ta->set_property('tag', 'textarea');
|
88 |
$ta->set_property('cols', 40, 'attr');
|
89 |
$ta->set_property('rows', 3, 'attr');
|
90 |
$this->add($ta);
|
91 |
|
92 |
+
// Rich Text
|
93 |
$rt = new SLB_Field_Type('richtext', 'textarea');
|
94 |
$rt->set_property('class', 'theEditor {inherit}');
|
95 |
$rt->set_layout('form', '<div class="rt_container">{inherit}</div>');
|
96 |
$rt->add_action('admin_print_footer_scripts', 'wp_tiny_mce', 25);
|
97 |
$this->add($rt);
|
98 |
|
99 |
+
// Hidden
|
100 |
$hidden = new SLB_Field_Type('hidden');
|
101 |
$hidden->set_parent('input');
|
102 |
$hidden->set_description(__('Hidden Field', 'simple-lightbox'));
|
103 |
$hidden->set_property('type', 'hidden');
|
104 |
$this->add($hidden);
|
105 |
|
106 |
+
// Select
|
107 |
$select = new SLB_Field_Type('select', 'base_closed');
|
108 |
$select->set_description(__('Select tag', 'simple-lightbox'));
|
109 |
$select->set_property('tag', 'select');
|
115 |
$select->set_layout('option_data', '<{tag_option} value="{data_ext id="option_value"}" selected="selected">{data_ext id="option_text"}</{tag_option}>');
|
116 |
$this->add($select);
|
117 |
|
118 |
+
// Span
|
119 |
$span = new SLB_Field_Type('span', 'base_closed');
|
120 |
$span->set_description(__('Inline wrapper', 'simple-lightbox'));
|
121 |
$span->set_property('tag', 'span');
|
122 |
$span->set_property('value', 'Hello there!');
|
123 |
$this->add($span);
|
124 |
|
125 |
+
// Enable plugins to modify (add, remove, etc.) field types
|
126 |
+
$this->util->do_action_ref_array('register_fields', array($this), false);
|
127 |
|
128 |
+
// Signal completion of field registration
|
129 |
+
$this->util->do_action_ref_array('fields_registered', array($this), false);
|
130 |
}
|
131 |
|
132 |
/* Placeholder handlers */
|
133 |
|
134 |
function register_placeholders() {
|
135 |
+
// Default placeholder handlers
|
136 |
$this->register_placeholder('all', $this->m('process_placeholder_default'), 11);
|
137 |
$this->register_placeholder('field_id', $this->m('process_placeholder_id'));
|
138 |
$this->register_placeholder('field_name', $this->m('process_placeholder_name'));
|
142 |
$this->register_placeholder('label', $this->m('process_placeholder_label'));
|
143 |
$this->register_placeholder('checked', $this->m('process_placeholder_checked'));
|
144 |
|
145 |
+
// Allow other code to register placeholders
|
146 |
+
$this->util->do_action_ref_array('register_field_placeholders', array($this), false);
|
147 |
|
148 |
+
// Signal completion of field placeholder registration
|
149 |
+
$this->util->do_action_ref_array('field_placeholders_registered', array($this), false);
|
150 |
}
|
151 |
|
152 |
/**
|
181 |
* @return string Value to use in place of current placeholder
|
182 |
*/
|
183 |
function process_placeholder_default($output, $item, $placeholder, $layout, $data) {
|
184 |
+
// Validate parameters before processing
|
185 |
+
if ( empty($output) && ($item instanceof SLB_Field_Type) && is_array($placeholder) ) {
|
186 |
+
// Build path to replacement data
|
187 |
$output = $item->get_member_value($placeholder);
|
188 |
|
189 |
+
// Check if value is group (properties, etc.)
|
190 |
+
// All groups must have additional attributes (beyond reserved attributes) that define how items in group are used
|
191 |
if (is_array($output)
|
192 |
&& !empty($placeholder['attributes'])
|
193 |
&& is_array($placeholder['attributes'])
|
196 |
) {
|
197 |
/* Targeted property is an array, but the placeholder contains additional options on how property is to be used */
|
198 |
|
199 |
+
// Find items matching criteria in $output
|
200 |
+
// Check for group criteria
|
201 |
if ( 'properties' == $placeholder['tag'] && ($prop_group = $item->get_group($placeholder['attributes']['group'])) && !empty($prop_group) ) {
|
202 |
/* Process group */
|
203 |
$group_out = array();
|
204 |
+
// Iterate through properties in group and build string
|
205 |
foreach ( array_keys($prop_group) as $prop_key ) {
|
206 |
$prop_val = $item->get_property($prop_key);
|
207 |
if ( !is_null($prop_val) )
|
209 |
}
|
210 |
$output = implode(' ', $group_out);
|
211 |
}
|
212 |
+
} elseif ( is_object($output) && ($output instanceof $item->base_class) ) {
|
213 |
/* Targeted property is actually a nested item */
|
214 |
+
// Set caller to current item
|
215 |
$output->set_caller($item);
|
216 |
+
// Build layout for nested element
|
217 |
$output = $output->build_layout($layout);
|
218 |
}
|
219 |
}
|
227 |
* @return string Placeholder output
|
228 |
*/
|
229 |
function process_placeholder_id($output, $item, $placeholder, $layout, $data) {
|
230 |
+
// Get attributes
|
231 |
$args = wp_parse_args($placeholder['attributes'], array('format' => 'attr_id'));
|
232 |
return $item->get_id($args);
|
233 |
}
|
239 |
* @return string Placeholder output
|
240 |
*/
|
241 |
function process_placeholder_name($output, $item, $placeholder, $layout, $data) {
|
242 |
+
// Get attributes
|
243 |
$args = wp_parse_args($placeholder['attributes'], array('format' => 'attr_name'));
|
244 |
return $item->get_id($args);
|
245 |
}
|
250 |
* @return string Field label
|
251 |
*/
|
252 |
function process_placeholder_label($output, $item, $placeholder, $layout, $data) {
|
253 |
+
// Check if item has label property (e.g. sub-elements)
|
254 |
$out = $item->get_property('label');
|
255 |
+
// If property not set, use item title
|
256 |
if ( empty($out) )
|
257 |
$out = $item->get_title();
|
258 |
return $out;
|
268 |
'context' => '',
|
269 |
);
|
270 |
$opts = wp_parse_args($placeholder['attributes'], $attr_default);
|
271 |
+
// Save context to separate variable
|
272 |
$context = $opts['context'];
|
273 |
unset($opts['context']);
|
274 |
+
// Get data
|
275 |
$out = $item->get_data($opts);
|
276 |
if ( !is_null($out) ) {
|
277 |
+
// Get specific member in value (e.g. value from a specific item element)
|
278 |
if ( isset($opts['element']) && is_array($out) && ( $el = $opts['element'] ) && isset($out[$el]) )
|
279 |
$out = $out[$el];
|
280 |
}
|
281 |
|
282 |
+
// Format data based on context
|
283 |
$out = $item->preserve_special_chars($out, $context);
|
284 |
$out = $item->format($out, $context);
|
285 |
+
// Return data
|
286 |
return $out;
|
287 |
}
|
288 |
|
313 |
* @return string Placeholder output
|
314 |
*/
|
315 |
function process_placeholder_loop($output, $item, $placeholder, $layout, $data) {
|
316 |
+
// Setup loop options
|
317 |
$attr_defaults = array (
|
318 |
'layout' => '',
|
319 |
'layout_data' => null,
|
322 |
$attr = wp_parse_args($placeholder['attributes'], $attr_defaults);
|
323 |
if ( is_null($attr['layout_data']) )
|
324 |
$attr['layout_data'] =& $attr['layout'];
|
325 |
+
// Get data for loop
|
326 |
$path = explode('.', $attr['data']);
|
327 |
$loop_data = $item->get_member_value($path);
|
328 |
|
329 |
+
// Check if data is callback
|
330 |
if ( is_callable($loop_data) )
|
331 |
$loop_data = call_user_func($loop_data);
|
332 |
|
333 |
+
// Get item data
|
334 |
$data = $item->get_data();
|
335 |
|
336 |
+
// Iterate over data and build output
|
337 |
$out = array();
|
338 |
if ( is_array($loop_data) && !empty($loop_data) ) {
|
339 |
foreach ( $loop_data as $value => $label ) {
|
340 |
+
// Load appropriate layout based on item value
|
341 |
$layout = ( ($data === 0 && $value === $data) xor $data == $value ) ? $attr['layout_data'] : $attr['layout'];
|
342 |
+
// Stop processing if no valid layout is returned
|
343 |
if ( empty($layout) )
|
344 |
continue;
|
345 |
+
// Prep extended item data
|
346 |
$data_ext = array('option_value' => $value, 'option_text' => $label);
|
347 |
$out[] = $item->build_layout($layout, $data_ext);
|
348 |
}
|
349 |
}
|
350 |
|
351 |
+
// Return output
|
352 |
return implode($out);
|
353 |
}
|
354 |
|
381 |
'elements' => 'has_elements'
|
382 |
);
|
383 |
|
384 |
+
// Stop execution if group does not exist
|
385 |
if ( $this->group_exists($group) && $group =& $this->get_group($group) ) {
|
386 |
$group_items = ( count($group->items) > 1 ) ? $classnames->multi : $classnames->single . ( ( ( $fs = array_keys($group->items) ) && ( $f =& $group->items[$fs[0]] ) && ( $els = $f->get_member_value('elements', '', null) ) && !empty($els) ) ? '_' . $classnames->elements : '' );
|
387 |
$classname = array($this->add_prefix('attributes_wrap'), $group_items);
|
388 |
+
$out[] = '<div class="' . implode(' ', $classname) . '">'; // Wrap all items in group
|
389 |
|
390 |
+
// Build layout for each item in group
|
391 |
foreach ( array_keys($group->items) as $item_id ) {
|
392 |
$item =& $group->items[$item_id];
|
393 |
$item->set_caller($this);
|
394 |
+
// Start item output
|
395 |
$id = $this->add_prefix('field_' . $item->get_id());
|
396 |
$out[] = '<div id="' . $id . '_wrap" class=' . $this->add_prefix('attribute_wrap') . '>';
|
397 |
+
// Build item layout
|
398 |
$out[] = $item->build_layout();
|
399 |
+
// end item output
|
400 |
$out[] = '</div>';
|
401 |
$item->clear_caller();
|
402 |
}
|
403 |
+
$out[] = '</div>'; // Close items container
|
404 |
+
// Add description if exists
|
405 |
if ( !empty($group->description) )
|
406 |
$out[] = '<p class=' . $this->add_prefix('group_description') . '>' . $group->description . '</p>';
|
407 |
}
|
408 |
|
409 |
+
// Return group output
|
410 |
return implode($out);
|
411 |
}
|
412 |
}
|
includes/class.option.php
ADDED
@@ -0,0 +1,179 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Option object
|
4 |
+
* @package Simple Lightbox
|
5 |
+
* @subpackage Options
|
6 |
+
* @author Archetyped
|
7 |
+
*/
|
8 |
+
class SLB_Option extends SLB_Field {
|
9 |
+
|
10 |
+
/* Properties */
|
11 |
+
|
12 |
+
public $hook_prefix = 'option';
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Determines whether option will be sent to client
|
16 |
+
* @var bool
|
17 |
+
*/
|
18 |
+
var $in_client = false;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Child mapping
|
22 |
+
* @see SLB_Field_Base::map
|
23 |
+
* @var array
|
24 |
+
*/
|
25 |
+
var $map = array (
|
26 |
+
'default' => 'data',
|
27 |
+
'attr' => 'properties'
|
28 |
+
);
|
29 |
+
|
30 |
+
var $property_priority = array ('id', 'data', 'parent');
|
31 |
+
|
32 |
+
/* Init */
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @see SLB_Field::__construct()
|
36 |
+
* @uses parent::__construct() to initialize instance
|
37 |
+
* @param $id
|
38 |
+
* @param $title
|
39 |
+
* @param $default
|
40 |
+
*/
|
41 |
+
function __construct($id, $title = '', $default = '') {
|
42 |
+
// Normalize properties
|
43 |
+
$args = func_get_args();
|
44 |
+
$defaults = array ('title' => '', 'default' => '');
|
45 |
+
$props = $this->make_properties($args, $defaults);
|
46 |
+
// Validate
|
47 |
+
if ( is_scalar($id) )
|
48 |
+
$props['id'] = $id;
|
49 |
+
if ( !is_string($props['title']) )
|
50 |
+
$props['title'] = '';
|
51 |
+
// Send to parent constructor
|
52 |
+
parent::__construct($props);
|
53 |
+
}
|
54 |
+
|
55 |
+
/* Getters/Setters */
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Retrieve default value for option
|
59 |
+
* @return mixed Default option value
|
60 |
+
*/
|
61 |
+
function get_default($context = '') {
|
62 |
+
return $this->get_data($context, false);
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Sets parent based on default value
|
67 |
+
*/
|
68 |
+
function set_parent($parent = null) {
|
69 |
+
$p = $this->get_parent();
|
70 |
+
if ( empty($parent) && empty($p) ) {
|
71 |
+
$parent = 'text';
|
72 |
+
$d = $this->get_default();
|
73 |
+
if ( is_bool($d) )
|
74 |
+
$parent = 'checkbox';
|
75 |
+
$parent = 'option_' . $parent;
|
76 |
+
} elseif ( !empty($p) && !is_object($p) ) {
|
77 |
+
$parent =& $p;
|
78 |
+
}
|
79 |
+
parent::set_parent($parent);
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Set in_client property
|
84 |
+
* @uses this::in_client
|
85 |
+
* @param bool Whether or not option should be included in client output (Default: false)
|
86 |
+
* @return void
|
87 |
+
*/
|
88 |
+
function set_in_client($in_client = false) {
|
89 |
+
$this->in_client = !!$in_client;
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Determines whether option should be included in client output
|
94 |
+
* @uses this::in_client
|
95 |
+
* @return bool TRUE if option is included in client output
|
96 |
+
*/
|
97 |
+
function get_in_client() {
|
98 |
+
return $this->in_client;
|
99 |
+
}
|
100 |
+
|
101 |
+
/* Formatting */
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Format data as string for browser output
|
105 |
+
* @see SLB_Field_Base::format()
|
106 |
+
* @param mixed $value Data to format
|
107 |
+
* @param string $context (optional) Current context
|
108 |
+
* @return string Formatted value
|
109 |
+
*/
|
110 |
+
function format_display($value, $context = '') {
|
111 |
+
if ( !is_string($value) ) {
|
112 |
+
if ( is_bool($value) ) {
|
113 |
+
$value = ( $value ) ? __('Enabled', 'simple-lightbox') : __('Disabled', 'simple-lightbox');
|
114 |
+
}
|
115 |
+
elseif ( is_null($value) )
|
116 |
+
$value = '';
|
117 |
+
else
|
118 |
+
$value = strval($value);
|
119 |
+
} elseif ( empty($value) ) {
|
120 |
+
$value = 'empty';
|
121 |
+
}
|
122 |
+
return htmlentities($value);
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Format data using same format as default value
|
127 |
+
* @see SLB_Field_Base::format()
|
128 |
+
* @param mixed $value Data to format
|
129 |
+
* @param string $context (optional) Current context
|
130 |
+
* @return mixed Formatted option value
|
131 |
+
*/
|
132 |
+
function format_default($value, $context = '') {
|
133 |
+
// Get default value
|
134 |
+
$d = $this->get_default();
|
135 |
+
if ( empty($d) )
|
136 |
+
return $value;
|
137 |
+
if ( is_bool($d) )
|
138 |
+
$value = $this->format_bool($value);
|
139 |
+
elseif ( is_string($d) )
|
140 |
+
$value = $this->format_string($value);
|
141 |
+
return $value;
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* Format data as boolean (true/false)
|
146 |
+
* @see SLB_Field_Base::format()
|
147 |
+
* @param mixed $value Data to format
|
148 |
+
* @param string $context (optional) Current context
|
149 |
+
* @return bool Option value
|
150 |
+
*/
|
151 |
+
function format_bool($value, $context = '') {
|
152 |
+
if ( !is_bool($value) )
|
153 |
+
$value = !!$value;
|
154 |
+
return $value;
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Format data as string
|
159 |
+
* @see SLB_Field_Base::format()
|
160 |
+
* @param mixed $value Data to format
|
161 |
+
* @param string $context (optional) Current context
|
162 |
+
* @return string Option string value
|
163 |
+
*/
|
164 |
+
function format_string($value, $context = '') {
|
165 |
+
if ( is_bool($value) ) {
|
166 |
+
$value = ( $value ) ? 'true' : 'false';
|
167 |
+
}
|
168 |
+
elseif ( is_object($value) ) {
|
169 |
+
$value = get_class($value);
|
170 |
+
}
|
171 |
+
elseif ( is_array($value) ) {
|
172 |
+
$value = implode(' ', $value);
|
173 |
+
}
|
174 |
+
else {
|
175 |
+
$value = strval($value);
|
176 |
+
}
|
177 |
+
return $value;
|
178 |
+
}
|
179 |
+
}
|
includes/class.options.php
CHANGED
@@ -1,184 +1,4 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Option object
|
5 |
-
* @package Simple Lightbox
|
6 |
-
* @subpackage Options
|
7 |
-
* @author Archetyped
|
8 |
-
*/
|
9 |
-
class SLB_Option extends SLB_Field {
|
10 |
-
|
11 |
-
/* Properties */
|
12 |
-
|
13 |
-
public $hook_prefix = 'option';
|
14 |
-
|
15 |
-
/**
|
16 |
-
* Determines whether option will be sent to client
|
17 |
-
* @var bool
|
18 |
-
*/
|
19 |
-
var $in_client = false;
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Child mapping
|
23 |
-
* @see SLB_Field_Base::map
|
24 |
-
* @var array
|
25 |
-
*/
|
26 |
-
var $map = array (
|
27 |
-
'default' => 'data',
|
28 |
-
'attr' => 'properties'
|
29 |
-
);
|
30 |
-
|
31 |
-
var $property_priority = array ('id', 'data', 'parent');
|
32 |
-
|
33 |
-
/* Init */
|
34 |
-
|
35 |
-
/**
|
36 |
-
* @see SLB_Field::__construct()
|
37 |
-
* @uses parent::__construct() to initialize instance
|
38 |
-
* @param $id
|
39 |
-
* @param $title
|
40 |
-
* @param $default
|
41 |
-
*/
|
42 |
-
function __construct($id, $title = '', $default = '') {
|
43 |
-
//Normalize properties
|
44 |
-
$args = func_get_args();
|
45 |
-
$defaults = array ('title' => '', 'default' => '');
|
46 |
-
$props = $this->make_properties($args, $defaults);
|
47 |
-
//Validate
|
48 |
-
if ( is_scalar($id) )
|
49 |
-
$props['id'] = $id;
|
50 |
-
if ( !is_string($props['title']) )
|
51 |
-
$props['title'] = '';
|
52 |
-
//Send to parent constructor
|
53 |
-
parent::__construct($props);
|
54 |
-
}
|
55 |
-
|
56 |
-
/* Getters/Setters */
|
57 |
-
|
58 |
-
/**
|
59 |
-
* Retrieve default value for option
|
60 |
-
* @return mixed Default option value
|
61 |
-
*/
|
62 |
-
function get_default($context = '') {
|
63 |
-
return $this->get_data($context, false);
|
64 |
-
}
|
65 |
-
|
66 |
-
/**
|
67 |
-
* Sets parent based on default value
|
68 |
-
*/
|
69 |
-
function set_parent($parent = null) {
|
70 |
-
$p =& $this->get_parent();
|
71 |
-
if ( empty($parent) && empty($p) ) {
|
72 |
-
$parent = 'text';
|
73 |
-
$d = $this->get_default();
|
74 |
-
if ( is_bool($d) )
|
75 |
-
$parent = 'checkbox';
|
76 |
-
$parent = 'option_' . $parent;
|
77 |
-
} elseif ( !empty($p) && !is_object($p) ) {
|
78 |
-
$parent =& $p;
|
79 |
-
}
|
80 |
-
parent::set_parent($parent);
|
81 |
-
}
|
82 |
-
|
83 |
-
/**
|
84 |
-
* Set in_client property
|
85 |
-
* @uses this::in_client
|
86 |
-
* @param bool Whether or not option should be included in client output (Default: false)
|
87 |
-
* @return void
|
88 |
-
*/
|
89 |
-
function set_in_client($in_client = false) {
|
90 |
-
$this->in_client = !!$in_client;
|
91 |
-
}
|
92 |
-
|
93 |
-
/**
|
94 |
-
* Determines whether option should be included in client output
|
95 |
-
* @uses this::in_client
|
96 |
-
* @return bool TRUE if option is included in client output
|
97 |
-
*/
|
98 |
-
function get_in_client() {
|
99 |
-
return $this->in_client;
|
100 |
-
}
|
101 |
-
|
102 |
-
/* Formatting */
|
103 |
-
|
104 |
-
/**
|
105 |
-
* Format data as string for browser output
|
106 |
-
* @see SLB_Field_Base::format()
|
107 |
-
* @param mixed $value Data to format
|
108 |
-
* @param string $context (optional) Current context
|
109 |
-
* @return string Formatted value
|
110 |
-
*/
|
111 |
-
function format_display($value, $context = '') {
|
112 |
-
if ( !is_string($value) ) {
|
113 |
-
if ( is_bool($value) ) {
|
114 |
-
$value = ( $value ) ? __('Enabled', 'simple-lightbox') : __('Disabled', 'simple-lightbox');
|
115 |
-
}
|
116 |
-
elseif ( is_null($value) )
|
117 |
-
$value = '';
|
118 |
-
else
|
119 |
-
$value = strval($value);
|
120 |
-
} elseif ( empty($value) ) {
|
121 |
-
$value = 'empty';
|
122 |
-
}
|
123 |
-
return htmlentities($value);
|
124 |
-
}
|
125 |
-
|
126 |
-
/**
|
127 |
-
* Format data using same format as default value
|
128 |
-
* @see SLB_Field_Base::format()
|
129 |
-
* @param mixed $value Data to format
|
130 |
-
* @param string $context (optional) Current context
|
131 |
-
* @return mixed Formatted option value
|
132 |
-
*/
|
133 |
-
function format_default($value, $context = '') {
|
134 |
-
//Get default value
|
135 |
-
$d = $this->get_default();
|
136 |
-
if ( empty($d) )
|
137 |
-
return $value;
|
138 |
-
if ( is_bool($d) )
|
139 |
-
$value = $this->format_bool($value);
|
140 |
-
elseif ( is_string($d) )
|
141 |
-
$value = $this->format_string($value);
|
142 |
-
return $value;
|
143 |
-
}
|
144 |
-
|
145 |
-
/**
|
146 |
-
* Format data as boolean (true/false)
|
147 |
-
* @see SLB_Field_Base::format()
|
148 |
-
* @param mixed $value Data to format
|
149 |
-
* @param string $context (optional) Current context
|
150 |
-
* @return bool Option value
|
151 |
-
*/
|
152 |
-
function format_bool($value, $context = '') {
|
153 |
-
if ( !is_bool($value) )
|
154 |
-
$value = !!$value;
|
155 |
-
return $value;
|
156 |
-
}
|
157 |
-
|
158 |
-
/**
|
159 |
-
* Format data as string
|
160 |
-
* @see SLB_Field_Base::format()
|
161 |
-
* @param mixed $value Data to format
|
162 |
-
* @param string $context (optional) Current context
|
163 |
-
* @return string Option string value
|
164 |
-
*/
|
165 |
-
function format_string($value, $context = '') {
|
166 |
-
if ( is_bool($value) ) {
|
167 |
-
$value = ( $value ) ? 'true' : 'false';
|
168 |
-
}
|
169 |
-
elseif ( is_object($value) ) {
|
170 |
-
$value = get_class($value);
|
171 |
-
}
|
172 |
-
elseif ( is_array($value) ) {
|
173 |
-
$value = implode(' ', $value);
|
174 |
-
}
|
175 |
-
else {
|
176 |
-
$value = strval($value);
|
177 |
-
}
|
178 |
-
return $value;
|
179 |
-
}
|
180 |
-
}
|
181 |
-
|
182 |
/**
|
183 |
* Options collection
|
184 |
* @package Simple Lightbox
|
@@ -218,9 +38,9 @@ class SLB_Options extends SLB_Field_Collection {
|
|
218 |
/* Init */
|
219 |
|
220 |
function __construct($id = '', $props = array()) {
|
221 |
-
//Validate arguments
|
222 |
$args = func_get_args();
|
223 |
-
//Set default ID
|
224 |
if ( !$this->validate_id($id) ) {
|
225 |
$id = 'options';
|
226 |
}
|
@@ -232,12 +52,15 @@ class SLB_Options extends SLB_Field_Collection {
|
|
232 |
|
233 |
protected function _hooks() {
|
234 |
parent::_hooks();
|
235 |
-
//Register fields
|
236 |
-
|
237 |
-
//Set option parents
|
238 |
-
|
239 |
-
//Building
|
240 |
$this->util->add_action('build_init', $this->m('build_init'));
|
|
|
|
|
|
|
241 |
}
|
242 |
|
243 |
/* Legacy/Migration */
|
@@ -253,21 +76,21 @@ class SLB_Options extends SLB_Field_Collection {
|
|
253 |
if ( !$this->version_checked ) {
|
254 |
$this->version_checked = true;
|
255 |
$version_changed = false;
|
256 |
-
//Get version from DB
|
257 |
$vo = $this->get_version();
|
258 |
-
//Get current version
|
259 |
$vn = $this->util->get_plugin_version();
|
260 |
-
//Compare versions
|
261 |
if ( $vo != $vn ) {
|
262 |
-
//Update saved version
|
263 |
$this->set_version($vn);
|
264 |
-
//Migrate old version to new version
|
265 |
if ( strcasecmp($vo, $vn) < 0 ) {
|
266 |
-
//Force full migration
|
267 |
$version_changed = true;
|
268 |
}
|
269 |
}
|
270 |
-
//Migrate
|
271 |
$this->migrate($version_changed);
|
272 |
}
|
273 |
|
@@ -306,30 +129,30 @@ class SLB_Options extends SLB_Field_Collection {
|
|
306 |
if ( !$full && $this->items_migrated )
|
307 |
return false;
|
308 |
|
309 |
-
//Legacy options
|
310 |
$d = null;
|
311 |
$this->load_data();
|
312 |
|
313 |
-
$items
|
314 |
|
315 |
-
//Migrate separate options to unified option
|
316 |
if ( $full ) {
|
317 |
foreach ( $items as $opt => $props ) {
|
318 |
$oid = $this->add_prefix($opt);
|
319 |
$o = get_option($oid, $d);
|
320 |
if ( $o !== $d ) {
|
321 |
-
//Migrate value to data array
|
322 |
$this->set_data($opt, $o, false);
|
323 |
-
//Delete legacy option
|
324 |
delete_option($oid);
|
325 |
}
|
326 |
}
|
327 |
}
|
328 |
|
329 |
-
//Migrate legacy items
|
330 |
if ( is_array($this->properties_init) && isset($this->properties_init['legacy']) && is_array($this->properties_init['legacy']) ) {
|
331 |
$l =& $this->properties_init['legacy'];
|
332 |
-
//Normalize legacy map
|
333 |
foreach ( $l as $opt => $dest ) {
|
334 |
if ( !is_array($dest) ) {
|
335 |
if ( is_string($dest) )
|
@@ -344,37 +167,37 @@ class SLB_Options extends SLB_Field_Collection {
|
|
344 |
foreach ( $l as $opt => $dest ) {
|
345 |
$oid = $this->add_prefix($opt);
|
346 |
$o = get_option($oid, $d);
|
347 |
-
//Only migrate valid values
|
348 |
if ( $o !== $d ) {
|
349 |
-
//Process destinations
|
350 |
foreach ( $dest as $id ) {
|
351 |
$this->set_data($id, $o, false, true);
|
352 |
}
|
353 |
}
|
354 |
-
//Remove legacy option
|
355 |
delete_option($oid);
|
356 |
}
|
357 |
}
|
358 |
|
359 |
/* Simple Migration (Internal options only) */
|
360 |
|
361 |
-
//Get existing items that are also legacy items
|
362 |
$opts = array_intersect_key($this->get_data(), $l);
|
363 |
foreach ( $opts as $opt => $val ) {
|
364 |
$d = $this->get_data($opt);
|
365 |
-
//Migrate data from old option to new option
|
366 |
$dest = $l[$opt];
|
367 |
-
//Validate new options to send data to
|
368 |
foreach ( $dest as $id ) {
|
369 |
$this->set_data($id, $d, false, true);
|
370 |
}
|
371 |
-
//Remove legacy option
|
372 |
$this->remove($opt, false);
|
373 |
}
|
374 |
}
|
375 |
-
//Save changes
|
376 |
$this->save();
|
377 |
-
//Set flag
|
378 |
$this->items_migrated = true;
|
379 |
}
|
380 |
|
@@ -408,33 +231,41 @@ class SLB_Options extends SLB_Field_Collection {
|
|
408 |
* @param SLB_Fields $fields Reference to global fields object
|
409 |
* @return void
|
410 |
*/
|
411 |
-
function register_fields(
|
412 |
-
//Layouts
|
413 |
$o = $this->get_field_elements();
|
|
|
414 |
|
415 |
-
$form =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
416 |
|
417 |
-
//Text input
|
418 |
$otxt = new SLB_Field_Type('option_text', 'text');
|
419 |
$otxt->set_property('class', '{inherit} code');
|
420 |
$otxt->set_property('size', null);
|
421 |
$otxt->set_property('value', '{data context="form"}');
|
422 |
-
$otxt->set_layout('label', $
|
423 |
$otxt->set_layout('form', $form);
|
424 |
$fields->add($otxt);
|
425 |
|
426 |
-
//Checkbox
|
427 |
$ocb = new SLB_Field_Type('option_checkbox', 'checkbox');
|
428 |
-
$ocb->set_layout('label', $
|
429 |
$ocb->set_layout('form', $form);
|
430 |
$fields->add($ocb);
|
431 |
|
432 |
-
//Select
|
433 |
$othm = new SLB_Field_Type('option_select', 'select');
|
434 |
-
$othm->set_layout('label', $
|
435 |
-
$othm->set_layout('form_start', $
|
436 |
-
$othm->set_layout('form_end', '{inherit}' . $
|
437 |
-
$othm->set_layout('form', $
|
438 |
$fields->add($othm);
|
439 |
}
|
440 |
|
@@ -446,10 +277,10 @@ class SLB_Options extends SLB_Field_Collection {
|
|
446 |
* @param object $fields Collection of default field types
|
447 |
* @return void
|
448 |
*/
|
449 |
-
function set_parents(
|
450 |
if ( !is_admin() )
|
451 |
return false;
|
452 |
-
$items
|
453 |
foreach ( array_keys($items) as $opt ) {
|
454 |
$items[$opt]->set_parent();
|
455 |
}
|
@@ -470,41 +301,50 @@ class SLB_Options extends SLB_Field_Collection {
|
|
470 |
* @param array $values (optional) Option values
|
471 |
* @return array Full options data
|
472 |
*/
|
473 |
-
function validate($values = null
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
$force_save = true;
|
478 |
-
$values = $_REQUEST[$this->add_prefix('options')];
|
479 |
}
|
480 |
if ( is_array($values) ) {
|
481 |
-
//Format data based on option type (bool, string, etc.)
|
482 |
foreach ( $values as $id => $val ) {
|
483 |
-
//Get default
|
484 |
$d = $this->get_default($id);
|
485 |
if ( is_bool($d) && !empty($val) )
|
486 |
$values[$id] = true;
|
487 |
}
|
488 |
-
|
489 |
-
//
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
498 |
}
|
499 |
}
|
500 |
}
|
501 |
|
502 |
-
|
503 |
-
$this->set_data($values);
|
504 |
-
$values = $values_orig;
|
505 |
-
}
|
506 |
-
|
507 |
-
//Return value
|
508 |
return $values;
|
509 |
}
|
510 |
|
@@ -516,19 +356,16 @@ class SLB_Options extends SLB_Field_Collection {
|
|
516 |
* @return array Options data
|
517 |
*/
|
518 |
function fetch_data($sanitize = true) {
|
519 |
-
//Get data
|
520 |
$data = get_option($this->get_key(), null);
|
521 |
if ( $sanitize && is_array($data) ) {
|
522 |
-
//Sanitize loaded data based on default values
|
523 |
foreach ( $data as $id => $val ) {
|
524 |
if ( $this->has($id) ) {
|
525 |
$opt = $this->get($id);
|
526 |
if ( is_bool($opt->get_default()) )
|
527 |
$data[$id] = !!$val;
|
528 |
-
}
|
529 |
-
//Remove data that has no matching item
|
530 |
-
unset($data[$id]);
|
531 |
-
}*/
|
532 |
}
|
533 |
}
|
534 |
return $data;
|
@@ -540,10 +377,10 @@ class SLB_Options extends SLB_Field_Collection {
|
|
540 |
*/
|
541 |
function load_data() {
|
542 |
if ( !$this->data_loaded ) {
|
543 |
-
//Retrieve data
|
544 |
$this->data = $this->fetch_data();
|
545 |
$this->data_loaded = true;
|
546 |
-
//Check update
|
547 |
$this->check_update();
|
548 |
}
|
549 |
}
|
@@ -554,11 +391,11 @@ class SLB_Options extends SLB_Field_Collection {
|
|
554 |
*/
|
555 |
function reset($hard = true) {
|
556 |
$this->load_data();
|
557 |
-
//Reset data
|
558 |
if ( $hard ) {
|
559 |
$this->data = null;
|
560 |
}
|
561 |
-
//Save
|
562 |
$this->save();
|
563 |
}
|
564 |
|
@@ -603,9 +440,9 @@ class SLB_Options extends SLB_Field_Collection {
|
|
603 |
* @return SLB_Option Option instance
|
604 |
*/
|
605 |
function &add($id, $properties = array(), $update = false) {
|
606 |
-
//Create item
|
607 |
$args = func_get_args();
|
608 |
-
$ret
|
609 |
return $ret;
|
610 |
}
|
611 |
|
@@ -661,7 +498,7 @@ class SLB_Options extends SLB_Field_Collection {
|
|
661 |
* @return array Associative array of options
|
662 |
*/
|
663 |
function build_client_output() {
|
664 |
-
$items
|
665 |
$out = array();
|
666 |
foreach ( $items as $option ) {
|
667 |
if ( !$option->get_in_client() )
|
@@ -670,4 +507,135 @@ class SLB_Options extends SLB_Field_Collection {
|
|
670 |
}
|
671 |
return $out;
|
672 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
673 |
}
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
/**
|
3 |
* Options collection
|
4 |
* @package Simple Lightbox
|
38 |
/* Init */
|
39 |
|
40 |
function __construct($id = '', $props = array()) {
|
41 |
+
// Validate arguments
|
42 |
$args = func_get_args();
|
43 |
+
// Set default ID
|
44 |
if ( !$this->validate_id($id) ) {
|
45 |
$id = 'options';
|
46 |
}
|
52 |
|
53 |
protected function _hooks() {
|
54 |
parent::_hooks();
|
55 |
+
// Register fields
|
56 |
+
$this->util->add_action('register_fields', $this->m('register_fields'), 10, 1, false);
|
57 |
+
// Set option parents
|
58 |
+
$this->util->add_action('fields_registered', $this->m('set_parents'), 10, 1, false);
|
59 |
+
// Building
|
60 |
$this->util->add_action('build_init', $this->m('build_init'));
|
61 |
+
// Admin
|
62 |
+
$this->util->add_action('admin_page_render_content', $this->m('admin_page_render_content'), 10, 3, false);
|
63 |
+
$this->util->add_filter('admin_action_reset', $this->m('admin_action_reset'), 10, 3, false);
|
64 |
}
|
65 |
|
66 |
/* Legacy/Migration */
|
76 |
if ( !$this->version_checked ) {
|
77 |
$this->version_checked = true;
|
78 |
$version_changed = false;
|
79 |
+
// Get version from DB
|
80 |
$vo = $this->get_version();
|
81 |
+
// Get current version
|
82 |
$vn = $this->util->get_plugin_version();
|
83 |
+
// Compare versions
|
84 |
if ( $vo != $vn ) {
|
85 |
+
// Update saved version
|
86 |
$this->set_version($vn);
|
87 |
+
// Migrate old version to new version
|
88 |
if ( strcasecmp($vo, $vn) < 0 ) {
|
89 |
+
// Force full migration
|
90 |
$version_changed = true;
|
91 |
}
|
92 |
}
|
93 |
+
// Migrate
|
94 |
$this->migrate($version_changed);
|
95 |
}
|
96 |
|
129 |
if ( !$full && $this->items_migrated )
|
130 |
return false;
|
131 |
|
132 |
+
// Legacy options
|
133 |
$d = null;
|
134 |
$this->load_data();
|
135 |
|
136 |
+
$items = $this->get_items();
|
137 |
|
138 |
+
// Migrate separate options to unified option
|
139 |
if ( $full ) {
|
140 |
foreach ( $items as $opt => $props ) {
|
141 |
$oid = $this->add_prefix($opt);
|
142 |
$o = get_option($oid, $d);
|
143 |
if ( $o !== $d ) {
|
144 |
+
// Migrate value to data array
|
145 |
$this->set_data($opt, $o, false);
|
146 |
+
// Delete legacy option
|
147 |
delete_option($oid);
|
148 |
}
|
149 |
}
|
150 |
}
|
151 |
|
152 |
+
// Migrate legacy items
|
153 |
if ( is_array($this->properties_init) && isset($this->properties_init['legacy']) && is_array($this->properties_init['legacy']) ) {
|
154 |
$l =& $this->properties_init['legacy'];
|
155 |
+
// Normalize legacy map
|
156 |
foreach ( $l as $opt => $dest ) {
|
157 |
if ( !is_array($dest) ) {
|
158 |
if ( is_string($dest) )
|
167 |
foreach ( $l as $opt => $dest ) {
|
168 |
$oid = $this->add_prefix($opt);
|
169 |
$o = get_option($oid, $d);
|
170 |
+
// Only migrate valid values
|
171 |
if ( $o !== $d ) {
|
172 |
+
// Process destinations
|
173 |
foreach ( $dest as $id ) {
|
174 |
$this->set_data($id, $o, false, true);
|
175 |
}
|
176 |
}
|
177 |
+
// Remove legacy option
|
178 |
delete_option($oid);
|
179 |
}
|
180 |
}
|
181 |
|
182 |
/* Simple Migration (Internal options only) */
|
183 |
|
184 |
+
// Get existing items that are also legacy items
|
185 |
$opts = array_intersect_key($this->get_data(), $l);
|
186 |
foreach ( $opts as $opt => $val ) {
|
187 |
$d = $this->get_data($opt);
|
188 |
+
// Migrate data from old option to new option
|
189 |
$dest = $l[$opt];
|
190 |
+
// Validate new options to send data to
|
191 |
foreach ( $dest as $id ) {
|
192 |
$this->set_data($id, $d, false, true);
|
193 |
}
|
194 |
+
// Remove legacy option
|
195 |
$this->remove($opt, false);
|
196 |
}
|
197 |
}
|
198 |
+
// Save changes
|
199 |
$this->save();
|
200 |
+
// Set flag
|
201 |
$this->items_migrated = true;
|
202 |
}
|
203 |
|
231 |
* @param SLB_Fields $fields Reference to global fields object
|
232 |
* @return void
|
233 |
*/
|
234 |
+
function register_fields($fields) {
|
235 |
+
// Layouts
|
236 |
$o = $this->get_field_elements();
|
237 |
+
$l =& $o->layout;
|
238 |
|
239 |
+
$form = implode('', array (
|
240 |
+
$l->opt_pre,
|
241 |
+
$l->label_ref,
|
242 |
+
$l->field_pre,
|
243 |
+
$l->form,
|
244 |
+
$l->field_post,
|
245 |
+
$l->opt_post
|
246 |
+
));
|
247 |
|
248 |
+
// Text input
|
249 |
$otxt = new SLB_Field_Type('option_text', 'text');
|
250 |
$otxt->set_property('class', '{inherit} code');
|
251 |
$otxt->set_property('size', null);
|
252 |
$otxt->set_property('value', '{data context="form"}');
|
253 |
+
$otxt->set_layout('label', $l->label);
|
254 |
$otxt->set_layout('form', $form);
|
255 |
$fields->add($otxt);
|
256 |
|
257 |
+
// Checkbox
|
258 |
$ocb = new SLB_Field_Type('option_checkbox', 'checkbox');
|
259 |
+
$ocb->set_layout('label', $l->label);
|
260 |
$ocb->set_layout('form', $form);
|
261 |
$fields->add($ocb);
|
262 |
|
263 |
+
// Select
|
264 |
$othm = new SLB_Field_Type('option_select', 'select');
|
265 |
+
$othm->set_layout('label', $l->label);
|
266 |
+
$othm->set_layout('form_start', $l->field_pre . '{inherit}');
|
267 |
+
$othm->set_layout('form_end', '{inherit}' . $l->field_post);
|
268 |
+
$othm->set_layout('form', $l->opt_pre . '{inherit}' . $l->opt_post);
|
269 |
$fields->add($othm);
|
270 |
}
|
271 |
|
277 |
* @param object $fields Collection of default field types
|
278 |
* @return void
|
279 |
*/
|
280 |
+
function set_parents($fields) {
|
281 |
if ( !is_admin() )
|
282 |
return false;
|
283 |
+
$items = &$this->get_items();
|
284 |
foreach ( array_keys($items) as $opt ) {
|
285 |
$items[$opt]->set_parent();
|
286 |
}
|
301 |
* @param array $values (optional) Option values
|
302 |
* @return array Full options data
|
303 |
*/
|
304 |
+
function validate($values = null) {
|
305 |
+
$qvar = $this->get_id('formatted');
|
306 |
+
if ( empty($values) && isset($_REQUEST[$qvar]) ) {
|
307 |
+
$values = $_REQUEST[$qvar];
|
|
|
|
|
308 |
}
|
309 |
if ( is_array($values) ) {
|
310 |
+
// Format data based on option type (bool, string, etc.)
|
311 |
foreach ( $values as $id => $val ) {
|
312 |
+
// Get default
|
313 |
$d = $this->get_default($id);
|
314 |
if ( is_bool($d) && !empty($val) )
|
315 |
$values[$id] = true;
|
316 |
}
|
317 |
+
|
318 |
+
// Merge in additional options that are not in post data
|
319 |
+
// Missing options (e.g. disabled checkboxes, empty fields, etc.)
|
320 |
+
|
321 |
+
// Get groups that were output in request
|
322 |
+
$qvar_groups = $qvar . '_groups';
|
323 |
+
if ( isset($_REQUEST[$qvar_groups]) ) {
|
324 |
+
$groups = explode( ',', implode(',', $_REQUEST[$qvar_groups]) );
|
325 |
+
|
326 |
+
// Get group items
|
327 |
+
$items = array();
|
328 |
+
$items_temp = null;
|
329 |
+
foreach ( $groups as $gid ) {
|
330 |
+
$items_temp = $this->get_group_items($gid);
|
331 |
+
$items = array_merge($items, $items_temp);
|
332 |
+
}
|
333 |
+
unset($items_temp);
|
334 |
+
$items = call_user_func_array('array_merge', $items);
|
335 |
+
foreach ( $items as $id => $opt ) {
|
336 |
+
// Add options that were not included in form submission
|
337 |
+
if ( !array_key_exists($id, $values) ) {
|
338 |
+
if ( is_bool($opt->get_default()) )
|
339 |
+
$values[$id] = false;
|
340 |
+
else
|
341 |
+
$values[$id] = $opt->get_default();
|
342 |
+
}
|
343 |
}
|
344 |
}
|
345 |
}
|
346 |
|
347 |
+
// Return value
|
|
|
|
|
|
|
|
|
|
|
348 |
return $values;
|
349 |
}
|
350 |
|
356 |
* @return array Options data
|
357 |
*/
|
358 |
function fetch_data($sanitize = true) {
|
359 |
+
// Get data
|
360 |
$data = get_option($this->get_key(), null);
|
361 |
if ( $sanitize && is_array($data) ) {
|
362 |
+
// Sanitize loaded data based on default values
|
363 |
foreach ( $data as $id => $val ) {
|
364 |
if ( $this->has($id) ) {
|
365 |
$opt = $this->get($id);
|
366 |
if ( is_bool($opt->get_default()) )
|
367 |
$data[$id] = !!$val;
|
368 |
+
}
|
|
|
|
|
|
|
369 |
}
|
370 |
}
|
371 |
return $data;
|
377 |
*/
|
378 |
function load_data() {
|
379 |
if ( !$this->data_loaded ) {
|
380 |
+
// Retrieve data
|
381 |
$this->data = $this->fetch_data();
|
382 |
$this->data_loaded = true;
|
383 |
+
// Check update
|
384 |
$this->check_update();
|
385 |
}
|
386 |
}
|
391 |
*/
|
392 |
function reset($hard = true) {
|
393 |
$this->load_data();
|
394 |
+
// Reset data
|
395 |
if ( $hard ) {
|
396 |
$this->data = null;
|
397 |
}
|
398 |
+
// Save
|
399 |
$this->save();
|
400 |
}
|
401 |
|
440 |
* @return SLB_Option Option instance
|
441 |
*/
|
442 |
function &add($id, $properties = array(), $update = false) {
|
443 |
+
// Create item
|
444 |
$args = func_get_args();
|
445 |
+
$ret = call_user_func_array(array('parent', 'add'), $args);
|
446 |
return $ret;
|
447 |
}
|
448 |
|
498 |
* @return array Associative array of options
|
499 |
*/
|
500 |
function build_client_output() {
|
501 |
+
$items = $this->get_items();
|
502 |
$out = array();
|
503 |
foreach ( $items as $option ) {
|
504 |
if ( !$option->get_in_client() )
|
507 |
}
|
508 |
return $out;
|
509 |
}
|
510 |
+
|
511 |
+
/* Admin */
|
512 |
+
|
513 |
+
/**
|
514 |
+
* Handles output building for options on admin pages
|
515 |
+
* @param obj|array $opts Options instance or Array of options instance and groups to build
|
516 |
+
* @param obj $page Admin Page instance
|
517 |
+
* @param obj $state Admin Page state properties
|
518 |
+
*/
|
519 |
+
public function admin_page_render_content($opts, $page, $state) {
|
520 |
+
$groups = null;
|
521 |
+
if ( is_array($opts) && count($opts) == 2 ) {
|
522 |
+
$groups = $opts[1];
|
523 |
+
$opts = $opts[0];
|
524 |
+
}
|
525 |
+
if ( $opts === $this ) {
|
526 |
+
// Set build variables and callbacks
|
527 |
+
$this->set_build_var('admin_page', $page);
|
528 |
+
$this->set_build_var('admin_state', $state);
|
529 |
+
if ( !empty($groups) ) {
|
530 |
+
$this->set_build_var('groups', $groups);
|
531 |
+
}
|
532 |
+
$hooks = array (
|
533 |
+
'filter' => array (
|
534 |
+
'parse_build_vars' => array( $this->m('admin_parse_build_vars'), 10, 2 )
|
535 |
+
)
|
536 |
+
);
|
537 |
+
|
538 |
+
// Add hooks
|
539 |
+
foreach ( $hooks as $type => $hook ) {
|
540 |
+
$m = 'add_' . $type;
|
541 |
+
foreach ( $hook as $tag => $args ) {
|
542 |
+
array_unshift($args, $tag);
|
543 |
+
call_user_func_array($this->util->m($m), $args);
|
544 |
+
}
|
545 |
+
}
|
546 |
+
|
547 |
+
// Build output
|
548 |
+
$this->build(array('build_groups' => $this->m('admin_build_groups')));
|
549 |
+
|
550 |
+
// Remove hooks
|
551 |
+
foreach ( $hooks as $type => $hook ) {
|
552 |
+
$m = 'remove_' . $type;
|
553 |
+
foreach ( $hook as $tag => $args ) {
|
554 |
+
call_user_func($this->util->m($m), $tag, $args[0]);
|
555 |
+
}
|
556 |
+
}
|
557 |
+
// Clear custom build vars
|
558 |
+
$this->delete_build_var('admin_page');
|
559 |
+
$this->delete_build_var('admin_state');
|
560 |
+
}
|
561 |
+
}
|
562 |
+
|
563 |
+
/**
|
564 |
+
* Builds option groups output
|
565 |
+
*/
|
566 |
+
public function admin_build_groups() {
|
567 |
+
$page = $this->get_build_var('admin_page');
|
568 |
+
$state = $this->get_build_var('admin_state');
|
569 |
+
$groups = $this->get_build_var('groups');
|
570 |
+
|
571 |
+
// Get all groups
|
572 |
+
$groups_all = $this->get_groups();
|
573 |
+
$groups_built = array();
|
574 |
+
if ( empty($groups) ) {
|
575 |
+
$groups = array_keys($groups_all);
|
576 |
+
}
|
577 |
+
// Iterate through groups
|
578 |
+
foreach ( $groups as $gid ) {
|
579 |
+
// Validate
|
580 |
+
if ( !isset($groups_all[$gid]) || !count($this->get_items($gid)) ) {
|
581 |
+
continue;
|
582 |
+
}
|
583 |
+
// Add meta box for each group
|
584 |
+
$g = $groups_all[$gid];
|
585 |
+
add_meta_box($g->id, $g->title, $this->m('admin_build_group'), $state->screen, $state->context, $state->priority, array('group' => $g->id, 'page' => $page));
|
586 |
+
$groups_built[] = $gid;
|
587 |
+
}
|
588 |
+
|
589 |
+
// Define groups built
|
590 |
+
if ( !empty($groups_built) ) {
|
591 |
+
echo $this->util->build_html_element(array(
|
592 |
+
'tag' => 'input',
|
593 |
+
'attributes' => array (
|
594 |
+
'type' => 'hidden',
|
595 |
+
'value' => implode(',', $groups_built),
|
596 |
+
'name' => $this->get_id('formatted') . '_groups[]'
|
597 |
+
),
|
598 |
+
));
|
599 |
+
}
|
600 |
+
}
|
601 |
+
|
602 |
+
/**
|
603 |
+
* Group output handler for admin pages
|
604 |
+
* @param obj $obj Object passed by `do_meta_boxes()` call (Default: NULL)
|
605 |
+
* @param array $box Meta box properties
|
606 |
+
*/
|
607 |
+
public function admin_build_group($obj, $box) {
|
608 |
+
$a = $box['args'];
|
609 |
+
$group = $a['group'];
|
610 |
+
$this->build_group($group);
|
611 |
+
}
|
612 |
+
|
613 |
+
/**
|
614 |
+
* Parse build vars
|
615 |
+
* @uses `options_parse_build_vars` filter hook
|
616 |
+
*/
|
617 |
+
public function admin_parse_build_vars($vars, $opts) {
|
618 |
+
// Handle form submission
|
619 |
+
if ( isset($_REQUEST[$opts->get_id('formatted')]) ) {
|
620 |
+
$vars['validate_pre'] = $vars['save_pre'] = true;
|
621 |
+
}
|
622 |
+
return $vars;
|
623 |
+
}
|
624 |
+
|
625 |
+
/**
|
626 |
+
* Admin reset handler
|
627 |
+
* @param bool $res Current result
|
628 |
+
* @param obj $opts Options instance
|
629 |
+
* @param obj $reset Admin Reset instance
|
630 |
+
*/
|
631 |
+
public function admin_action_reset($res, $opts, $reset) {
|
632 |
+
// Only process matching options instance
|
633 |
+
if ( $opts === $this ) {
|
634 |
+
// Reset options
|
635 |
+
$this->reset();
|
636 |
+
// Set result
|
637 |
+
$res = true;
|
638 |
+
}
|
639 |
+
return $res;
|
640 |
+
}
|
641 |
}
|
includes/class.template_tags.php
CHANGED
@@ -13,10 +13,10 @@ class SLB_Template_Tags extends SLB_Collection_Controller {
|
|
13 |
|
14 |
public $hook_prefix = 'template_tags';
|
15 |
|
16 |
-
//Use tag ID as key
|
17 |
protected $key_prop = 'get_id';
|
18 |
|
19 |
-
//Call $key_prop is a method to be called
|
20 |
protected $key_call = true;
|
21 |
|
22 |
/* Properties */
|
@@ -32,8 +32,8 @@ class SLB_Template_Tags extends SLB_Collection_Controller {
|
|
32 |
protected function _hooks() {
|
33 |
parent::_hooks();
|
34 |
$this->util->add_action('init', $this->m('init_defaults'));
|
35 |
-
|
36 |
-
|
37 |
}
|
38 |
|
39 |
/* Collection Management */
|
@@ -48,7 +48,7 @@ class SLB_Template_Tags extends SLB_Collection_Controller {
|
|
48 |
*/
|
49 |
public function add($id, $props = array()) {
|
50 |
$o = ( is_string($id) ) ? new $this->item_type($id, $props) : $id;
|
51 |
-
//Add to collection
|
52 |
return parent::add($o);
|
53 |
}
|
54 |
|
@@ -59,12 +59,19 @@ class SLB_Template_Tags extends SLB_Collection_Controller {
|
|
59 |
* @param SLB_Template_Tags $tags Tags controller
|
60 |
*/
|
61 |
public function init_defaults($tags) {
|
|
|
|
|
|
|
62 |
$defaults = array (
|
63 |
'item' => array (
|
64 |
-
'
|
|
|
|
|
65 |
),
|
66 |
'ui' => array (
|
67 |
-
'
|
|
|
|
|
68 |
),
|
69 |
);
|
70 |
foreach ( $defaults as $id => $props ) {
|
@@ -75,27 +82,41 @@ class SLB_Template_Tags extends SLB_Collection_Controller {
|
|
75 |
/* Output */
|
76 |
|
77 |
/**
|
78 |
-
*
|
79 |
*/
|
80 |
public function client_output() {
|
81 |
-
//
|
82 |
-
|
83 |
-
|
84 |
}
|
85 |
-
|
86 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
$code = array();
|
88 |
-
|
89 |
-
foreach ( $this->get() as $
|
90 |
-
|
|
|
|
|
|
|
|
|
91 |
$params = array(
|
92 |
-
sprintf("'%s'", $
|
93 |
-
sprintf("'%s'", $tag->get_client_script('uri')),
|
94 |
);
|
95 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
}
|
97 |
-
|
98 |
-
$out[] = '<!-- /SLB-TPTG -->' . PHP_EOL;
|
99 |
-
echo implode('', $out);
|
100 |
}
|
101 |
}
|
13 |
|
14 |
public $hook_prefix = 'template_tags';
|
15 |
|
16 |
+
// Use tag ID as key
|
17 |
protected $key_prop = 'get_id';
|
18 |
|
19 |
+
// Call $key_prop is a method to be called
|
20 |
protected $key_call = true;
|
21 |
|
22 |
/* Properties */
|
32 |
protected function _hooks() {
|
33 |
parent::_hooks();
|
34 |
$this->util->add_action('init', $this->m('init_defaults'));
|
35 |
+
$this->util->add_action('footer', $this->m('client_output'), 1, 0, false);
|
36 |
+
$this->util->add_filter('footer_script', $this->m('client_output_script'), $this->util->priority('client_footer_output'), 1, false);
|
37 |
}
|
38 |
|
39 |
/* Collection Management */
|
48 |
*/
|
49 |
public function add($id, $props = array()) {
|
50 |
$o = ( is_string($id) ) ? new $this->item_type($id, $props) : $id;
|
51 |
+
// Add to collection
|
52 |
return parent::add($o);
|
53 |
}
|
54 |
|
59 |
* @param SLB_Template_Tags $tags Tags controller
|
60 |
*/
|
61 |
public function init_defaults($tags) {
|
62 |
+
$js_path = 'js/';
|
63 |
+
$js_path .= ( SLB_DEV ) ? 'dev' : 'prod';
|
64 |
+
$src_base = $this->util->get_file_url('template-tags', true);
|
65 |
$defaults = array (
|
66 |
'item' => array (
|
67 |
+
'scripts' => array (
|
68 |
+
array ( 'base', "$src_base/item/$js_path/tag.item.js" ),
|
69 |
+
)
|
70 |
),
|
71 |
'ui' => array (
|
72 |
+
'scripts' => array (
|
73 |
+
array ( 'base', "$src_base/ui/$js_path/tag.ui.js" ),
|
74 |
+
)
|
75 |
),
|
76 |
);
|
77 |
foreach ( $defaults as $id => $props ) {
|
82 |
/* Output */
|
83 |
|
84 |
/**
|
85 |
+
* Build client output
|
86 |
*/
|
87 |
public function client_output() {
|
88 |
+
// Load matched handlers
|
89 |
+
foreach ( $this->get() as $tag ) {
|
90 |
+
$tag->enqueue_scripts();
|
91 |
}
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Client output script
|
96 |
+
* @param array $commands Client script commands
|
97 |
+
* @return array Modified script commands
|
98 |
+
*/
|
99 |
+
public function client_output_script($commands) {
|
100 |
+
$out = array('/* TPLT */');
|
101 |
$code = array();
|
102 |
+
|
103 |
+
foreach ( $this->get() as $tag ) {
|
104 |
+
$styles = $tag->get_styles(array('uri_format'=>'full'));
|
105 |
+
if ( empty($styles) ) {
|
106 |
+
continue;
|
107 |
+
}
|
108 |
+
// Setup client parameters
|
109 |
$params = array(
|
110 |
+
sprintf("'%s'", $tag->get_id()),
|
|
|
111 |
);
|
112 |
+
$params[] = json_encode( array('styles' => array_values($styles)) );
|
113 |
+
// Extend handler in client
|
114 |
+
$code[] = $this->util->call_client_method('View.extend_template_tag_handler', $params, false);
|
115 |
+
}
|
116 |
+
if ( !empty($code) ) {
|
117 |
+
$out[] = implode('', $code);
|
118 |
+
$commands[] = implode(PHP_EOL, $out);
|
119 |
}
|
120 |
+
return $commands;
|
|
|
|
|
121 |
}
|
122 |
}
|
includes/class.theme.php
CHANGED
@@ -11,13 +11,20 @@ class SLB_Theme extends SLB_Component {
|
|
11 |
|
12 |
protected $props_required = array('name');
|
13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
/* Get/Set */
|
15 |
|
16 |
/**
|
17 |
* Retrieve theme's ancestors
|
|
|
18 |
* @return array Theme's ancestors (sorted by nearest to most distant ancestor)
|
19 |
*/
|
20 |
-
public function get_ancestors() {
|
21 |
$ret = array();
|
22 |
/**
|
23 |
* @var SLB_Theme
|
@@ -25,35 +32,34 @@ class SLB_Theme extends SLB_Component {
|
|
25 |
$thm = $this;
|
26 |
while ( $thm->has_parent() ) {
|
27 |
$par = $thm->get_parent();
|
28 |
-
//Add ancestor
|
29 |
if ( $par->is_valid() && !in_array($par, $ret, true) ) {
|
30 |
$ret[] = $par;
|
31 |
}
|
32 |
-
//Get next ancestor
|
33 |
$thm = $par;
|
34 |
}
|
|
|
|
|
|
|
|
|
35 |
return $ret;
|
36 |
}
|
37 |
|
38 |
-
/* Style */
|
39 |
-
|
40 |
/**
|
41 |
-
* Set
|
42 |
-
* @
|
43 |
*/
|
44 |
-
public function
|
45 |
-
|
46 |
-
list($src, $deps) = func_get_arg(0);
|
47 |
-
}
|
48 |
-
return $this->add_style('client', $src, $deps);
|
49 |
}
|
50 |
|
51 |
/**
|
52 |
-
* Get
|
53 |
-
* @
|
54 |
*/
|
55 |
-
public function
|
56 |
-
return
|
57 |
}
|
58 |
|
59 |
/* Templates */
|
11 |
|
12 |
protected $props_required = array('name');
|
13 |
|
14 |
+
/**
|
15 |
+
* Public flag
|
16 |
+
* @var bool
|
17 |
+
*/
|
18 |
+
protected $public = true;
|
19 |
+
|
20 |
/* Get/Set */
|
21 |
|
22 |
/**
|
23 |
* Retrieve theme's ancestors
|
24 |
+
* @param bool $sort_topdown (optional) Ancestor sorting (Default: Nearest to Farthest)
|
25 |
* @return array Theme's ancestors (sorted by nearest to most distant ancestor)
|
26 |
*/
|
27 |
+
public function get_ancestors($sort_topdown = false) {
|
28 |
$ret = array();
|
29 |
/**
|
30 |
* @var SLB_Theme
|
32 |
$thm = $this;
|
33 |
while ( $thm->has_parent() ) {
|
34 |
$par = $thm->get_parent();
|
35 |
+
// Add ancestor
|
36 |
if ( $par->is_valid() && !in_array($par, $ret, true) ) {
|
37 |
$ret[] = $par;
|
38 |
}
|
39 |
+
// Get next ancestor
|
40 |
$thm = $par;
|
41 |
}
|
42 |
+
// Sorting
|
43 |
+
if ( $sort_topdown ) {
|
44 |
+
$ret = array_reverse($ret);
|
45 |
+
}
|
46 |
return $ret;
|
47 |
}
|
48 |
|
|
|
|
|
49 |
/**
|
50 |
+
* Set public flag
|
51 |
+
* @param bool $public
|
52 |
*/
|
53 |
+
public function set_public($public) {
|
54 |
+
$this->public = !!$public;
|
|
|
|
|
|
|
55 |
}
|
56 |
|
57 |
/**
|
58 |
+
* Get privacy state
|
59 |
+
* @return bool
|
60 |
*/
|
61 |
+
public function get_public() {
|
62 |
+
return !!$this->public;
|
63 |
}
|
64 |
|
65 |
/* Templates */
|
includes/class.themes.php
CHANGED
@@ -25,11 +25,12 @@ class SLB_Themes extends SLB_Collection_Controller {
|
|
25 |
|
26 |
protected function _hooks() {
|
27 |
parent::_hooks();
|
28 |
-
//Register themes
|
29 |
$this->util->add_action('init', $this->m('init_defaults'), 1);
|
30 |
|
31 |
-
//Client output
|
32 |
-
add_action('
|
|
|
33 |
}
|
34 |
|
35 |
protected function _options() {
|
@@ -46,7 +47,7 @@ class SLB_Themes extends SLB_Collection_Controller {
|
|
46 |
)
|
47 |
);
|
48 |
|
49 |
-
parent::
|
50 |
}
|
51 |
|
52 |
/**
|
@@ -54,17 +55,39 @@ class SLB_Themes extends SLB_Collection_Controller {
|
|
54 |
* @param SLB_Themes $themes Themes controller
|
55 |
*/
|
56 |
function init_defaults($themes) {
|
|
|
|
|
|
|
|
|
|
|
57 |
$defaults = array (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
$this->get_default_id() => array (
|
59 |
'name' => __('Default (Light)', 'simple-lightbox'),
|
60 |
-
'
|
61 |
-
'
|
62 |
-
|
|
|
|
|
|
|
|
|
63 |
),
|
64 |
$this->add_prefix('black') => array (
|
65 |
'name' => __('Default (Dark)', 'simple-lightbox'),
|
66 |
'parent' => $this->get_default_id(),
|
67 |
-
'
|
|
|
|
|
68 |
),
|
69 |
);
|
70 |
|
@@ -84,18 +107,58 @@ class SLB_Themes extends SLB_Collection_Controller {
|
|
84 |
* @return object Current instance
|
85 |
*/
|
86 |
public function add($id, $props = array()) {
|
87 |
-
//Prepare parent
|
88 |
if ( isset($props['parent']) && !($props['parent'] instanceof $this->item_type) ) {
|
89 |
$pid = $props['parent'];
|
90 |
-
$items = $this->get();
|
91 |
if ( isset($items[$pid]) ) {
|
92 |
$props['parent'] = $items[$pid];
|
93 |
}
|
94 |
}
|
95 |
$o = ( is_string($id) ) ? new $this->item_type($id, $props) : $id;
|
96 |
-
//Add to collection
|
97 |
return parent::add($o);
|
98 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
|
100 |
/* Helpers */
|
101 |
|
@@ -116,9 +179,9 @@ class SLB_Themes extends SLB_Collection_Controller {
|
|
116 |
* @return SLB_Theme Selected theme
|
117 |
*/
|
118 |
protected function get_selected() {
|
119 |
-
//Get themes
|
120 |
$thms = $this->get();
|
121 |
-
//Retrieve currently-selected theme
|
122 |
$id = $this->options->get_value('theme_default');
|
123 |
if ( !isset($thms[$id]) ) {
|
124 |
$id = $this->get_default_id();
|
@@ -129,66 +192,72 @@ class SLB_Themes extends SLB_Collection_Controller {
|
|
129 |
/* Output */
|
130 |
|
131 |
/**
|
132 |
-
*
|
133 |
*/
|
134 |
public function client_output() {
|
135 |
-
//
|
136 |
-
|
137 |
-
return;
|
138 |
-
}
|
139 |
|
140 |
-
//
|
141 |
-
|
142 |
-
|
143 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
$thm = $this->get_selected();
|
145 |
|
146 |
-
//Process theme ancestors
|
147 |
-
$thms =
|
148 |
$thms[] = $thm;
|
149 |
|
150 |
-
$
|
151 |
-
$out = array();
|
152 |
-
$out[] = '<!-- SLB-THM -->' . PHP_EOL;
|
153 |
$code = array();
|
154 |
|
155 |
-
//Build output for each theme
|
156 |
foreach ( $thms as $thm ) {
|
157 |
-
//Setup client parameters
|
158 |
$params = array(
|
159 |
sprintf("'%s'", $thm->get_id()),
|
160 |
);
|
161 |
-
//Theme properties
|
162 |
$thm_props = array(
|
163 |
'name' => $thm->get_name(),
|
164 |
'parent' => ( $thm->has_parent() ) ? $thm->get_parent()->get_id() : '',
|
|
|
165 |
);
|
166 |
/* Optional properties */
|
167 |
-
//Layout
|
168 |
-
$
|
169 |
-
if ( !empty($
|
170 |
-
|
|
|
|
|
|
|
171 |
}
|
172 |
-
//
|
173 |
-
$script = $thm->get_client_script('uri');
|
174 |
-
if ( !empty($script) ) {
|
175 |
-
$thm_props['client_script'] = $script;
|
176 |
-
}
|
177 |
-
//Style
|
178 |
-
$style = $thm->get_client_style('uri');
|
179 |
-
if ( !empty($style) ) {
|
180 |
-
$thm_props['client_style'] = $style;
|
181 |
-
}
|
182 |
-
//Add properties to parameters
|
183 |
$params[] = json_encode($thm_props);
|
184 |
|
185 |
-
//Add theme to client
|
186 |
-
$code[] = $this->util->call_client_method('View.
|
187 |
}
|
188 |
|
189 |
-
|
190 |
-
|
191 |
-
|
|
|
|
|
192 |
}
|
193 |
|
194 |
/* Options */
|
@@ -199,24 +268,26 @@ class SLB_Themes extends SLB_Collection_Controller {
|
|
199 |
* @return array Theme options
|
200 |
*/
|
201 |
public function opt_get_field_values() {
|
202 |
-
//Get themes
|
203 |
$items = $this->get();
|
204 |
$d = $this->get_default_id();
|
205 |
-
//Pop out default theme
|
206 |
if ( isset($items[$d]) ) {
|
207 |
$itm_d = $items[$d];
|
208 |
unset($items[$d]);
|
209 |
}
|
210 |
|
211 |
-
//Sort themes by name
|
212 |
-
uasort($items,
|
|
|
|
|
213 |
|
214 |
-
//Insert default theme at top of array
|
215 |
if ( isset($itm_d) ) {
|
216 |
$items = array( $d => $itm_d ) + $items;
|
217 |
}
|
218 |
|
219 |
-
//Build options
|
220 |
foreach ( $items as $item ) {
|
221 |
$items[$item->get_id()] = $item->get_name();
|
222 |
}
|
25 |
|
26 |
protected function _hooks() {
|
27 |
parent::_hooks();
|
28 |
+
// Register themes
|
29 |
$this->util->add_action('init', $this->m('init_defaults'), 1);
|
30 |
|
31 |
+
// Client output
|
32 |
+
$this->util->add_action('footer', $this->m('client_output'), 1, 0, false);
|
33 |
+
$this->util->add_filter('footer_script', $this->m('client_output_script'), $this->util->priority('client_footer_output'), 1, false);
|
34 |
}
|
35 |
|
36 |
protected function _options() {
|
47 |
)
|
48 |
);
|
49 |
|
50 |
+
parent::_set_options($opts);
|
51 |
}
|
52 |
|
53 |
/**
|
55 |
* @param SLB_Themes $themes Themes controller
|
56 |
*/
|
57 |
function init_defaults($themes) {
|
58 |
+
$js_path = 'js/';
|
59 |
+
$js_path .= ( SLB_DEV ) ? 'dev' : 'prod';
|
60 |
+
$scheme = is_ssl() ? 'https' : 'http';
|
61 |
+
$baseline = $this->add_prefix('baseline');
|
62 |
+
$src_base = $this->util->get_file_url('themes', true);
|
63 |
$defaults = array (
|
64 |
+
$baseline => array (
|
65 |
+
'name' => __('Baseline', 'simple-lightbox'),
|
66 |
+
'public' => false,
|
67 |
+
'layout' => "$src_base/baseline/layout.html",
|
68 |
+
'scripts' => array (
|
69 |
+
array ( 'base', $src_base . "/baseline/$js_path/client.js" ),
|
70 |
+
),
|
71 |
+
'styles' => array (
|
72 |
+
array ( 'base', "$src_base/baseline/css/style.css" ),
|
73 |
+
),
|
74 |
+
),
|
75 |
$this->get_default_id() => array (
|
76 |
'name' => __('Default (Light)', 'simple-lightbox'),
|
77 |
+
'parent' => $baseline,
|
78 |
+
'scripts' => array (
|
79 |
+
array ( 'base', $src_base . "/default/$js_path/client.js" ),
|
80 |
+
),
|
81 |
+
'styles' => array (
|
82 |
+
array ( 'base', "$src_base/default/css/style.css" ),
|
83 |
+
),
|
84 |
),
|
85 |
$this->add_prefix('black') => array (
|
86 |
'name' => __('Default (Dark)', 'simple-lightbox'),
|
87 |
'parent' => $this->get_default_id(),
|
88 |
+
'styles' => array (
|
89 |
+
array ( 'base', "$src_base/black/css/style.css" )
|
90 |
+
)
|
91 |
),
|
92 |
);
|
93 |
|
107 |
* @return object Current instance
|
108 |
*/
|
109 |
public function add($id, $props = array()) {
|
110 |
+
// Prepare parent
|
111 |
if ( isset($props['parent']) && !($props['parent'] instanceof $this->item_type) ) {
|
112 |
$pid = $props['parent'];
|
113 |
+
$items = $this->get(array('include_private' => true));
|
114 |
if ( isset($items[$pid]) ) {
|
115 |
$props['parent'] = $items[$pid];
|
116 |
}
|
117 |
}
|
118 |
$o = ( is_string($id) ) ? new $this->item_type($id, $props) : $id;
|
119 |
+
// Add to collection
|
120 |
return parent::add($o);
|
121 |
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Get themes
|
125 |
+
* @param array $args (optional) Arguments
|
126 |
+
* @return array Themes
|
127 |
+
*/
|
128 |
+
public function get($args = null) {
|
129 |
+
// Normalize arguments
|
130 |
+
$args_default = array(
|
131 |
+
'include_public' => true,
|
132 |
+
'include_private' => false,
|
133 |
+
);
|
134 |
+
$r = wp_parse_args($args, $args_default);
|
135 |
+
$r['include_public'] = !!$r['include_public'];
|
136 |
+
$r['include_private'] = !!$r['include_private'];
|
137 |
+
|
138 |
+
$items = parent::get($args);
|
139 |
+
|
140 |
+
if ( empty($items) )
|
141 |
+
return $items;
|
142 |
+
|
143 |
+
/* Process custom arguments */
|
144 |
+
|
145 |
+
// Filter
|
146 |
+
$items_exclude = array();
|
147 |
+
// Identify excluded themes
|
148 |
+
$filter_props = array('include_public' => true, 'include_private' => false);
|
149 |
+
foreach ( $filter_props as $filter_prop => $filter_value ) {
|
150 |
+
if ( !$r[ $filter_prop ] ) {
|
151 |
+
foreach ( $items as $id => $item ) {
|
152 |
+
if ( $item->get_public() == $filter_value ) {
|
153 |
+
$items_exclude[] = $id;
|
154 |
+
}
|
155 |
+
}
|
156 |
+
}
|
157 |
+
}
|
158 |
+
// Filter themes from collection
|
159 |
+
$items = array_diff_key($items, array_fill_keys($items_exclude, null));
|
160 |
+
return $items;
|
161 |
+
}
|
162 |
|
163 |
/* Helpers */
|
164 |
|
179 |
* @return SLB_Theme Selected theme
|
180 |
*/
|
181 |
protected function get_selected() {
|
182 |
+
// Get themes
|
183 |
$thms = $this->get();
|
184 |
+
// Retrieve currently-selected theme
|
185 |
$id = $this->options->get_value('theme_default');
|
186 |
if ( !isset($thms[$id]) ) {
|
187 |
$id = $this->get_default_id();
|
192 |
/* Output */
|
193 |
|
194 |
/**
|
195 |
+
* Build client output
|
196 |
*/
|
197 |
public function client_output() {
|
198 |
+
// Process active theme
|
199 |
+
$thm = $this->get_selected();
|
|
|
|
|
200 |
|
201 |
+
// Get theme ancestors
|
202 |
+
$thms = $thm->get_ancestors(true);
|
203 |
+
$thms[] = $thm;
|
204 |
+
|
205 |
+
foreach ( $thms as $thm ) {
|
206 |
+
// Load files
|
207 |
+
$thm->enqueue_scripts();
|
208 |
+
}
|
209 |
+
}
|
210 |
+
|
211 |
+
/**
|
212 |
+
* Client output script
|
213 |
+
*
|
214 |
+
* @param array $commands Client script commands
|
215 |
+
* @return array Modified script commands
|
216 |
+
*/
|
217 |
+
public function client_output_script($commands) {
|
218 |
+
// Theme
|
219 |
$thm = $this->get_selected();
|
220 |
|
221 |
+
// Process theme ancestors
|
222 |
+
$thms = $thm->get_ancestors(true);
|
223 |
$thms[] = $thm;
|
224 |
|
225 |
+
$out = array('/* THM */');
|
|
|
|
|
226 |
$code = array();
|
227 |
|
228 |
+
// Build output for each theme
|
229 |
foreach ( $thms as $thm ) {
|
230 |
+
// Setup client parameters
|
231 |
$params = array(
|
232 |
sprintf("'%s'", $thm->get_id()),
|
233 |
);
|
234 |
+
// Theme properties
|
235 |
$thm_props = array(
|
236 |
'name' => $thm->get_name(),
|
237 |
'parent' => ( $thm->has_parent() ) ? $thm->get_parent()->get_id() : '',
|
238 |
+
'styles' => array_values($thm->get_styles(array('uri_format'=>'full'))),
|
239 |
);
|
240 |
/* Optional properties */
|
241 |
+
// Layout
|
242 |
+
$layout = $thm->get_layout('contents');
|
243 |
+
if ( !empty($layout) ) {
|
244 |
+
// Format
|
245 |
+
$layout = str_replace(array("\n", "\r", "\t"), '', $layout);
|
246 |
+
// Save
|
247 |
+
$thm_props['layout_raw'] = $layout;
|
248 |
}
|
249 |
+
// Add properties to parameters
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
250 |
$params[] = json_encode($thm_props);
|
251 |
|
252 |
+
// Add theme to client
|
253 |
+
$code[] = $this->util->call_client_method('View.extend_theme', $params, false);
|
254 |
}
|
255 |
|
256 |
+
if ( !empty($code) ) {
|
257 |
+
$out[] = implode('', $code);
|
258 |
+
$commands[] = implode(PHP_EOL, $out);
|
259 |
+
}
|
260 |
+
return $commands;
|
261 |
}
|
262 |
|
263 |
/* Options */
|
268 |
* @return array Theme options
|
269 |
*/
|
270 |
public function opt_get_field_values() {
|
271 |
+
// Get themes
|
272 |
$items = $this->get();
|
273 |
$d = $this->get_default_id();
|
274 |
+
// Pop out default theme
|
275 |
if ( isset($items[$d]) ) {
|
276 |
$itm_d = $items[$d];
|
277 |
unset($items[$d]);
|
278 |
}
|
279 |
|
280 |
+
// Sort themes by name
|
281 |
+
uasort( $items, function( $a, $b ) {
|
282 |
+
return strcmp( $a->get_name(), $b->get_name() );
|
283 |
+
});
|
284 |
|
285 |
+
// Insert default theme at top of array
|
286 |
if ( isset($itm_d) ) {
|
287 |
$items = array( $d => $itm_d ) + $items;
|
288 |
}
|
289 |
|
290 |
+
// Build options
|
291 |
foreach ( $items as $item ) {
|
292 |
$items[$item->get_id()] = $item->get_name();
|
293 |
}
|
includes/class.utilities.php
CHANGED
@@ -16,30 +16,40 @@ class SLB_Utilities {
|
|
16 |
* Instance parent
|
17 |
* @var object
|
18 |
*/
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
|
21 |
/**
|
22 |
-
*
|
23 |
-
* @var
|
24 |
*/
|
25 |
-
private $
|
26 |
-
'Name' => 'Plugin Name',
|
27 |
-
'PluginURI' => 'Plugin URI',
|
28 |
-
'Version' => 'Version',
|
29 |
-
'Description' => 'Description',
|
30 |
-
'Author' => 'Author',
|
31 |
-
'AuthorURI' => 'Author URI',
|
32 |
-
'TextDomain' => 'Text Domain',
|
33 |
-
'DomainPath' => 'Domain Path',
|
34 |
-
'Network' => 'Network',
|
35 |
-
);
|
36 |
-
|
37 |
|
38 |
/**
|
39 |
* Standard hook priorities
|
40 |
* @var array
|
41 |
*/
|
42 |
-
private $
|
43 |
'high' => 1,
|
44 |
'low' => 99,
|
45 |
'safe' => 15,
|
@@ -48,9 +58,10 @@ class SLB_Utilities {
|
|
48 |
|
49 |
/* Constructors */
|
50 |
|
51 |
-
function __construct(
|
52 |
-
if ( is_object($obj) )
|
53 |
-
$this->
|
|
|
54 |
}
|
55 |
|
56 |
/**
|
@@ -93,35 +104,47 @@ class SLB_Utilities {
|
|
93 |
*/
|
94 |
function get_prefix($sep = null) {
|
95 |
$sep = $this->get_sep($sep);
|
96 |
-
$prefix = ( !empty($this->
|
97 |
return $prefix;
|
98 |
}
|
99 |
|
100 |
/**
|
101 |
* Check if a string is prefixed
|
102 |
-
* @param string $text Text to check for prefix
|
103 |
* @param string $sep (optional) Separator used
|
104 |
*/
|
105 |
function has_prefix($text, $sep = null) {
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
return ( !empty($text) && stripos($text, $this->get_prefix($sep)) === 0 );
|
107 |
}
|
108 |
|
109 |
/**
|
110 |
* Prepend plugin prefix to some text
|
111 |
-
* @param string $text Text to add to prefix
|
112 |
* @param string $sep (optional) Text used to separate prefix and text
|
113 |
* @param bool $once (optional) Whether to add prefix to text that already contains a prefix or not
|
114 |
* @return string Text with prefix prepended
|
115 |
*/
|
116 |
function add_prefix($text, $sep = '_', $once = true) {
|
117 |
-
|
118 |
-
|
119 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
}
|
121 |
|
122 |
/**
|
123 |
* Prepend uppercased plugin prefix to some text
|
124 |
-
* @param string $text Text to add to prefix
|
125 |
* @param string $sep (optional) Text used to separate prefix and text
|
126 |
* @param bool $once (optional) Whether to add prefix to text that already contains a prefix or not
|
127 |
* @return string Text with prefix prepended
|
@@ -176,8 +199,8 @@ class SLB_Utilities {
|
|
176 |
*/
|
177 |
public function priority($id = null) {
|
178 |
$pri = 10;
|
179 |
-
if ( !is_null($id) && array_key_exists($id, $this->
|
180 |
-
$pri = $this->
|
181 |
}
|
182 |
return $pri;
|
183 |
}
|
@@ -185,30 +208,44 @@ class SLB_Utilities {
|
|
185 |
/* Wrapped Values */
|
186 |
|
187 |
/**
|
188 |
-
*
|
|
|
|
|
|
|
189 |
* @param string|array $start Start text (Can also be array defining start & end values)
|
190 |
* @param string $end (optional) End text
|
191 |
* If $end not defined, then $start is used
|
192 |
* @return obj Wrapper
|
193 |
*/
|
194 |
function get_wrapper($start = null, $end = null) {
|
195 |
-
//
|
196 |
if ( is_object($start) && isset($start->start) && isset($start->end) )
|
197 |
return $start;
|
198 |
-
//Default wrapper
|
199 |
-
if ( is_null($start) && is_null($end) )
|
200 |
-
$start = array('[', ']');
|
201 |
-
$wrapper = compact('start', 'end');
|
202 |
-
if ( is_array($start) && count($start) > 1 ) {
|
203 |
-
$wrapper['start'] = $start[0];
|
204 |
-
$wrapper['end'] = $start[1];
|
205 |
-
}
|
206 |
-
if ( !is_string($wrapper['start']) || empty($wrapper['start'] ) )
|
207 |
-
$wrapper['start'] = '';
|
208 |
-
if ( !is_string($wrapper['end']) || empty($wrapper['end']) )
|
209 |
-
$wrapper['end'] = $wrapper['start'];
|
210 |
|
211 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
212 |
}
|
213 |
|
214 |
/**
|
@@ -221,11 +258,11 @@ class SLB_Utilities {
|
|
221 |
function has_wrapper($text, $start = null, $end = null) {
|
222 |
if ( !is_string($text) || empty($text) )
|
223 |
return false;
|
224 |
-
//Validate wrapper
|
225 |
$w = $this->get_wrapper($start, $end);
|
226 |
|
227 |
-
//Check for wrapper
|
228 |
-
return ( substr($text, 0,
|
229 |
}
|
230 |
|
231 |
/**
|
@@ -248,7 +285,7 @@ class SLB_Utilities {
|
|
248 |
|
249 |
/**
|
250 |
* Add wrapper to specified text
|
251 |
-
* @uses
|
252 |
* @param string $text Text to wrap
|
253 |
* @param string|array $start (optional) Start text (Array defines both start/end text)
|
254 |
* @param string $end (optional) End text
|
@@ -285,13 +322,14 @@ class SLB_Utilities {
|
|
285 |
*/
|
286 |
function parse_client_files($files, $type = 'scripts') {
|
287 |
if ( is_array($files) && !empty($files) ) {
|
288 |
-
//Defaults
|
289 |
$defaults = array(
|
290 |
'file' => null,
|
291 |
'deps' => array(),
|
292 |
'callback' => null,
|
293 |
'context' => array(),
|
294 |
'enqueue' => true,
|
|
|
295 |
);
|
296 |
switch ( $type ) {
|
297 |
case 'styles':
|
@@ -300,34 +338,43 @@ class SLB_Utilities {
|
|
300 |
default:
|
301 |
$defaults['in_footer'] = false;
|
302 |
}
|
303 |
-
//Iterate through files
|
|
|
|
|
|
|
|
|
304 |
foreach ( $files as $h => $p ) {
|
305 |
unset($file, $cb, $ctxs, $ctx);
|
306 |
-
//Set ID
|
307 |
$p['id'] = $this->add_prefix($h);
|
308 |
-
//Type Validation
|
|
|
|
|
|
|
|
|
309 |
foreach ( $defaults as $m => $d ) {
|
310 |
-
//Check if value requires validation
|
311 |
if ( !is_array($d) || !isset($p[$m]) || is_array($p[$m]) )
|
312 |
continue;
|
313 |
-
//Wrap value in array or destroy it
|
314 |
if ( is_scalar($p[$m]) )
|
315 |
$p[$m] = array($p[$m]);
|
316 |
else
|
317 |
unset($p[$m]);
|
318 |
}
|
319 |
|
|
|
320 |
$p = array_merge($defaults, $p);
|
321 |
|
322 |
/* File name */
|
323 |
|
324 |
-
//Validate file
|
325 |
$file =& $p['file'];
|
326 |
|
327 |
-
//Determine if filename or callback
|
328 |
if ( !$this->is_file($file) )
|
329 |
-
$file =
|
330 |
-
//Remove invalid file and move on to next
|
331 |
if ( empty($file) ) {
|
332 |
unset($files[$h]);
|
333 |
continue;
|
@@ -335,7 +382,7 @@ class SLB_Utilities {
|
|
335 |
|
336 |
/* Dependencies */
|
337 |
|
338 |
-
//Format internal dependencies
|
339 |
foreach ( $p['deps'] as $idx => $dep ) {
|
340 |
if ( $this->has_wrapper($dep) ) {
|
341 |
$dep = $this->remove_wrapper($dep);
|
@@ -345,50 +392,46 @@ class SLB_Utilities {
|
|
345 |
|
346 |
/* Context */
|
347 |
|
348 |
-
//Validate callback
|
349 |
$cb =& $p['callback'];
|
350 |
-
if ( !is_null($cb) ) {
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
unset($files[$h]);
|
355 |
-
continue;
|
356 |
-
}
|
357 |
}
|
358 |
|
359 |
-
//Validate contexts
|
360 |
$ctxs =& $p['context'];
|
361 |
$ctxs = array_unique($ctxs);
|
362 |
$has_contexts = ( count($ctxs) > 0 ) ? true : false;
|
363 |
foreach ( $ctxs as $idx => $ctx ) {
|
364 |
-
//Convert to array
|
365 |
$ctx = array_values( array_slice( (array) $ctx, 0, 2 ) );
|
366 |
switch ( count($ctx) ) {
|
367 |
case 1 :
|
368 |
-
//Simple context
|
369 |
$ctx = $ctx[0];
|
370 |
break;
|
371 |
case 2 :
|
372 |
-
//Context + Callback
|
373 |
-
|
374 |
-
if ( !is_null($ctx[1]) ) {
|
375 |
break;
|
376 |
}
|
377 |
-
//Continue to default case if callback is invalid
|
378 |
default :
|
379 |
-
//Context is invalid
|
380 |
$ctx = false;
|
381 |
break;
|
382 |
}
|
383 |
|
384 |
-
//Remove invalid contexts
|
385 |
if ( empty($ctx) ) {
|
386 |
unset($ctxs[$idx]);
|
387 |
} else {
|
388 |
$ctxs[$idx] = $ctx;
|
389 |
}
|
390 |
}
|
391 |
-
//Remove file if all specified contexts invalid (no context is OK)
|
392 |
if ( $has_contexts && empty($ctxs) ) {
|
393 |
unset($files[$h]);
|
394 |
continue;
|
@@ -397,30 +440,15 @@ class SLB_Utilities {
|
|
397 |
|
398 |
/* Finalize Properties */
|
399 |
|
400 |
-
//Convert properties to object
|
401 |
$files[$h] = (object) $p;
|
402 |
}
|
403 |
}
|
404 |
-
//Cast to object before returning
|
405 |
$files = (object) $files;
|
406 |
return $files;
|
407 |
}
|
408 |
|
409 |
-
/**
|
410 |
-
* Parses callbacks set for client files
|
411 |
-
* @param string $callback Callback value
|
412 |
-
* > Values wrapped in square brackets (`[` & `]`) are internal methods (of parent object)
|
413 |
-
* @return callback|null Validated callback (NULL if callback is invalid)
|
414 |
-
*/
|
415 |
-
function parse_client_file_callback($callback) {
|
416 |
-
if ( $this->has_wrapper($callback) ) {
|
417 |
-
$callback = $this->m($this->parent, $this->remove_wrapper($callback));
|
418 |
-
}
|
419 |
-
if ( !is_callable($callback) )
|
420 |
-
$callback = null;
|
421 |
-
return $callback;
|
422 |
-
}
|
423 |
-
|
424 |
/**
|
425 |
* Build JS client object
|
426 |
* @param string (optional) $path Additional object path
|
@@ -444,7 +472,7 @@ class SLB_Utilities {
|
|
444 |
* @return string JS expression to extend client object
|
445 |
*/
|
446 |
function extend_client_object($obj, $data = null, $out = false) {
|
447 |
-
//Validate parameters
|
448 |
$args = func_get_args();
|
449 |
switch ( count($args) ) {
|
450 |
case 2:
|
@@ -459,14 +487,14 @@ class SLB_Utilities {
|
|
459 |
$obj = null;
|
460 |
break;
|
461 |
}
|
462 |
-
//Default client object
|
463 |
if ( !is_string($obj) || empty($obj) )
|
464 |
$obj = null;
|
465 |
-
//Default data
|
466 |
if ( is_array($data) ) {
|
467 |
$data = (object)$data;
|
468 |
}
|
469 |
-
//Build expression
|
470 |
if ( empty($data) || ( empty($obj) && is_scalar($data) ) ) {
|
471 |
$ret = '';
|
472 |
} else {
|
@@ -487,24 +515,24 @@ class SLB_Utilities {
|
|
487 |
* If no command is specified the validation conditions are returned
|
488 |
*/
|
489 |
public function validate_client_object($obj, $cmd = null) {
|
490 |
-
//
|
|
|
|
|
|
|
491 |
$sep = '.';
|
492 |
-
$obj = trim(
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
$
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
} while ( $offset < $len && ( $pos = strrpos($obj, $sep, $offset) ) && $pos !== false );
|
503 |
-
//Format condition
|
504 |
-
$condition = implode(' && ', array_reverse($objs));
|
505 |
|
506 |
-
//Wrap command in validation
|
507 |
-
if (
|
508 |
$condition = sprintf('if ( %1$s ) { %2$s }', $condition, $cmd);
|
509 |
}
|
510 |
return $condition;
|
@@ -527,7 +555,7 @@ class SLB_Utilities {
|
|
527 |
$encode = !!$encode;
|
528 |
$validate = !!$validate;
|
529 |
|
530 |
-
//Build parameters
|
531 |
if ( !is_null($params) ) {
|
532 |
if ( $encode ) {
|
533 |
$params = json_encode($params);
|
@@ -571,17 +599,17 @@ class SLB_Utilities {
|
|
571 |
return true;
|
572 |
}
|
573 |
|
574 |
-
/* Hooks */
|
575 |
|
576 |
/**
|
577 |
* Retrieve parent object
|
578 |
* @return obj|bool Parent object (FALSE if no valid parent set)
|
579 |
*/
|
580 |
-
function
|
581 |
-
if ( is_object($this->
|
582 |
-
return $this->
|
583 |
-
else
|
584 |
-
return false;
|
|
|
585 |
}
|
586 |
|
587 |
/**
|
@@ -592,9 +620,11 @@ class SLB_Utilities {
|
|
592 |
* @return mixed Parent property value
|
593 |
*/
|
594 |
function get_parent_property($prop, $default = '') {
|
595 |
-
$p
|
596 |
return ( !!$p && property_exists($p, $prop) ) ? $p->{$prop} : $default;
|
597 |
-
}
|
|
|
|
|
598 |
|
599 |
/**
|
600 |
* Retrieve formatted name for internal hooks
|
@@ -602,14 +632,20 @@ class SLB_Utilities {
|
|
602 |
* @uses self::get_parent_property() to retrieve hook prefix
|
603 |
* @uses self::add_prefix()
|
604 |
* @param string $tag Base tag
|
|
|
605 |
* @return string Formatted hook
|
606 |
*/
|
607 |
-
function get_hook($tag) {
|
608 |
-
//Hook prefix
|
609 |
-
$hook =
|
|
|
|
|
|
|
|
|
|
|
610 |
if ( !empty($hook) )
|
611 |
$hook .= '_';
|
612 |
-
//Prefix
|
613 |
return $this->add_prefix($hook . $tag);
|
614 |
}
|
615 |
|
@@ -618,19 +654,27 @@ class SLB_Utilities {
|
|
618 |
* Namespaces $tag
|
619 |
* @uses self::get_hook()
|
620 |
* @see do_action()
|
|
|
621 |
*/
|
622 |
function do_action($tag, $arg = '') {
|
|
|
|
|
|
|
|
|
|
|
|
|
623 |
$args = func_get_args();
|
624 |
-
$args[0] = $this->get_hook($tag);
|
625 |
return call_user_func_array('do_action', $args);
|
626 |
}
|
627 |
|
628 |
/**
|
629 |
* Run internal action passing arguments in array
|
630 |
* @uses do_action_ref_array()
|
|
|
631 |
*/
|
632 |
-
function do_action_ref_array($tag, $args) {
|
633 |
-
return do_action_ref_array($this->get_hook($tag), $args);
|
634 |
}
|
635 |
|
636 |
/**
|
@@ -638,19 +682,27 @@ class SLB_Utilities {
|
|
638 |
* Namespaces $tag
|
639 |
* @uses self::get_hook()
|
640 |
* @see apply_filters()
|
|
|
641 |
*/
|
642 |
function apply_filters($tag, $value) {
|
|
|
|
|
|
|
|
|
|
|
|
|
643 |
$args = func_get_args();
|
644 |
-
$args[0] = $this->get_hook($tag);
|
645 |
return call_user_func_array('apply_filters', $args);
|
646 |
}
|
647 |
|
648 |
/**
|
649 |
* Run internal filter passing arguments in array
|
650 |
* @uses apply_filters_ref_array()
|
|
|
651 |
*/
|
652 |
-
function apply_filters_ref_array($tag, $args) {
|
653 |
-
return apply_filters_ref_array($this->get_hook($tag), $args);
|
654 |
}
|
655 |
|
656 |
/**
|
@@ -658,9 +710,10 @@ class SLB_Utilities {
|
|
658 |
* Namespaces $tag
|
659 |
* @uses self::get_hook()
|
660 |
* @see add_action()
|
|
|
661 |
*/
|
662 |
-
function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
|
663 |
-
return add_action($this->get_hook($tag), $function_to_add, $priority, $accepted_args);
|
664 |
}
|
665 |
|
666 |
/**
|
@@ -668,9 +721,10 @@ class SLB_Utilities {
|
|
668 |
* Namespaces $tag
|
669 |
* @uses self::get_hook()
|
670 |
* @see add_filter()
|
|
|
671 |
*/
|
672 |
-
function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
|
673 |
-
return add_filter($this->get_hook($tag), $function_to_add, $priority, $accepted_args);
|
674 |
}
|
675 |
|
676 |
/**
|
@@ -678,9 +732,10 @@ class SLB_Utilities {
|
|
678 |
* Namespaces $tag
|
679 |
* @uses self::get_hook()
|
680 |
* @uses remove_action()
|
|
|
681 |
*/
|
682 |
-
function remove_action($tag, $function_to_remove, $priority = 10, $accepted_args = 1) {
|
683 |
-
return remove_action($this->get_hook($tag), $function_to_remove, $priority, $accepted_args);
|
684 |
}
|
685 |
|
686 |
/**
|
@@ -688,9 +743,71 @@ class SLB_Utilities {
|
|
688 |
* Namespaces $tag
|
689 |
* @uses self::get_hook()
|
690 |
* @uses remove_filter()
|
|
|
691 |
*/
|
692 |
-
function remove_filter($tag, $function_to_remove, $priority = 10, $accepted_args = 1) {
|
693 |
-
return remove_filter($this->get_hook($tag), $function_to_remove, $priority, $accepted_args);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
694 |
}
|
695 |
|
696 |
/* Meta */
|
@@ -777,37 +894,8 @@ class SLB_Utilities {
|
|
777 |
return '_' . $this->add_prefix($text);
|
778 |
}
|
779 |
|
780 |
-
/*-** Request **-*/
|
781 |
-
|
782 |
-
/**
|
783 |
-
* Checks if the currently executing file matches specified file name
|
784 |
-
* @param string $filename Filename to check for
|
785 |
-
* @return bool TRUE if current page matches specified filename, FALSE otherwise
|
786 |
-
*/
|
787 |
-
function is_current_file( $filename ) {
|
788 |
-
return ( $filename == basename( $_SERVER['SCRIPT_NAME'] ) );
|
789 |
-
}
|
790 |
-
|
791 |
-
/**
|
792 |
-
* Checks whether the current page is a management page
|
793 |
-
* @return bool TRUE if current page is a management page, FALSE otherwise
|
794 |
-
*/
|
795 |
-
function is_admin_management_page() {
|
796 |
-
return ( is_admin()
|
797 |
-
&& ( $this->is_current_file('edit.php')
|
798 |
-
|| ( $this->is_current_file('admin.php')
|
799 |
-
&& isset($_GET['page'])
|
800 |
-
&& strpos($_GET['page'], 'cnr') === 0 )
|
801 |
-
)
|
802 |
-
);
|
803 |
-
}
|
804 |
-
|
805 |
/* Class */
|
806 |
|
807 |
-
function is_a($obj, $class_name) {
|
808 |
-
return ( is_object($obj) && is_a($obj, $this->add_prefix_uc($class_name)) ) ? true : false;
|
809 |
-
}
|
810 |
-
|
811 |
/**
|
812 |
* Retrieve name of internal class
|
813 |
* @param string $class Base name of class
|
@@ -824,38 +912,43 @@ class SLB_Utilities {
|
|
824 |
* @return array Context
|
825 |
*/
|
826 |
function get_context() {
|
827 |
-
//Context
|
828 |
static $ctx = null;
|
829 |
if ( !is_array($ctx) ) {
|
830 |
-
//Standard
|
831 |
$ctx = array($this->build_context());
|
832 |
-
//Action
|
833 |
$action = $this->get_action();
|
834 |
if ( !empty($action) ) {
|
835 |
$ctx[] = $this->build_context('action', $action);
|
836 |
}
|
837 |
-
//Post type
|
838 |
$post_type = $this->get_post_type();
|
839 |
if ( !empty($action) ) {
|
840 |
$ctx[] = $this->build_context('post-type', $post_type);
|
841 |
}
|
842 |
-
//Admin page
|
843 |
if ( is_admin() ) {
|
844 |
global $pagenow;
|
845 |
$pg = $this->strip_file_extension($pagenow);
|
846 |
$ctx[] = $this->build_context('page', $pg);
|
847 |
-
//Query String
|
848 |
-
|
849 |
-
|
850 |
-
|
|
|
|
|
|
|
|
|
|
|
851 |
}
|
852 |
-
//Action
|
853 |
if ( !empty($action) ) {
|
854 |
$ctx[] = $this->build_context('page', $pg, 'action', $action);
|
855 |
$ctx[] = $this->build_context('post-type', $post_type, 'action', $action);
|
856 |
}
|
857 |
}
|
858 |
-
//User
|
859 |
$u = wp_get_current_user();
|
860 |
$ctx[] = $this->build_context('user', ( $u->ID ) ? 'registered' : 'guest', false);
|
861 |
}
|
@@ -875,16 +968,16 @@ class SLB_Utilities {
|
|
875 |
*/
|
876 |
function build_context($context = null, $prefix = true) {
|
877 |
$args = func_get_args();
|
878 |
-
//Get prefix option
|
879 |
if ( !empty($args) ) {
|
880 |
$prefix = ( is_bool($args[count($args) - 1]) ) ? array_pop($args) : true;
|
881 |
}
|
882 |
|
883 |
-
//Validate
|
884 |
$context = array_filter($args, 'is_string');
|
885 |
$sep = '_';
|
886 |
|
887 |
-
//Context Prefix
|
888 |
if ( $prefix )
|
889 |
array_unshift($context, ( is_admin() ) ? 'admin' : 'public' );
|
890 |
return implode($sep, $context);
|
@@ -919,6 +1012,8 @@ class SLB_Utilities {
|
|
919 |
$this->extend_client_object($ctx, true);
|
920 |
}
|
921 |
|
|
|
|
|
922 |
/**
|
923 |
* Joins and normalizes the slashes in the paths passed to method
|
924 |
* All forward/back slashes are converted to forward slashes
|
@@ -932,47 +1027,47 @@ class SLB_Utilities {
|
|
932 |
$sl_f = '/';
|
933 |
$sl_b = '\\';
|
934 |
$parts = func_get_args();
|
935 |
-
//Slash defaults (trailing, leading);
|
936 |
$slashes = array(false, true);
|
937 |
if ( func_num_args() > 1 ) {
|
938 |
-
//Get last argument
|
939 |
$arg_last = $parts[count($parts) - 1];
|
940 |
if ( is_bool($arg_last) ) {
|
941 |
$arg_last = array($arg_last);
|
942 |
}
|
943 |
|
944 |
if ( is_array($arg_last) && count($arg_last) > 0 && is_bool($arg_last[0]) ) {
|
945 |
-
//Remove slash paramter from args array
|
946 |
array_pop($parts);
|
947 |
-
//Normalize slashes options
|
948 |
if ( isset($arg_last[0]) )
|
949 |
$slashes[0] = $arg_last[0];
|
950 |
if ( isset($arg_last[1]) )
|
951 |
$slashes[1] = $arg_last[1];
|
952 |
}
|
953 |
}
|
954 |
-
//Extract to slash options local variables
|
955 |
list($trailing_slash, $leading_slash) = $slashes;
|
956 |
|
957 |
-
//Clean path segments
|
958 |
foreach ( $parts as $key => $part ) {
|
959 |
-
//Trim slashes/spaces
|
960 |
$parts[$key] = trim($part, " " . $sl_f . $sl_b);
|
961 |
|
962 |
-
//Verify path segment still contains value
|
963 |
if ( empty($parts[$key]) ) {
|
964 |
unset($parts[$key]);
|
965 |
continue;
|
966 |
}
|
967 |
}
|
968 |
|
969 |
-
//Join path parts together
|
970 |
$parts = implode($sl_b, $parts);
|
971 |
$parts = str_replace($sl_b, $sl_f, $parts);
|
972 |
-
//Add trailing slash (if necessary)
|
973 |
if ( $trailing_slash )
|
974 |
$parts .= $sl_f;
|
975 |
-
//Add leading slash (if necessary)
|
976 |
$regex = '#^.+:[\\/]#';
|
977 |
if ( $leading_slash && !preg_match($regex, $parts) ) {
|
978 |
$parts = $sl_f . $parts;
|
@@ -983,11 +1078,12 @@ class SLB_Utilities {
|
|
983 |
/**
|
984 |
* Returns URL of file (assumes that it is in plugin directory)
|
985 |
* @param string $file name of file get URL
|
|
|
986 |
* @return string File URL
|
987 |
*/
|
988 |
-
function get_file_url($file) {
|
989 |
if ( is_string($file) && '' != trim($file) ) {
|
990 |
-
$file = str_replace(' ', '%20', $this->normalize_path($this->get_url_base(), $file));
|
991 |
}
|
992 |
return $file;
|
993 |
}
|
@@ -997,9 +1093,10 @@ class SLB_Utilities {
|
|
997 |
* @param string $file file name
|
998 |
* @return string File path
|
999 |
*/
|
1000 |
-
function get_file_path($file) {
|
|
|
1001 |
if ( is_string($file) && '' != trim($file) ) {
|
1002 |
-
$file = $this->normalize_path($this->get_path_base(), $file);
|
1003 |
}
|
1004 |
return $file;
|
1005 |
}
|
@@ -1020,6 +1117,15 @@ class SLB_Utilities {
|
|
1020 |
return ( empty($ext) ) ? false : true;
|
1021 |
}
|
1022 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1023 |
/**
|
1024 |
* Retrieves file extension
|
1025 |
* @param string $file file name/path
|
@@ -1029,8 +1135,13 @@ class SLB_Utilities {
|
|
1029 |
function get_file_extension($file, $lowercase = true) {
|
1030 |
$ret = '';
|
1031 |
$sep = '.';
|
|
|
1032 |
if ( !is_string($file) )
|
1033 |
return $ret;
|
|
|
|
|
|
|
|
|
1034 |
if ( ( $rpos = strrpos($file, $sep) ) > 0 )
|
1035 |
$ret = substr($file, $rpos + 1);
|
1036 |
if ( !!$lowercase )
|
@@ -1050,7 +1161,7 @@ class SLB_Utilities {
|
|
1050 |
if ( !is_array($extension) )
|
1051 |
$extension = array(strval($extension));
|
1052 |
if ( !$case_sensitive ) {
|
1053 |
-
//Normalize extensions
|
1054 |
$extension = array_map('strtolower', $extension);
|
1055 |
}
|
1056 |
return ( in_array($this->get_file_extension($file, !$case_sensitive), $extension) ) ? true : false;
|
@@ -1077,12 +1188,28 @@ class SLB_Utilities {
|
|
1077 |
* @uses normalize_path()
|
1078 |
* @return string Base URL
|
1079 |
*/
|
1080 |
-
function get_url_base() {
|
1081 |
-
|
1082 |
-
if (
|
1083 |
-
$
|
1084 |
}
|
1085 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1086 |
}
|
1087 |
|
1088 |
/**
|
@@ -1092,28 +1219,74 @@ class SLB_Utilities {
|
|
1092 |
* @uses normalize_path()
|
1093 |
* @return string Base path
|
1094 |
*/
|
1095 |
-
function get_path_base() {
|
1096 |
-
|
1097 |
-
if (
|
1098 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1099 |
}
|
1100 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1101 |
}
|
1102 |
|
1103 |
/**
|
1104 |
* Retrieve plugin's base directory
|
1105 |
* @uses WP_PLUGIN_DIR
|
1106 |
-
* @uses
|
|
|
1107 |
* @return string Base directory
|
1108 |
*/
|
1109 |
-
function get_plugin_base(
|
1110 |
-
|
1111 |
-
if (
|
1112 |
-
$
|
1113 |
}
|
1114 |
-
|
1115 |
-
$plugin_dir = trim($plugin_dir, ' \/');
|
1116 |
-
return $plugin_dir;
|
1117 |
}
|
1118 |
|
1119 |
/**
|
@@ -1123,28 +1296,30 @@ class SLB_Utilities {
|
|
1123 |
* @return string Base file path
|
1124 |
*/
|
1125 |
function get_plugin_base_file() {
|
1126 |
-
|
1127 |
-
if ( empty($
|
1128 |
-
$dir = @
|
1129 |
if ( $dir ) {
|
1130 |
while ( ($ftemp = readdir($dir)) !== false ) {
|
1131 |
-
//Only process PHP files
|
1132 |
$ftemp = $this->get_file_path($ftemp);
|
1133 |
if ( !$this->has_file_extension($ftemp, 'php') || !is_readable($ftemp) )
|
1134 |
continue;
|
1135 |
-
//Check for data
|
1136 |
-
$data = get_file_data($ftemp, $this->
|
1137 |
if ( !empty($data['Name']) ) {
|
1138 |
-
//Set base file
|
1139 |
-
$
|
|
|
|
|
1140 |
break;
|
1141 |
}
|
1142 |
}
|
1143 |
}
|
1144 |
@closedir($dir);
|
1145 |
}
|
1146 |
-
//Return
|
1147 |
-
return $
|
1148 |
}
|
1149 |
|
1150 |
/**
|
@@ -1155,33 +1330,35 @@ class SLB_Utilities {
|
|
1155 |
* @return string Internal plugin name
|
1156 |
*/
|
1157 |
function get_plugin_base_name() {
|
1158 |
-
|
1159 |
-
if (
|
1160 |
-
$
|
1161 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1162 |
}
|
1163 |
-
return $name;
|
1164 |
}
|
1165 |
|
1166 |
/**
|
1167 |
* Retrieve plugin info
|
1168 |
* Parses info comment in main plugin file
|
1169 |
-
* @uses get_plugin_base_file()
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
1173 |
-
$ret = '';
|
1174 |
-
//Get plugin data
|
1175 |
-
if ( empty($
|
1176 |
-
$
|
1177 |
-
$
|
1178 |
}
|
1179 |
-
//Return specified field
|
1180 |
if ( !empty($field) ) {
|
1181 |
-
|
1182 |
-
$ret = $data[$field];
|
1183 |
-
} else {
|
1184 |
-
$ret = $data;
|
1185 |
}
|
1186 |
return $ret;
|
1187 |
}
|
@@ -1193,33 +1370,17 @@ class SLB_Utilities {
|
|
1193 |
* @return string Plugin version
|
1194 |
*/
|
1195 |
function get_plugin_version($strip_desc = true) {
|
1196 |
-
|
1197 |
-
|
1198 |
-
|
1199 |
-
|
1200 |
-
$v = $this->get_plugin_info($field);
|
1201 |
-
}
|
1202 |
-
//Format
|
1203 |
-
$ret = $v;
|
1204 |
-
if ( $strip_desc ) {
|
1205 |
$ret = explode(' ', $ret, 2);
|
1206 |
$ret = $ret[0];
|
1207 |
}
|
1208 |
-
//Return
|
1209 |
return $ret;
|
1210 |
}
|
1211 |
|
1212 |
-
/**
|
1213 |
-
* Retrieve plugin textdomain (for localization)
|
1214 |
-
* @return string
|
1215 |
-
*/
|
1216 |
-
function get_plugin_textdomain() {
|
1217 |
-
static $dom = '';
|
1218 |
-
if ( empty($dom) )
|
1219 |
-
$dom = $this->get_plugin_base(true);
|
1220 |
-
return $dom;
|
1221 |
-
}
|
1222 |
-
|
1223 |
/**
|
1224 |
* Retrieve current post type based on URL query variables
|
1225 |
* @return string|null Current post type
|
@@ -1243,15 +1404,15 @@ class SLB_Utilities {
|
|
1243 |
function get_action($default = null) {
|
1244 |
$action = '';
|
1245 |
|
1246 |
-
//Check if action is set in URL
|
1247 |
if ( isset($_GET['action']) )
|
1248 |
$action = $_GET['action'];
|
1249 |
-
//Otherwise, Determine action based on plugin
|
1250 |
-
elseif ( isset($_GET['page']) && ($pos = strrpos($_GET['page'], '-')) && $pos !== false && ( $pos !=
|
1251 |
$action = trim(substr($_GET['page'], $pos + 1), '-_');
|
1252 |
|
1253 |
-
//Determine action for core admin pages
|
1254 |
-
if ( !
|
1255 |
$actions = array(
|
1256 |
'add' => array('page-new', 'post-new'),
|
1257 |
'edit-item' => array('page', 'post'),
|
@@ -1273,25 +1434,9 @@ class SLB_Utilities {
|
|
1273 |
|
1274 |
/*-** General **-*/
|
1275 |
|
1276 |
-
/**
|
1277 |
-
* Checks if last parameter sent to a function is an array of options and returns it
|
1278 |
-
* Calling function should use `func_get_args()` and pass the value to this method
|
1279 |
-
* @param array $args Parameters passed to calling function
|
1280 |
-
* @return array Options array (Default: empty array)
|
1281 |
-
*/
|
1282 |
-
function func_get_options($args) {
|
1283 |
-
$r = array();
|
1284 |
-
if ( is_array($args) && !empty($args) ) {
|
1285 |
-
$last = count($args) - 1;
|
1286 |
-
if ( is_array($args[$last]) )
|
1287 |
-
$r = $args[$last];
|
1288 |
-
}
|
1289 |
-
return $r;
|
1290 |
-
}
|
1291 |
-
|
1292 |
/**
|
1293 |
* Checks if a property exists in a class or object
|
1294 |
-
*
|
1295 |
* @param mixed $class Class or object to check
|
1296 |
* @param string $property Name of property to look for in $class
|
1297 |
*/
|
@@ -1313,13 +1458,13 @@ class SLB_Utilities {
|
|
1313 |
*/
|
1314 |
function &get_property(&$obj, $property) {
|
1315 |
$property = trim($property);
|
1316 |
-
//Object
|
1317 |
if ( is_object($obj) )
|
1318 |
return $obj->{$property};
|
1319 |
-
//Array
|
1320 |
if ( is_array($obj) )
|
1321 |
return $obj[$property];
|
1322 |
-
//Class
|
1323 |
if ( is_string($obj) && class_exists($obj) ) {
|
1324 |
$cvars = get_class_vars($obj);
|
1325 |
if ( isset($cvars[$property]) )
|
@@ -1339,23 +1484,23 @@ class SLB_Utilities {
|
|
1339 |
*/
|
1340 |
function array_remap($arr, $map = array(), $overwrite = false) {
|
1341 |
if ( !empty($map) && is_array($map) ) {
|
1342 |
-
//Iterate through mappings
|
1343 |
foreach ( $map as $from => $to ) {
|
1344 |
if ( !array_key_exists($from, $arr) )
|
1345 |
continue;
|
1346 |
$move = $overwrite;
|
1347 |
-
//Only remap if parent property doesn't already exist in array
|
1348 |
if ( !array_key_exists($to, $arr) )
|
1349 |
$move = true;
|
1350 |
if ( $move ) {
|
1351 |
-
//Move member value to new key
|
1352 |
$arr[$to] = $arr[$from];
|
1353 |
-
//Remove source member
|
1354 |
unset($arr[$from]);
|
1355 |
}
|
1356 |
}
|
1357 |
}
|
1358 |
-
//Return remapped properties
|
1359 |
return $arr;
|
1360 |
}
|
1361 |
|
@@ -1397,28 +1542,28 @@ class SLB_Utilities {
|
|
1397 |
* @return array Merged array
|
1398 |
*/
|
1399 |
function array_merge_recursive_distinct($arr1) {
|
1400 |
-
//Get all arrays passed to function
|
1401 |
$args = func_get_args();
|
1402 |
if ( empty($args) )
|
1403 |
return false;
|
1404 |
-
//Return empty array if first parameter is not an array
|
1405 |
if ( !is_array($args[0]) )
|
1406 |
return array();
|
1407 |
-
//Set first array as base array
|
1408 |
$merged = $args[0];
|
1409 |
-
//Iterate through arrays to merge
|
1410 |
$arg_length = count($args);
|
1411 |
for ( $x = 1; $x < $arg_length; $x++ ) {
|
1412 |
-
//Skip if argument is not an array (only merge arrays)
|
1413 |
if ( !is_array($args[$x]) )
|
1414 |
continue;
|
1415 |
-
//Iterate through argument items
|
1416 |
foreach ( $args[$x] as $key => $val ) {
|
1417 |
-
//Generate key for numeric indexes
|
1418 |
if ( is_int($key) ) {
|
1419 |
-
//Add new item to merged array
|
1420 |
$merged[] = null;
|
1421 |
-
//Get key of new item
|
1422 |
$key = array_pop(array_keys($merged));
|
1423 |
}
|
1424 |
if ( !isset($merged[$key]) || !is_array($merged[$key]) || !is_array($val) ) {
|
@@ -1441,13 +1586,13 @@ class SLB_Utilities {
|
|
1441 |
*/
|
1442 |
function array_replace_recursive($search, $arr_replace, $arr_subject) {
|
1443 |
foreach ($arr_subject as $key => $val) {
|
1444 |
-
//Skip element if key does not exist in the replacement array
|
1445 |
if (!isset($arr_replace[$key]))
|
1446 |
continue;
|
1447 |
-
//If element values for both arrays are strings, replace text
|
1448 |
if (is_string($val) && strpos($val, $search) !== false && is_string($arr_replace[$key]))
|
1449 |
$arr_subject[$key] = str_replace($search, $arr_replace[$key], $val);
|
1450 |
-
//If value in both arrays are arrays, recursively replace text
|
1451 |
if (is_array($val) && is_array($arr_replace[$key]))
|
1452 |
$arr_subject[$key] = $this->array_replace_recursive($search, $arr_replace[$key], $val);
|
1453 |
}
|
@@ -1466,20 +1611,6 @@ class SLB_Utilities {
|
|
1466 |
return eval('return isset($arr' . $f_path . ');');
|
1467 |
}
|
1468 |
|
1469 |
-
/**
|
1470 |
-
* Returns value of item at specified path in array
|
1471 |
-
* @param array $arr Array to get item from
|
1472 |
-
* @param array $path Array of segments that form path to array (each array item is a deeper dimension in the array)
|
1473 |
-
* @return mixed Value of item in array (Default: empty string)
|
1474 |
-
*/
|
1475 |
-
function &get_array_item(&$arr, &$path) {
|
1476 |
-
$item = '';
|
1477 |
-
if ($this->array_item_isset($arr, $path)) {
|
1478 |
-
eval('$item =& $arr' . $this->get_array_path($path) . ';');
|
1479 |
-
}
|
1480 |
-
return $item;
|
1481 |
-
}
|
1482 |
-
|
1483 |
/**
|
1484 |
* Build formatted string based on array values
|
1485 |
* Array values in formatted string will be ordered by index order
|
@@ -1488,14 +1619,14 @@ class SLB_Utilities {
|
|
1488 |
* @return string Formatted string based on array values
|
1489 |
*/
|
1490 |
function get_array_path($attribute = '', $format = null) {
|
1491 |
-
//Formatted value
|
1492 |
$fmtd = '';
|
1493 |
if (!empty($attribute)) {
|
1494 |
-
//Make sure attribute is array
|
1495 |
if (!is_array($attribute)) {
|
1496 |
$attribute = array($attribute);
|
1497 |
}
|
1498 |
-
//Format attribute
|
1499 |
$format = strtolower($format);
|
1500 |
switch ($format) {
|
1501 |
case 'id':
|
@@ -1503,14 +1634,14 @@ class SLB_Utilities {
|
|
1503 |
break;
|
1504 |
case 'metadata':
|
1505 |
case 'attribute':
|
1506 |
-
//Join segments
|
1507 |
$delim = '_';
|
1508 |
$fmtd = implode($delim, $attribute);
|
1509 |
-
//Replace white space and repeating delimiters
|
1510 |
$fmtd = str_replace(' ', $delim, $fmtd);
|
1511 |
while (strpos($fmtd, $delim.$delim) !== false)
|
1512 |
$fmtd = str_replace($delim.$delim, $delim, $fmtd);
|
1513 |
-
//Prefix formatted value with delimeter for metadata keys
|
1514 |
if ('metadata' == $format)
|
1515 |
$fmtd = $delim . $fmtd;
|
1516 |
break;
|
@@ -1533,17 +1664,17 @@ class SLB_Utilities {
|
|
1533 |
$path = array();
|
1534 |
$args = func_get_args();
|
1535 |
|
1536 |
-
//Iterate through parameters and build path
|
1537 |
foreach ( $args as $arg ) {
|
1538 |
if ( empty($arg) )
|
1539 |
continue;
|
1540 |
|
1541 |
if (is_array($arg)) {
|
1542 |
-
//Recurse through array items to pull out any more arrays
|
1543 |
foreach ($arg as $key => $val) {
|
1544 |
$path = array_merge($path, $this->build_path($val));
|
1545 |
}
|
1546 |
-
|
1547 |
} elseif ( is_scalar($arg) ) {
|
1548 |
$path[] = $arg;
|
1549 |
}
|
@@ -1552,6 +1683,51 @@ class SLB_Utilities {
|
|
1552 |
return $path;
|
1553 |
}
|
1554 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1555 |
/**
|
1556 |
* Parse string of attributes into array
|
1557 |
* For XML/XHTML tag attributes
|
@@ -1561,11 +1737,11 @@ class SLB_Utilities {
|
|
1561 |
function parse_attribute_string($txt, $defaults = array()) {
|
1562 |
$txt = trim($txt, ' >');
|
1563 |
$matches = $attr = array();
|
1564 |
-
//Strip tag
|
1565 |
if ( $txt[0] == '<' && ($s = strpos($txt, ' ')) && $s !== false ) {
|
1566 |
$txt = trim(substr($txt, $s + 1));
|
1567 |
}
|
1568 |
-
//Parse attributes
|
1569 |
$rgx = "/\b(\w+.*?)=([\"'])(.*?)\\2(?:\s|$)/i";
|
1570 |
preg_match_all($rgx, $txt, $matches);
|
1571 |
if ( count($matches) > 3 ) {
|
@@ -1574,7 +1750,7 @@ class SLB_Utilities {
|
|
1574 |
$attr[trim($val)] = trim($matches[3][$sub_idx]);
|
1575 |
}
|
1576 |
}
|
1577 |
-
//Destroy parsing vars
|
1578 |
unset($txt, $matches);
|
1579 |
|
1580 |
return array_merge($defaults, $attr);
|
@@ -1587,9 +1763,10 @@ class SLB_Utilities {
|
|
1587 |
*/
|
1588 |
function build_attribute_string($attr) {
|
1589 |
$ret = '';
|
1590 |
-
if ( is_object($attr) )
|
1591 |
$attr = (array) $attr;
|
1592 |
-
|
|
|
1593 |
array_map('esc_attr', $attr);
|
1594 |
$attr_str = array();
|
1595 |
foreach ( $attr as $key => $val ) {
|
@@ -1600,6 +1777,36 @@ class SLB_Utilities {
|
|
1600 |
return $ret;
|
1601 |
}
|
1602 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1603 |
function build_html_link($uri, $content, $attributes = array()) {
|
1604 |
$attributes = array_merge(array('href' => $uri, 'title' => $content), $attributes);
|
1605 |
return $this->build_html_element(array('tag' => 'a', 'wrap' => true, 'content' => $content, 'attributes' => $attributes));
|
@@ -1610,7 +1817,7 @@ class SLB_Utilities {
|
|
1610 |
* @param $url Stylesheet URL
|
1611 |
* @return string Stylesheet element
|
1612 |
*/
|
1613 |
-
function build_stylesheet_element($url
|
1614 |
$attributes = array('href' => $url, 'type' => 'text/css', 'rel' => 'stylesheet');
|
1615 |
return $this->build_html_element(array('tag' => 'link', 'wrap' => false, 'attributes' => $attributes));
|
1616 |
}
|
@@ -1624,9 +1831,9 @@ class SLB_Utilities {
|
|
1624 |
* @param bool $wait_doc_ready (optional) Wait until document is fully loaded before executing commands? (Default: No)
|
1625 |
*/
|
1626 |
function build_script_element($content = '', $id = '', $wrap_jquery = true, $wait_doc_ready = false) {
|
1627 |
-
//Stop processing invalid content
|
1628 |
if ( is_array($content) && !empty($content) ) {
|
1629 |
-
$content = implode(PHP_EOL, $content);
|
1630 |
}
|
1631 |
if ( empty($content) || !is_string($content) ) {
|
1632 |
return '';
|
@@ -1635,269 +1842,22 @@ class SLB_Utilities {
|
|
1635 |
$start = array('/* <![CDATA[ */');
|
1636 |
$end = array('/* ]]> */');
|
1637 |
if ( $wrap_jquery ) {
|
1638 |
-
$start[] = '(function($){';
|
1639 |
-
$end[] = '})(jQuery);';
|
1640 |
|
1641 |
-
//Add event handler (if necessary)
|
1642 |
if ( $wait_doc_ready ) {
|
1643 |
$start[] = '$(document).ready(function(){';
|
1644 |
$end[] = '})';
|
1645 |
}
|
1646 |
}
|
1647 |
|
1648 |
-
//Reverse order of end values
|
1649 |
$end = array_reverse($end);
|
1650 |
$content = implode('', array_merge($start, array($content), $end));
|
1651 |
if ( is_string($id) && !empty($id) ) {
|
1652 |
$attributes['id'] = $this->add_prefix($id);
|
1653 |
}
|
1654 |
-
return $this->build_html_element(array('tag' => 'script', 'content' => $content, 'attributes' => $attributes)) . PHP_EOL;
|
1655 |
-
}
|
1656 |
-
|
1657 |
-
/**
|
1658 |
-
* Generate external script element
|
1659 |
-
* @param $url Script URL
|
1660 |
-
* @return string Script element
|
1661 |
-
*/
|
1662 |
-
function build_ext_script_element($url = '') {
|
1663 |
-
$attributes = array('src' => $url, 'type' => 'text/javascript');
|
1664 |
-
return $this->build_html_element(array('tag' => 'script', 'attributes' => $attributes)) . PHP_EOL;
|
1665 |
-
}
|
1666 |
-
|
1667 |
-
/**
|
1668 |
-
* Generate HTML element based on values
|
1669 |
-
* @param $args Element arguments
|
1670 |
-
* @return string Generated HTML element
|
1671 |
-
*/
|
1672 |
-
function build_html_element($args) {
|
1673 |
-
$defaults = array(
|
1674 |
-
'tag' => 'span',
|
1675 |
-
'wrap' => true,
|
1676 |
-
'content' => '',
|
1677 |
-
'attributes' => array()
|
1678 |
-
);
|
1679 |
-
$el_start = '<';
|
1680 |
-
$el_end = '>';
|
1681 |
-
$el_close = '/';
|
1682 |
-
$args = wp_parse_args($args, $defaults);
|
1683 |
-
//Collect attributes
|
1684 |
-
$attr_exclude = array( 'content', 'tag', 'wrap', 'attributes' );
|
1685 |
-
$attr_extra = array_diff_key($args, array_fill_keys($attr_exclude, null));
|
1686 |
-
if ( count($attr_extra) ) {
|
1687 |
-
//Merge attributes
|
1688 |
-
$args['attributes'] = wp_parse_args($attr_extra, $args['attributes']);
|
1689 |
-
//Remove attributes from top-level arguments
|
1690 |
-
$args = array_diff_key($args, $attr_extra);
|
1691 |
-
}
|
1692 |
-
extract($args, EXTR_SKIP);
|
1693 |
-
$content = trim($content);
|
1694 |
-
|
1695 |
-
|
1696 |
-
if ( !$wrap && strlen($content) > 0 )
|
1697 |
-
$wrap = true;
|
1698 |
-
|
1699 |
-
$attributes = $this->build_attribute_string($attributes);
|
1700 |
-
if ( strlen($attributes) > 0 )
|
1701 |
-
$attributes = ' ' . $attributes;
|
1702 |
-
|
1703 |
-
$ret = $el_start . $tag . $attributes;
|
1704 |
-
|
1705 |
-
if ( $wrap )
|
1706 |
-
$ret .= $el_end . $content . $el_start . $el_close . $tag;
|
1707 |
-
else
|
1708 |
-
$ret .= ' ' . $el_close;
|
1709 |
-
|
1710 |
-
$ret .= $el_end;
|
1711 |
-
return $ret;
|
1712 |
-
}
|
1713 |
-
|
1714 |
-
/*-** Admin **-*/
|
1715 |
-
|
1716 |
-
/**
|
1717 |
-
* Add submenu page in the admin menu
|
1718 |
-
* Adds ability to set the position of the page in the menu
|
1719 |
-
* @see add_submenu_page (Wraps functionality)
|
1720 |
-
*
|
1721 |
-
* @param $parent
|
1722 |
-
* @param $page_title
|
1723 |
-
* @param $menu_title
|
1724 |
-
* @param $access_level
|
1725 |
-
* @param $file
|
1726 |
-
* @param $function
|
1727 |
-
* @param int $pos Index position of menu page
|
1728 |
-
*
|
1729 |
-
* @global array $submenu Admin page submenus
|
1730 |
-
*/
|
1731 |
-
function add_submenu_page($parent, $page_title, $menu_title, $capability, $file, $function = '', $pos = false) {
|
1732 |
-
//Add submenu page as usual
|
1733 |
-
$args = func_get_args();
|
1734 |
-
$hookname = call_user_func_array('add_submenu_page', $args);
|
1735 |
-
if ( is_int($pos) ) {
|
1736 |
-
global $submenu;
|
1737 |
-
//Get last submenu added
|
1738 |
-
$parent = $this->get_submenu_parent_file($parent);
|
1739 |
-
if ( isset($submenu[$parent]) ) {
|
1740 |
-
$subs =& $submenu[$parent];
|
1741 |
-
|
1742 |
-
//Make sure menu isn't already in the desired position
|
1743 |
-
if ( $pos <= ( count($subs) - 1 ) ) {
|
1744 |
-
//Get submenu that was just added
|
1745 |
-
$sub = array_pop($subs);
|
1746 |
-
//Insert into desired position
|
1747 |
-
if ( 0 == $pos ) {
|
1748 |
-
array_unshift($subs, $sub);
|
1749 |
-
} else {
|
1750 |
-
$top = array_slice($subs, 0, $pos);
|
1751 |
-
$bottom = array_slice($subs, $pos);
|
1752 |
-
array_push($top, $sub);
|
1753 |
-
$subs = array_merge($top, $bottom);
|
1754 |
-
}
|
1755 |
-
}
|
1756 |
-
}
|
1757 |
-
}
|
1758 |
-
|
1759 |
-
return $hookname;
|
1760 |
-
}
|
1761 |
-
|
1762 |
-
/**
|
1763 |
-
* Remove admin submenu
|
1764 |
-
* @param string $parent Submenu parent file
|
1765 |
-
* @param string $file Submenu file name
|
1766 |
-
* @return int|null Index of removed submenu (NULL if submenu not found)
|
1767 |
-
*
|
1768 |
-
* @global array $submenu
|
1769 |
-
* @global array $_registered_pages
|
1770 |
-
*/
|
1771 |
-
function remove_submenu_page($parent, $file) {
|
1772 |
-
global $submenu, $_registered_pages;
|
1773 |
-
$ret = null;
|
1774 |
-
|
1775 |
-
$parent = $this->get_submenu_parent_file($parent);
|
1776 |
-
$file = plugin_basename($file);
|
1777 |
-
$file_index = 2;
|
1778 |
-
|
1779 |
-
//Find submenu
|
1780 |
-
if ( isset($submenu[$parent]) ) {
|
1781 |
-
$subs =& $submenu[$parent];
|
1782 |
-
for ($x = 0; $x < count($subs); $x++) {
|
1783 |
-
if ( $subs[$x][$file_index] == $file ) {
|
1784 |
-
//Remove matching submenu
|
1785 |
-
$hookname = get_plugin_page_hookname($file, $parent);
|
1786 |
-
remove_all_actions($hookname);
|
1787 |
-
unset($_registered_pages[$hookname]);
|
1788 |
-
unset($subs[$x]);
|
1789 |
-
$subs = array_values($subs);
|
1790 |
-
//Set index and stop processing
|
1791 |
-
$ret = $x;
|
1792 |
-
break;
|
1793 |
-
}
|
1794 |
-
}
|
1795 |
-
}
|
1796 |
-
|
1797 |
-
return $ret;
|
1798 |
-
}
|
1799 |
-
|
1800 |
-
/**
|
1801 |
-
* Replace a submenu page
|
1802 |
-
* Adds a submenu page in the place of an existing submenu page that has the same $file value
|
1803 |
-
*
|
1804 |
-
* @param $parent
|
1805 |
-
* @param $page_title
|
1806 |
-
* @param $menu_title
|
1807 |
-
* @param $access_level
|
1808 |
-
* @param $file
|
1809 |
-
* @param $function
|
1810 |
-
* @return string Hookname
|
1811 |
-
*
|
1812 |
-
* @global array $submenu
|
1813 |
-
*/
|
1814 |
-
function replace_submenu_page($parent, $page_title, $menu_title, $access_level, $file, $function = '') {
|
1815 |
-
global $submenu;
|
1816 |
-
//Remove matching submenu (if exists)
|
1817 |
-
$pos = $this->remove_submenu_page($parent, $file);
|
1818 |
-
//Insert submenu page
|
1819 |
-
$hookname = $this->add_submenu_page($parent, $page_title, $menu_title, $access_level, $file, $function, $pos);
|
1820 |
-
return $hookname;
|
1821 |
-
}
|
1822 |
-
|
1823 |
-
/**
|
1824 |
-
* Retrieves parent file for submenu
|
1825 |
-
* @param string $parent Parent file
|
1826 |
-
* @return string Formatted parent file name
|
1827 |
-
*
|
1828 |
-
* @global array $_wp_real_parent_file;
|
1829 |
-
*/
|
1830 |
-
function get_submenu_parent_file($parent) {
|
1831 |
-
global $_wp_real_parent_file;
|
1832 |
-
$parent = plugin_basename($parent);
|
1833 |
-
if ( isset($_wp_real_parent_file[$parent]) )
|
1834 |
-
$parent = $_wp_real_parent_file[$parent];
|
1835 |
-
return $parent;
|
1836 |
-
}
|
1837 |
-
|
1838 |
-
/* Shortcodes */
|
1839 |
-
|
1840 |
-
/**
|
1841 |
-
* Generate shortcode to be used in content
|
1842 |
-
* @param string $tag Shortcode tag
|
1843 |
-
* @param array $attr Associative array of attributes
|
1844 |
-
* @return string Shortcode markup
|
1845 |
-
*/
|
1846 |
-
public function make_shortcode($tag, $attr = array()) {
|
1847 |
-
return '[' . $tag . ']';
|
1848 |
-
}
|
1849 |
-
|
1850 |
-
/**
|
1851 |
-
* Build shortcode regex pattern for specific shortcode
|
1852 |
-
* @uses $shortcode_tags
|
1853 |
-
* @param string $tag Shortcode tag
|
1854 |
-
* @return string Shortcode regex pattern
|
1855 |
-
*/
|
1856 |
-
public function get_shortcode_regex($tag) {
|
1857 |
-
global $shortcode_tags;
|
1858 |
-
//Backup shortcodes
|
1859 |
-
$tgs_temp = $shortcode_tags;
|
1860 |
-
$ret = '';
|
1861 |
-
if ( !is_string($tag) || empty($tag) ) {
|
1862 |
-
return $ret;
|
1863 |
-
}
|
1864 |
-
//Modify
|
1865 |
-
$shortcode_tags = array( $tag => null );
|
1866 |
-
//Build pattern
|
1867 |
-
$ret = get_shortcode_regex();
|
1868 |
-
//Restore shortcodes
|
1869 |
-
$shortcode_tags = $tgs_temp;
|
1870 |
-
|
1871 |
-
return $ret;
|
1872 |
-
}
|
1873 |
-
/**
|
1874 |
-
* Check if content contains shortcode
|
1875 |
-
* @param string $tag Name of shortcode to check for
|
1876 |
-
* @param string $content Content to check for shortcode
|
1877 |
-
* @return bool TRUE if content contains shortcode
|
1878 |
-
*/
|
1879 |
-
public function has_shortcode($content, $tag) {
|
1880 |
-
$ptn = $this->get_shortcode_regex($tag);
|
1881 |
-
$ret = ( is_string($content) && preg_match("/$ptn/s", $content) == 1 ) ? true : false;
|
1882 |
-
return $ret;
|
1883 |
-
}
|
1884 |
-
|
1885 |
-
/**
|
1886 |
-
* Add shortcode to content
|
1887 |
-
* @param string $content Content to add shortcode to
|
1888 |
-
* @param bool $in_footer (optional) Add shortcode to head or footer of content (Default: footer)
|
1889 |
-
* @return string Modified content
|
1890 |
-
*/
|
1891 |
-
public function add_shortcode($content, $tag, $attr = null, $in_footer = true) {
|
1892 |
-
if ( !is_string($content) ) {
|
1893 |
-
$content = '';
|
1894 |
-
}
|
1895 |
-
$sc = $this->make_shortcode($tag, $attr);
|
1896 |
-
if ( !!$in_footer ) {
|
1897 |
-
$content .= $sc;
|
1898 |
-
} else {
|
1899 |
-
$content = $sc . $content;
|
1900 |
-
}
|
1901 |
-
return $content;
|
1902 |
}
|
1903 |
}
|
16 |
* Instance parent
|
17 |
* @var object
|
18 |
*/
|
19 |
+
private $_parent = null;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Plugin Base
|
23 |
+
* @var string
|
24 |
+
*/
|
25 |
+
private $_plugin = array(
|
26 |
+
'base' => null,
|
27 |
+
'file' => null,
|
28 |
+
'name' => null,
|
29 |
+
'data' => null,
|
30 |
+
'uri' => null,
|
31 |
+
'headers' => array (
|
32 |
+
'Name' => 'Plugin Name',
|
33 |
+
'PluginURI' => 'Plugin URI',
|
34 |
+
'SupportURI' => 'Support URI',
|
35 |
+
'Version' => 'Version',
|
36 |
+
'Description' => 'Description',
|
37 |
+
'Author' => 'Author',
|
38 |
+
'AuthorURI' => 'Author URI',
|
39 |
+
)
|
40 |
+
);
|
41 |
|
42 |
/**
|
43 |
+
* Plugin base path
|
44 |
+
* @var string
|
45 |
*/
|
46 |
+
private $_path_base = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
|
48 |
/**
|
49 |
* Standard hook priorities
|
50 |
* @var array
|
51 |
*/
|
52 |
+
private $_priorities = array (
|
53 |
'high' => 1,
|
54 |
'low' => 99,
|
55 |
'safe' => 15,
|
58 |
|
59 |
/* Constructors */
|
60 |
|
61 |
+
function __construct($obj) {
|
62 |
+
if ( is_object($obj) ) {
|
63 |
+
$this->_parent = $obj;
|
64 |
+
}
|
65 |
}
|
66 |
|
67 |
/**
|
104 |
*/
|
105 |
function get_prefix($sep = null) {
|
106 |
$sep = $this->get_sep($sep);
|
107 |
+
$prefix = ( !empty($this->_parent->prefix) ) ? $this->_parent->prefix . $sep : '';
|
108 |
return $prefix;
|
109 |
}
|
110 |
|
111 |
/**
|
112 |
* Check if a string is prefixed
|
113 |
+
* @param string|array $text Text to check for prefix
|
114 |
* @param string $sep (optional) Separator used
|
115 |
*/
|
116 |
function has_prefix($text, $sep = null) {
|
117 |
+
if ( empty($text) )
|
118 |
+
return false;
|
119 |
+
if ( !is_array($text) )
|
120 |
+
$text = array($text);
|
121 |
+
$text = array_values($text);
|
122 |
+
$text = $text[0];
|
123 |
return ( !empty($text) && stripos($text, $this->get_prefix($sep)) === 0 );
|
124 |
}
|
125 |
|
126 |
/**
|
127 |
* Prepend plugin prefix to some text
|
128 |
+
* @param string|array $text Text to add to prefix
|
129 |
* @param string $sep (optional) Text used to separate prefix and text
|
130 |
* @param bool $once (optional) Whether to add prefix to text that already contains a prefix or not
|
131 |
* @return string Text with prefix prepended
|
132 |
*/
|
133 |
function add_prefix($text, $sep = '_', $once = true) {
|
134 |
+
// Normalize data type (array)
|
135 |
+
if ( empty($text) )
|
136 |
+
$text = array('');
|
137 |
+
if ( !is_array($text) )
|
138 |
+
$text = array($text);
|
139 |
+
// Add prefix (if necessary)
|
140 |
+
if ( !$once || ( $once && !$this->has_prefix($text, $sep) ) )
|
141 |
+
array_unshift($text, $this->get_prefix());
|
142 |
+
return implode($sep, $text);
|
143 |
}
|
144 |
|
145 |
/**
|
146 |
* Prepend uppercased plugin prefix to some text
|
147 |
+
* @param string|array $text Text to add to prefix
|
148 |
* @param string $sep (optional) Text used to separate prefix and text
|
149 |
* @param bool $once (optional) Whether to add prefix to text that already contains a prefix or not
|
150 |
* @return string Text with prefix prepended
|
199 |
*/
|
200 |
public function priority($id = null) {
|
201 |
$pri = 10;
|
202 |
+
if ( !is_null($id) && array_key_exists($id, $this->_priorities) ) {
|
203 |
+
$pri = $this->_priorities[$id];
|
204 |
}
|
205 |
return $pri;
|
206 |
}
|
208 |
/* Wrapped Values */
|
209 |
|
210 |
/**
|
211 |
+
* Create wrapper object
|
212 |
+
* Properties
|
213 |
+
* > start
|
214 |
+
* > end
|
215 |
* @param string|array $start Start text (Can also be array defining start & end values)
|
216 |
* @param string $end (optional) End text
|
217 |
* If $end not defined, then $start is used
|
218 |
* @return obj Wrapper
|
219 |
*/
|
220 |
function get_wrapper($start = null, $end = null) {
|
221 |
+
// Validate existing wrapper
|
222 |
if ( is_object($start) && isset($start->start) && isset($start->end) )
|
223 |
return $start;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
224 |
|
225 |
+
// Initialize wrapper
|
226 |
+
$w = array (
|
227 |
+
'start' => '[',
|
228 |
+
'end' => ']',
|
229 |
+
);
|
230 |
+
|
231 |
+
if ( !empty($start) ) {
|
232 |
+
if ( is_string($start) ) {
|
233 |
+
$w['start'] = $start;
|
234 |
+
} elseif ( is_array($start) ) {
|
235 |
+
$start = array_values($start);
|
236 |
+
if ( is_string($start) ) {
|
237 |
+
$w['start'] = $start[0];
|
238 |
+
}
|
239 |
+
if ( isset($start[1]) && is_string($start[1]) ) {
|
240 |
+
$w['end'] = $start[1];
|
241 |
+
}
|
242 |
+
}
|
243 |
+
}
|
244 |
+
if ( is_string($end) ) {
|
245 |
+
$w['end'] = $end;
|
246 |
+
}
|
247 |
+
|
248 |
+
return (object) $w;
|
249 |
}
|
250 |
|
251 |
/**
|
258 |
function has_wrapper($text, $start = null, $end = null) {
|
259 |
if ( !is_string($text) || empty($text) )
|
260 |
return false;
|
261 |
+
// Validate wrapper
|
262 |
$w = $this->get_wrapper($start, $end);
|
263 |
|
264 |
+
// Check for wrapper
|
265 |
+
return ( substr($text, 0, strlen($w->start)) == $w->start && substr($text, -1, strlen($w->end)) == $w->end ) ? true : false;
|
266 |
}
|
267 |
|
268 |
/**
|
285 |
|
286 |
/**
|
287 |
* Add wrapper to specified text
|
288 |
+
* @uses Utilities::get_wrapper() to retrieve wrapper object
|
289 |
* @param string $text Text to wrap
|
290 |
* @param string|array $start (optional) Start text (Array defines both start/end text)
|
291 |
* @param string $end (optional) End text
|
322 |
*/
|
323 |
function parse_client_files($files, $type = 'scripts') {
|
324 |
if ( is_array($files) && !empty($files) ) {
|
325 |
+
// Defaults
|
326 |
$defaults = array(
|
327 |
'file' => null,
|
328 |
'deps' => array(),
|
329 |
'callback' => null,
|
330 |
'context' => array(),
|
331 |
'enqueue' => true,
|
332 |
+
'enqueued' => false
|
333 |
);
|
334 |
switch ( $type ) {
|
335 |
case 'styles':
|
338 |
default:
|
339 |
$defaults['in_footer'] = false;
|
340 |
}
|
341 |
+
// Iterate through files
|
342 |
+
/**
|
343 |
+
* $h (string) handle
|
344 |
+
* $p (array) properties
|
345 |
+
*/
|
346 |
foreach ( $files as $h => $p ) {
|
347 |
unset($file, $cb, $ctxs, $ctx);
|
348 |
+
// Set ID
|
349 |
$p['id'] = $this->add_prefix($h);
|
350 |
+
// Type Validation
|
351 |
+
/**
|
352 |
+
* $m (string) property name
|
353 |
+
* $d (mixed) default value
|
354 |
+
*/
|
355 |
foreach ( $defaults as $m => $d ) {
|
356 |
+
// Check if value requires validation
|
357 |
if ( !is_array($d) || !isset($p[$m]) || is_array($p[$m]) )
|
358 |
continue;
|
359 |
+
// Wrap value in array or destroy it
|
360 |
if ( is_scalar($p[$m]) )
|
361 |
$p[$m] = array($p[$m]);
|
362 |
else
|
363 |
unset($p[$m]);
|
364 |
}
|
365 |
|
366 |
+
// Normalize file properties
|
367 |
$p = array_merge($defaults, $p);
|
368 |
|
369 |
/* File name */
|
370 |
|
371 |
+
// Validate file
|
372 |
$file =& $p['file'];
|
373 |
|
374 |
+
// Determine if filename or callback
|
375 |
if ( !$this->is_file($file) )
|
376 |
+
$file = ( is_callable($file) ) ? $file : null;
|
377 |
+
// Remove invalid file and move on to next
|
378 |
if ( empty($file) ) {
|
379 |
unset($files[$h]);
|
380 |
continue;
|
382 |
|
383 |
/* Dependencies */
|
384 |
|
385 |
+
// Format internal dependencies
|
386 |
foreach ( $p['deps'] as $idx => $dep ) {
|
387 |
if ( $this->has_wrapper($dep) ) {
|
388 |
$dep = $this->remove_wrapper($dep);
|
392 |
|
393 |
/* Context */
|
394 |
|
395 |
+
// Validate callback
|
396 |
$cb =& $p['callback'];
|
397 |
+
if ( !is_null($cb) && !is_callable($cb) ) {
|
398 |
+
// Remove files with invalid callbacks (will never be loaded)
|
399 |
+
unset($files[$h]);
|
400 |
+
continue;
|
|
|
|
|
|
|
401 |
}
|
402 |
|
403 |
+
// Validate contexts
|
404 |
$ctxs =& $p['context'];
|
405 |
$ctxs = array_unique($ctxs);
|
406 |
$has_contexts = ( count($ctxs) > 0 ) ? true : false;
|
407 |
foreach ( $ctxs as $idx => $ctx ) {
|
408 |
+
// Convert to array
|
409 |
$ctx = array_values( array_slice( (array) $ctx, 0, 2 ) );
|
410 |
switch ( count($ctx) ) {
|
411 |
case 1 :
|
412 |
+
// Simple context
|
413 |
$ctx = $ctx[0];
|
414 |
break;
|
415 |
case 2 :
|
416 |
+
// Context + Callback
|
417 |
+
if ( is_callable($ctx[1]) ) {
|
|
|
418 |
break;
|
419 |
}
|
420 |
+
// Continue to default case if callback is invalid
|
421 |
default :
|
422 |
+
// Context is invalid
|
423 |
$ctx = false;
|
424 |
break;
|
425 |
}
|
426 |
|
427 |
+
// Remove invalid contexts
|
428 |
if ( empty($ctx) ) {
|
429 |
unset($ctxs[$idx]);
|
430 |
} else {
|
431 |
$ctxs[$idx] = $ctx;
|
432 |
}
|
433 |
}
|
434 |
+
// Remove file if all specified contexts invalid (no context is OK)
|
435 |
if ( $has_contexts && empty($ctxs) ) {
|
436 |
unset($files[$h]);
|
437 |
continue;
|
440 |
|
441 |
/* Finalize Properties */
|
442 |
|
443 |
+
// Convert properties to object
|
444 |
$files[$h] = (object) $p;
|
445 |
}
|
446 |
}
|
447 |
+
// Cast to object before returning
|
448 |
$files = (object) $files;
|
449 |
return $files;
|
450 |
}
|
451 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
452 |
/**
|
453 |
* Build JS client object
|
454 |
* @param string (optional) $path Additional object path
|
472 |
* @return string JS expression to extend client object
|
473 |
*/
|
474 |
function extend_client_object($obj, $data = null, $out = false) {
|
475 |
+
// Validate parameters
|
476 |
$args = func_get_args();
|
477 |
switch ( count($args) ) {
|
478 |
case 2:
|
487 |
$obj = null;
|
488 |
break;
|
489 |
}
|
490 |
+
// Default client object
|
491 |
if ( !is_string($obj) || empty($obj) )
|
492 |
$obj = null;
|
493 |
+
// Default data
|
494 |
if ( is_array($data) ) {
|
495 |
$data = (object)$data;
|
496 |
}
|
497 |
+
// Build expression
|
498 |
if ( empty($data) || ( empty($obj) && is_scalar($data) ) ) {
|
499 |
$ret = '';
|
500 |
} else {
|
515 |
* If no command is specified the validation conditions are returned
|
516 |
*/
|
517 |
public function validate_client_object($obj, $cmd = null) {
|
518 |
+
// Get base object
|
519 |
+
$base = $this->get_client_object();
|
520 |
+
|
521 |
+
// Build condition
|
522 |
$sep = '.';
|
523 |
+
$obj = trim($obj, $sep);
|
524 |
+
// Strip base object
|
525 |
+
if ( 0 === strpos($obj, $base . $sep) ) {
|
526 |
+
$obj = substr($obj, strlen($base . $sep));
|
527 |
+
}
|
528 |
+
$fmt = '!!window.%1$s';
|
529 |
+
if ( !empty($obj) ) {
|
530 |
+
$fmt .= ' && %1$s.has_child(\'%2$s\')';
|
531 |
+
}
|
532 |
+
$condition = sprintf($fmt, $base, $obj);
|
|
|
|
|
|
|
533 |
|
534 |
+
// Wrap command in validation
|
535 |
+
if ( !empty($cmd) && is_string($cmd) ) {
|
536 |
$condition = sprintf('if ( %1$s ) { %2$s }', $condition, $cmd);
|
537 |
}
|
538 |
return $condition;
|
555 |
$encode = !!$encode;
|
556 |
$validate = !!$validate;
|
557 |
|
558 |
+
// Build parameters
|
559 |
if ( !is_null($params) ) {
|
560 |
if ( $encode ) {
|
561 |
$params = json_encode($params);
|
599 |
return true;
|
600 |
}
|
601 |
|
|
|
602 |
|
603 |
/**
|
604 |
* Retrieve parent object
|
605 |
* @return obj|bool Parent object (FALSE if no valid parent set)
|
606 |
*/
|
607 |
+
function get_parent() {
|
608 |
+
if ( is_object($this->_parent) ) {
|
609 |
+
return $this->_parent;
|
610 |
+
} else {
|
611 |
+
return false;
|
612 |
+
}
|
613 |
}
|
614 |
|
615 |
/**
|
620 |
* @return mixed Parent property value
|
621 |
*/
|
622 |
function get_parent_property($prop, $default = '') {
|
623 |
+
$p = $this->get_parent();
|
624 |
return ( !!$p && property_exists($p, $prop) ) ? $p->{$prop} : $default;
|
625 |
+
}
|
626 |
+
|
627 |
+
/* Hooks */
|
628 |
|
629 |
/**
|
630 |
* Retrieve formatted name for internal hooks
|
632 |
* @uses self::get_parent_property() to retrieve hook prefix
|
633 |
* @uses self::add_prefix()
|
634 |
* @param string $tag Base tag
|
635 |
+
* @param bool|string $hook_prefix (optional) Secondary prefix to use for hook (Default: Use predefined hook name, FALSE: no secondary hook)
|
636 |
* @return string Formatted hook
|
637 |
*/
|
638 |
+
function get_hook($tag, $hook_prefix = true) {
|
639 |
+
// Hook prefix
|
640 |
+
$hook = '';
|
641 |
+
if ( is_bool($hook_prefix) && $hook_prefix ) {
|
642 |
+
$hook = $this->get_parent_property('hook_prefix', '');
|
643 |
+
} elseif ( is_string($hook_prefix) ) {
|
644 |
+
$hook = $hook_prefix;
|
645 |
+
}
|
646 |
if ( !empty($hook) )
|
647 |
$hook .= '_';
|
648 |
+
// Prefix
|
649 |
return $this->add_prefix($hook . $tag);
|
650 |
}
|
651 |
|
654 |
* Namespaces $tag
|
655 |
* @uses self::get_hook()
|
656 |
* @see do_action()
|
657 |
+
* @param string|array $tag Action hook. If array, get hook prefix
|
658 |
*/
|
659 |
function do_action($tag, $arg = '') {
|
660 |
+
// Handle hook prefix
|
661 |
+
$hook_prefix = true;
|
662 |
+
if ( is_array($tag) ) {
|
663 |
+
$hook_prefix = $tag[1];
|
664 |
+
$tag = $tag[0];
|
665 |
+
}
|
666 |
$args = func_get_args();
|
667 |
+
$args[0] = $this->get_hook($tag, $hook_prefix);
|
668 |
return call_user_func_array('do_action', $args);
|
669 |
}
|
670 |
|
671 |
/**
|
672 |
* Run internal action passing arguments in array
|
673 |
* @uses do_action_ref_array()
|
674 |
+
* @param bool|string $hook_prefix (optional) Secondary prefix to use for hook (Default: Use predefined hook name, FALSE: no secondary hook)
|
675 |
*/
|
676 |
+
function do_action_ref_array($tag, $args, $hook_prefix = true) {
|
677 |
+
return do_action_ref_array($this->get_hook($tag, $hook_prefix), $args);
|
678 |
}
|
679 |
|
680 |
/**
|
682 |
* Namespaces $tag
|
683 |
* @uses self::get_hook()
|
684 |
* @see apply_filters()
|
685 |
+
* @param string|array $tag Action hook. If array, get hook prefix
|
686 |
*/
|
687 |
function apply_filters($tag, $value) {
|
688 |
+
// Handle hook prefix
|
689 |
+
$hook_prefix = true;
|
690 |
+
if ( is_array($tag) ) {
|
691 |
+
$hook_prefix = $tag[1];
|
692 |
+
$tag = $tag[0];
|
693 |
+
}
|
694 |
$args = func_get_args();
|
695 |
+
$args[0] = $this->get_hook($tag, $hook_prefix);
|
696 |
return call_user_func_array('apply_filters', $args);
|
697 |
}
|
698 |
|
699 |
/**
|
700 |
* Run internal filter passing arguments in array
|
701 |
* @uses apply_filters_ref_array()
|
702 |
+
* @param bool|string $hook_prefix (optional) Secondary prefix to use for hook (Default: Use predefined hook name, FALSE: no secondary hook)
|
703 |
*/
|
704 |
+
function apply_filters_ref_array($tag, $args, $hook_prefix = true) {
|
705 |
+
return apply_filters_ref_array($this->get_hook($tag, $hook_prefix), $args);
|
706 |
}
|
707 |
|
708 |
/**
|
710 |
* Namespaces $tag
|
711 |
* @uses self::get_hook()
|
712 |
* @see add_action()
|
713 |
+
* @param bool|string $hook_prefix (optional) Secondary prefix to use for hook (Default: Use predefined hook name, FALSE: no secondary hook)
|
714 |
*/
|
715 |
+
function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1, $hook_prefix = true) {
|
716 |
+
return add_action($this->get_hook($tag, $hook_prefix), $function_to_add, $priority, $accepted_args);
|
717 |
}
|
718 |
|
719 |
/**
|
721 |
* Namespaces $tag
|
722 |
* @uses self::get_hook()
|
723 |
* @see add_filter()
|
724 |
+
* @param bool|string $hook_prefix (optional) Secondary prefix to use for hook (Default: Use predefined hook name, FALSE: no secondary hook)
|
725 |
*/
|
726 |
+
function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1, $hook_prefix = true) {
|
727 |
+
return add_filter($this->get_hook($tag, $hook_prefix), $function_to_add, $priority, $accepted_args);
|
728 |
}
|
729 |
|
730 |
/**
|
732 |
* Namespaces $tag
|
733 |
* @uses self::get_hook()
|
734 |
* @uses remove_action()
|
735 |
+
* @param bool|string $hook_prefix (optional) Secondary prefix to use for hook (Default: Use predefined hook name, FALSE: no secondary hook)
|
736 |
*/
|
737 |
+
function remove_action($tag, $function_to_remove, $priority = 10, $accepted_args = 1, $hook_prefix = true) {
|
738 |
+
return remove_action($this->get_hook($tag, $hook_prefix), $function_to_remove, $priority, $accepted_args);
|
739 |
}
|
740 |
|
741 |
/**
|
743 |
* Namespaces $tag
|
744 |
* @uses self::get_hook()
|
745 |
* @uses remove_filter()
|
746 |
+
* @param bool|string $hook_prefix (optional) Secondary prefix to use for hook (Default: Use predefined hook name, FALSE: no secondary hook)
|
747 |
*/
|
748 |
+
function remove_filter($tag, $function_to_remove, $priority = 10, $accepted_args = 1, $hook_prefix = true) {
|
749 |
+
return remove_filter($this->get_hook($tag, $hook_prefix), $function_to_remove, $priority, $accepted_args);
|
750 |
+
}
|
751 |
+
|
752 |
+
/* Shortcode */
|
753 |
+
|
754 |
+
/**
|
755 |
+
* Process specific shortcode(s) in content
|
756 |
+
* Default: Process all existing shortcodes
|
757 |
+
* @uses $shortcode_tags - array tag => callback
|
758 |
+
* @uses do_shortcode()
|
759 |
+
*
|
760 |
+
* @param string $content Content to process for shortcodes
|
761 |
+
* @param string|array $shortcode Single tag or array of tags to process
|
762 |
+
* > Associative array sets temporary callbacks for shortcodes (`tag => callback`)
|
763 |
+
*/
|
764 |
+
public function do_shortcode($content, $shortcode = null) {
|
765 |
+
global $shortcode_tags;
|
766 |
+
|
767 |
+
// Process custom shortcodes
|
768 |
+
if ( !is_null($shortcode) ) {
|
769 |
+
// Cast to array
|
770 |
+
$shortcode = (array) $shortcode;
|
771 |
+
// Backup and reset shortcode handlers
|
772 |
+
$tags_temp = $shortcode_tags;
|
773 |
+
$shortcode_tags = array();
|
774 |
+
// Register specified tags
|
775 |
+
foreach ( $shortcode as $key => $val ) {
|
776 |
+
if ( is_string($key) && is_callable($val) ) {
|
777 |
+
// Tag w/custom callback
|
778 |
+
$shortcode_tags[$key] = $val;
|
779 |
+
} elseif ( is_int($key) && is_string($val) && isset($tags_temp[$val]) ) {
|
780 |
+
// Tag with default callback
|
781 |
+
$shortcode_tags[$val] = $tags_temp[$val];
|
782 |
+
}
|
783 |
+
}
|
784 |
+
}
|
785 |
+
|
786 |
+
// Process shortcodes in content
|
787 |
+
$content = do_shortcode($content);
|
788 |
+
|
789 |
+
// Restore default shortcode handlers
|
790 |
+
if ( isset($tags_temp) ) {
|
791 |
+
$shortcode_tags = $tags_temp;
|
792 |
+
unset($tags_temp);
|
793 |
+
}
|
794 |
+
|
795 |
+
return $content;
|
796 |
+
}
|
797 |
+
|
798 |
+
/**
|
799 |
+
* Build shortcode tag
|
800 |
+
* @param string $tag Shortcode base
|
801 |
+
* @param array (optional) $attr Shortcode attributes
|
802 |
+
* @param string (optional) $content Shortcode content
|
803 |
+
* @return string Shortcode tag
|
804 |
+
*/
|
805 |
+
public function make_shortcode($tag, $attr = null, $content = null) {
|
806 |
+
return $this->build_element(array (
|
807 |
+
'tag' => $tag,
|
808 |
+
'attributes' => $attr,
|
809 |
+
'content' => $content,
|
810 |
+
));
|
811 |
}
|
812 |
|
813 |
/* Meta */
|
894 |
return '_' . $this->add_prefix($text);
|
895 |
}
|
896 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
897 |
/* Class */
|
898 |
|
|
|
|
|
|
|
|
|
899 |
/**
|
900 |
* Retrieve name of internal class
|
901 |
* @param string $class Base name of class
|
912 |
* @return array Context
|
913 |
*/
|
914 |
function get_context() {
|
915 |
+
// Context
|
916 |
static $ctx = null;
|
917 |
if ( !is_array($ctx) ) {
|
918 |
+
// Standard
|
919 |
$ctx = array($this->build_context());
|
920 |
+
// Action
|
921 |
$action = $this->get_action();
|
922 |
if ( !empty($action) ) {
|
923 |
$ctx[] = $this->build_context('action', $action);
|
924 |
}
|
925 |
+
// Post type
|
926 |
$post_type = $this->get_post_type();
|
927 |
if ( !empty($action) ) {
|
928 |
$ctx[] = $this->build_context('post-type', $post_type);
|
929 |
}
|
930 |
+
// Admin page
|
931 |
if ( is_admin() ) {
|
932 |
global $pagenow;
|
933 |
$pg = $this->strip_file_extension($pagenow);
|
934 |
$ctx[] = $this->build_context('page', $pg);
|
935 |
+
// Query String
|
936 |
+
if ( isset($_SERVER['QUERY_STRING']) ) {
|
937 |
+
parse_str($_SERVER['QUERY_STRING'], $qv);
|
938 |
+
if ( isset($qv['page']) ) {
|
939 |
+
$ctx[] = $this->build_context('page', $qv['page']);
|
940 |
+
if ( stripos($qv['page'], $this->get_prefix()) === 0 ) {
|
941 |
+
$ctx[] = $this->build_context('page', $this->get_prefix());
|
942 |
+
}
|
943 |
+
}
|
944 |
}
|
945 |
+
// Action
|
946 |
if ( !empty($action) ) {
|
947 |
$ctx[] = $this->build_context('page', $pg, 'action', $action);
|
948 |
$ctx[] = $this->build_context('post-type', $post_type, 'action', $action);
|
949 |
}
|
950 |
}
|
951 |
+
// User
|
952 |
$u = wp_get_current_user();
|
953 |
$ctx[] = $this->build_context('user', ( $u->ID ) ? 'registered' : 'guest', false);
|
954 |
}
|
968 |
*/
|
969 |
function build_context($context = null, $prefix = true) {
|
970 |
$args = func_get_args();
|
971 |
+
// Get prefix option
|
972 |
if ( !empty($args) ) {
|
973 |
$prefix = ( is_bool($args[count($args) - 1]) ) ? array_pop($args) : true;
|
974 |
}
|
975 |
|
976 |
+
// Validate
|
977 |
$context = array_filter($args, 'is_string');
|
978 |
$sep = '_';
|
979 |
|
980 |
+
// Context Prefix
|
981 |
if ( $prefix )
|
982 |
array_unshift($context, ( is_admin() ) ? 'admin' : 'public' );
|
983 |
return implode($sep, $context);
|
1012 |
$this->extend_client_object($ctx, true);
|
1013 |
}
|
1014 |
|
1015 |
+
/* Path */
|
1016 |
+
|
1017 |
/**
|
1018 |
* Joins and normalizes the slashes in the paths passed to method
|
1019 |
* All forward/back slashes are converted to forward slashes
|
1027 |
$sl_f = '/';
|
1028 |
$sl_b = '\\';
|
1029 |
$parts = func_get_args();
|
1030 |
+
// Slash defaults (trailing, leading);
|
1031 |
$slashes = array(false, true);
|
1032 |
if ( func_num_args() > 1 ) {
|
1033 |
+
// Get last argument
|
1034 |
$arg_last = $parts[count($parts) - 1];
|
1035 |
if ( is_bool($arg_last) ) {
|
1036 |
$arg_last = array($arg_last);
|
1037 |
}
|
1038 |
|
1039 |
if ( is_array($arg_last) && count($arg_last) > 0 && is_bool($arg_last[0]) ) {
|
1040 |
+
// Remove slash paramter from args array
|
1041 |
array_pop($parts);
|
1042 |
+
// Normalize slashes options
|
1043 |
if ( isset($arg_last[0]) )
|
1044 |
$slashes[0] = $arg_last[0];
|
1045 |
if ( isset($arg_last[1]) )
|
1046 |
$slashes[1] = $arg_last[1];
|
1047 |
}
|
1048 |
}
|
1049 |
+
// Extract to slash options local variables
|
1050 |
list($trailing_slash, $leading_slash) = $slashes;
|
1051 |
|
1052 |
+
// Clean path segments
|
1053 |
foreach ( $parts as $key => $part ) {
|
1054 |
+
// Trim slashes/spaces
|
1055 |
$parts[$key] = trim($part, " " . $sl_f . $sl_b);
|
1056 |
|
1057 |
+
// Verify path segment still contains value
|
1058 |
if ( empty($parts[$key]) ) {
|
1059 |
unset($parts[$key]);
|
1060 |
continue;
|
1061 |
}
|
1062 |
}
|
1063 |
|
1064 |
+
// Join path parts together
|
1065 |
$parts = implode($sl_b, $parts);
|
1066 |
$parts = str_replace($sl_b, $sl_f, $parts);
|
1067 |
+
// Add trailing slash (if necessary)
|
1068 |
if ( $trailing_slash )
|
1069 |
$parts .= $sl_f;
|
1070 |
+
// Add leading slash (if necessary)
|
1071 |
$regex = '#^.+:[\\/]#';
|
1072 |
if ( $leading_slash && !preg_match($regex, $parts) ) {
|
1073 |
$parts = $sl_f . $parts;
|
1078 |
/**
|
1079 |
* Returns URL of file (assumes that it is in plugin directory)
|
1080 |
* @param string $file name of file get URL
|
1081 |
+
* @param string|bool $relative Path that URI should be relative to (Default: full path)
|
1082 |
* @return string File URL
|
1083 |
*/
|
1084 |
+
function get_file_url($file, $relative = null) {
|
1085 |
if ( is_string($file) && '' != trim($file) ) {
|
1086 |
+
$file = str_replace(' ', '%20', $this->normalize_path($this->get_url_base(false, $relative), $file));
|
1087 |
}
|
1088 |
return $file;
|
1089 |
}
|
1093 |
* @param string $file file name
|
1094 |
* @return string File path
|
1095 |
*/
|
1096 |
+
function get_file_path($file, $relative = null) {
|
1097 |
+
// Build path
|
1098 |
if ( is_string($file) && '' != trim($file) ) {
|
1099 |
+
$file = $this->normalize_path($this->get_path_base($relative), $file);
|
1100 |
}
|
1101 |
return $file;
|
1102 |
}
|
1117 |
return ( empty($ext) ) ? false : true;
|
1118 |
}
|
1119 |
|
1120 |
+
/**
|
1121 |
+
* Check if string is valid URI
|
1122 |
+
* @param string $uri String to check
|
1123 |
+
* @return bool TRUE if string is valid URI
|
1124 |
+
*/
|
1125 |
+
function is_uri($uri) {
|
1126 |
+
return ( preg_match('|^(https?:)?//|', $uri) ) ? true : false;
|
1127 |
+
}
|
1128 |
+
|
1129 |
/**
|
1130 |
* Retrieves file extension
|
1131 |
* @param string $file file name/path
|
1135 |
function get_file_extension($file, $lowercase = true) {
|
1136 |
$ret = '';
|
1137 |
$sep = '.';
|
1138 |
+
// Validate
|
1139 |
if ( !is_string($file) )
|
1140 |
return $ret;
|
1141 |
+
// Strip query string (if necessary)
|
1142 |
+
if ( ( $qpos = strpos($file, '?') ) && $qpos !== false ) {
|
1143 |
+
$file = substr($file, 0, $qpos);
|
1144 |
+
}
|
1145 |
if ( ( $rpos = strrpos($file, $sep) ) > 0 )
|
1146 |
$ret = substr($file, $rpos + 1);
|
1147 |
if ( !!$lowercase )
|
1161 |
if ( !is_array($extension) )
|
1162 |
$extension = array(strval($extension));
|
1163 |
if ( !$case_sensitive ) {
|
1164 |
+
// Normalize extensions
|
1165 |
$extension = array_map('strtolower', $extension);
|
1166 |
}
|
1167 |
return ( in_array($this->get_file_extension($file, !$case_sensitive), $extension) ) ? true : false;
|
1188 |
* @uses normalize_path()
|
1189 |
* @return string Base URL
|
1190 |
*/
|
1191 |
+
function get_url_base($trailing_slash = false, $relative = null) {
|
1192 |
+
$ret = $this->_plugin['uri'];
|
1193 |
+
if ( empty($ret) ) {
|
1194 |
+
$ret = $this->normalize_path(plugins_url(), $this->get_plugin_base());
|
1195 |
}
|
1196 |
+
// Trailing slash
|
1197 |
+
if ( !!$trailing_slash ) {
|
1198 |
+
$ret .= '/';
|
1199 |
+
}
|
1200 |
+
// Relative
|
1201 |
+
if ( !empty($relative) ) {
|
1202 |
+
// Default
|
1203 |
+
if ( is_bool($relative) ) {
|
1204 |
+
$relative = site_url();
|
1205 |
+
}
|
1206 |
+
// Custom
|
1207 |
+
if ( is_string($relative) ) {
|
1208 |
+
$ret = $this->get_relative_path($ret, $relative);
|
1209 |
+
}
|
1210 |
+
}
|
1211 |
+
|
1212 |
+
return $ret;
|
1213 |
}
|
1214 |
|
1215 |
/**
|
1219 |
* @uses normalize_path()
|
1220 |
* @return string Base path
|
1221 |
*/
|
1222 |
+
function get_path_base($relative = null) {
|
1223 |
+
$ret = $this->_path_base;
|
1224 |
+
if ( empty($ret) ) {
|
1225 |
+
// Get base directory of parent object
|
1226 |
+
if ( $this->get_parent() ) {
|
1227 |
+
$r = new ReflectionClass(get_class($this->get_parent()));
|
1228 |
+
$base = $r->getFileName();
|
1229 |
+
unset($r);
|
1230 |
+
} else {
|
1231 |
+
$base = __FILE__;
|
1232 |
+
}
|
1233 |
+
// Extract base path
|
1234 |
+
$base = $this->normalize_path($base);
|
1235 |
+
if ( 0 === strpos($base, $this->normalize_path(WP_PLUGIN_DIR)) ) {
|
1236 |
+
$end = strpos($base, '/', strlen(WP_PLUGIN_DIR) + 1);
|
1237 |
+
$base = substr($base, 0, $end);
|
1238 |
+
}
|
1239 |
+
$ret = $this->_path_base = $base;
|
1240 |
}
|
1241 |
+
// Make relative path
|
1242 |
+
if ( !empty($relative) ) {
|
1243 |
+
// Default
|
1244 |
+
if ( is_bool($relative) ) {
|
1245 |
+
$relative = ABSPATH;
|
1246 |
+
}
|
1247 |
+
// Custom
|
1248 |
+
if ( is_string($relative) ) {
|
1249 |
+
$ret = $this->get_relative_path($ret, $relative);
|
1250 |
+
}
|
1251 |
+
}
|
1252 |
+
return $ret;
|
1253 |
+
}
|
1254 |
+
|
1255 |
+
/**
|
1256 |
+
* Retrieve relative path for absolute paths
|
1257 |
+
* @param string $path Path to modify
|
1258 |
+
* @param string $relative (optional) Base path to make $path relative to (Default: Site's base path)
|
1259 |
+
* @return string Relative path
|
1260 |
+
*/
|
1261 |
+
function get_relative_path($path, $relative = true) {
|
1262 |
+
// Default base path
|
1263 |
+
if ( !is_string($relative) ) {
|
1264 |
+
$relative = ABSPATH;
|
1265 |
+
}
|
1266 |
+
if ( !empty($relative) && !empty($path) ) {
|
1267 |
+
$relative = $this->normalize_path($relative);
|
1268 |
+
$path = $this->normalize_path($path);
|
1269 |
+
// Strip base path
|
1270 |
+
if ( strpos($path, $relative) === 0 ) {
|
1271 |
+
$path = substr($path, strlen($relative));
|
1272 |
+
}
|
1273 |
+
}
|
1274 |
+
return $path;
|
1275 |
}
|
1276 |
|
1277 |
/**
|
1278 |
* Retrieve plugin's base directory
|
1279 |
* @uses WP_PLUGIN_DIR
|
1280 |
+
* @uses Utilities::get_path_base() to retrieve plugin base path
|
1281 |
+
* @uses Utilities::_plugin_base to save plugin base
|
1282 |
* @return string Base directory
|
1283 |
*/
|
1284 |
+
function get_plugin_base() {
|
1285 |
+
$ret = $this->_plugin['base'];
|
1286 |
+
if ( empty($ret) ) {
|
1287 |
+
$ret = $this->_plugin['base'] = basename($this->get_path_base());
|
1288 |
}
|
1289 |
+
return $ret;
|
|
|
|
|
1290 |
}
|
1291 |
|
1292 |
/**
|
1296 |
* @return string Base file path
|
1297 |
*/
|
1298 |
function get_plugin_base_file() {
|
1299 |
+
$ret = $this->_plugin['file'];
|
1300 |
+
if ( empty($ret) ) {
|
1301 |
+
$dir = @opendir($this->get_path_base());
|
1302 |
if ( $dir ) {
|
1303 |
while ( ($ftemp = readdir($dir)) !== false ) {
|
1304 |
+
// Only process PHP files
|
1305 |
$ftemp = $this->get_file_path($ftemp);
|
1306 |
if ( !$this->has_file_extension($ftemp, 'php') || !is_readable($ftemp) )
|
1307 |
continue;
|
1308 |
+
// Check for data
|
1309 |
+
$data = get_file_data($ftemp, $this->_plugin['headers']);
|
1310 |
if ( !empty($data['Name']) ) {
|
1311 |
+
// Set base file
|
1312 |
+
$ret = $ftemp;
|
1313 |
+
// Save plugin data
|
1314 |
+
$this->set_plugin_info($data);
|
1315 |
break;
|
1316 |
}
|
1317 |
}
|
1318 |
}
|
1319 |
@closedir($dir);
|
1320 |
}
|
1321 |
+
// Return
|
1322 |
+
return $ret;
|
1323 |
}
|
1324 |
|
1325 |
/**
|
1330 |
* @return string Internal plugin name
|
1331 |
*/
|
1332 |
function get_plugin_base_name() {
|
1333 |
+
$ret = $this->_plugin['name'];
|
1334 |
+
if ( empty($ret) ) {
|
1335 |
+
$ret = $this->_plugin['name'] = plugin_basename( $this->get_plugin_base_file() );
|
1336 |
+
}
|
1337 |
+
return $ret;
|
1338 |
+
}
|
1339 |
+
|
1340 |
+
private function set_plugin_info($data) {
|
1341 |
+
if ( is_array($data) ) {
|
1342 |
+
$this->_plugin['data'] = $data;
|
1343 |
}
|
|
|
1344 |
}
|
1345 |
|
1346 |
/**
|
1347 |
* Retrieve plugin info
|
1348 |
* Parses info comment in main plugin file
|
1349 |
+
* @uses get_plugin_base_file() to retrieve plugin info
|
1350 |
+
* @return array|string Plugin info (specific value if field set)
|
1351 |
+
*/
|
1352 |
+
function get_plugin_info($field = null) {
|
1353 |
+
$ret = $this->_plugin['data'];
|
1354 |
+
// Get plugin data
|
1355 |
+
if ( empty($ret) ) {
|
1356 |
+
$this->get_plugin_base_file();
|
1357 |
+
$ret = $this->_plugin['data'];
|
1358 |
}
|
1359 |
+
// Return specified field
|
1360 |
if ( !empty($field) ) {
|
1361 |
+
$ret = ( is_array($ret) && isset($ret[$field]) ) ? $ret[$field] : '';
|
|
|
|
|
|
|
1362 |
}
|
1363 |
return $ret;
|
1364 |
}
|
1370 |
* @return string Plugin version
|
1371 |
*/
|
1372 |
function get_plugin_version($strip_desc = true) {
|
1373 |
+
// Retrieve version
|
1374 |
+
$ret = $this->get_plugin_info('Version');
|
1375 |
+
// Format
|
1376 |
+
if ( !empty($ret) && $strip_desc ) {
|
|
|
|
|
|
|
|
|
|
|
1377 |
$ret = explode(' ', $ret, 2);
|
1378 |
$ret = $ret[0];
|
1379 |
}
|
1380 |
+
// Return
|
1381 |
return $ret;
|
1382 |
}
|
1383 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1384 |
/**
|
1385 |
* Retrieve current post type based on URL query variables
|
1386 |
* @return string|null Current post type
|
1404 |
function get_action($default = null) {
|
1405 |
$action = '';
|
1406 |
|
1407 |
+
// Check if action is set in URL
|
1408 |
if ( isset($_GET['action']) )
|
1409 |
$action = $_GET['action'];
|
1410 |
+
// Otherwise, Determine action based on plugin admin page suffix
|
1411 |
+
elseif ( isset($_GET['page']) && ($pos = strrpos($_GET['page'], '-')) && $pos !== false && ( $pos != strlen($_GET['page']) - 1 ) )
|
1412 |
$action = trim(substr($_GET['page'], $pos + 1), '-_');
|
1413 |
|
1414 |
+
// Determine action for core admin pages
|
1415 |
+
if ( ( !isset($_GET['page']) || empty($action) ) && isset($_SERVER['SCRIPT_NAME']) ) {
|
1416 |
$actions = array(
|
1417 |
'add' => array('page-new', 'post-new'),
|
1418 |
'edit-item' => array('page', 'post'),
|
1434 |
|
1435 |
/*-** General **-*/
|
1436 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1437 |
/**
|
1438 |
* Checks if a property exists in a class or object
|
1439 |
+
* Compatibility method for PHP 4
|
1440 |
* @param mixed $class Class or object to check
|
1441 |
* @param string $property Name of property to look for in $class
|
1442 |
*/
|
1458 |
*/
|
1459 |
function &get_property(&$obj, $property) {
|
1460 |
$property = trim($property);
|
1461 |
+
// Object
|
1462 |
if ( is_object($obj) )
|
1463 |
return $obj->{$property};
|
1464 |
+
// Array
|
1465 |
if ( is_array($obj) )
|
1466 |
return $obj[$property];
|
1467 |
+
// Class
|
1468 |
if ( is_string($obj) && class_exists($obj) ) {
|
1469 |
$cvars = get_class_vars($obj);
|
1470 |
if ( isset($cvars[$property]) )
|
1484 |
*/
|
1485 |
function array_remap($arr, $map = array(), $overwrite = false) {
|
1486 |
if ( !empty($map) && is_array($map) ) {
|
1487 |
+
// Iterate through mappings
|
1488 |
foreach ( $map as $from => $to ) {
|
1489 |
if ( !array_key_exists($from, $arr) )
|
1490 |
continue;
|
1491 |
$move = $overwrite;
|
1492 |
+
// Only remap if parent property doesn't already exist in array
|
1493 |
if ( !array_key_exists($to, $arr) )
|
1494 |
$move = true;
|
1495 |
if ( $move ) {
|
1496 |
+
// Move member value to new key
|
1497 |
$arr[$to] = $arr[$from];
|
1498 |
+
// Remove source member
|
1499 |
unset($arr[$from]);
|
1500 |
}
|
1501 |
}
|
1502 |
}
|
1503 |
+
// Return remapped properties
|
1504 |
return $arr;
|
1505 |
}
|
1506 |
|
1542 |
* @return array Merged array
|
1543 |
*/
|
1544 |
function array_merge_recursive_distinct($arr1) {
|
1545 |
+
// Get all arrays passed to function
|
1546 |
$args = func_get_args();
|
1547 |
if ( empty($args) )
|
1548 |
return false;
|
1549 |
+
// Return empty array if first parameter is not an array
|
1550 |
if ( !is_array($args[0]) )
|
1551 |
return array();
|
1552 |
+
// Set first array as base array
|
1553 |
$merged = $args[0];
|
1554 |
+
// Iterate through arrays to merge
|
1555 |
$arg_length = count($args);
|
1556 |
for ( $x = 1; $x < $arg_length; $x++ ) {
|
1557 |
+
// Skip if argument is not an array (only merge arrays)
|
1558 |
if ( !is_array($args[$x]) )
|
1559 |
continue;
|
1560 |
+
// Iterate through argument items
|
1561 |
foreach ( $args[$x] as $key => $val ) {
|
1562 |
+
// Generate key for numeric indexes
|
1563 |
if ( is_int($key) ) {
|
1564 |
+
// Add new item to merged array
|
1565 |
$merged[] = null;
|
1566 |
+
// Get key of new item
|
1567 |
$key = array_pop(array_keys($merged));
|
1568 |
}
|
1569 |
if ( !isset($merged[$key]) || !is_array($merged[$key]) || !is_array($val) ) {
|
1586 |
*/
|
1587 |
function array_replace_recursive($search, $arr_replace, $arr_subject) {
|
1588 |
foreach ($arr_subject as $key => $val) {
|
1589 |
+
// Skip element if key does not exist in the replacement array
|
1590 |
if (!isset($arr_replace[$key]))
|
1591 |
continue;
|
1592 |
+
// If element values for both arrays are strings, replace text
|
1593 |
if (is_string($val) && strpos($val, $search) !== false && is_string($arr_replace[$key]))
|
1594 |
$arr_subject[$key] = str_replace($search, $arr_replace[$key], $val);
|
1595 |
+
// If value in both arrays are arrays, recursively replace text
|
1596 |
if (is_array($val) && is_array($arr_replace[$key]))
|
1597 |
$arr_subject[$key] = $this->array_replace_recursive($search, $arr_replace[$key], $val);
|
1598 |
}
|
1611 |
return eval('return isset($arr' . $f_path . ');');
|
1612 |
}
|
1613 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1614 |
/**
|
1615 |
* Build formatted string based on array values
|
1616 |
* Array values in formatted string will be ordered by index order
|
1619 |
* @return string Formatted string based on array values
|
1620 |
*/
|
1621 |
function get_array_path($attribute = '', $format = null) {
|
1622 |
+
// Formatted value
|
1623 |
$fmtd = '';
|
1624 |
if (!empty($attribute)) {
|
1625 |
+
// Make sure attribute is array
|
1626 |
if (!is_array($attribute)) {
|
1627 |
$attribute = array($attribute);
|
1628 |
}
|
1629 |
+
// Format attribute
|
1630 |
$format = strtolower($format);
|
1631 |
switch ($format) {
|
1632 |
case 'id':
|
1634 |
break;
|
1635 |
case 'metadata':
|
1636 |
case 'attribute':
|
1637 |
+
// Join segments
|
1638 |
$delim = '_';
|
1639 |
$fmtd = implode($delim, $attribute);
|
1640 |
+
// Replace white space and repeating delimiters
|
1641 |
$fmtd = str_replace(' ', $delim, $fmtd);
|
1642 |
while (strpos($fmtd, $delim.$delim) !== false)
|
1643 |
$fmtd = str_replace($delim.$delim, $delim, $fmtd);
|
1644 |
+
// Prefix formatted value with delimeter for metadata keys
|
1645 |
if ('metadata' == $format)
|
1646 |
$fmtd = $delim . $fmtd;
|
1647 |
break;
|
1664 |
$path = array();
|
1665 |
$args = func_get_args();
|
1666 |
|
1667 |
+
// Iterate through parameters and build path
|
1668 |
foreach ( $args as $arg ) {
|
1669 |
if ( empty($arg) )
|
1670 |
continue;
|
1671 |
|
1672 |
if (is_array($arg)) {
|
1673 |
+
// Recurse through array items to pull out any more arrays
|
1674 |
foreach ($arg as $key => $val) {
|
1675 |
$path = array_merge($path, $this->build_path($val));
|
1676 |
}
|
1677 |
+
// $path = array_merge($path, array_values($arg));
|
1678 |
} elseif ( is_scalar($arg) ) {
|
1679 |
$path[] = $arg;
|
1680 |
}
|
1683 |
return $path;
|
1684 |
}
|
1685 |
|
1686 |
+
/**
|
1687 |
+
* Build generic element
|
1688 |
+
* @param array $args
|
1689 |
+
* @return string Element output
|
1690 |
+
*/
|
1691 |
+
public function build_element($args = array()) {
|
1692 |
+
$ret = '';
|
1693 |
+
$args_default = array(
|
1694 |
+
'tag' => '',
|
1695 |
+
'wrap' => false,
|
1696 |
+
'content' => '',
|
1697 |
+
'attributes' => array(),
|
1698 |
+
'format' => array(),
|
1699 |
+
);
|
1700 |
+
$format_default = array(
|
1701 |
+
'open' => '[%s]',
|
1702 |
+
'close' => '[/%s]',
|
1703 |
+
);
|
1704 |
+
$args = wp_parse_args($args, $args_default);
|
1705 |
+
$args['format'] = wp_parse_args($args['format'], $format_default);
|
1706 |
+
|
1707 |
+
// Validate
|
1708 |
+
if ( !is_string($args['tag']) || empty($args['tag']) ) {
|
1709 |
+
return $ret;
|
1710 |
+
}
|
1711 |
+
|
1712 |
+
$args = (object) $args;
|
1713 |
+
|
1714 |
+
$args->attributes = $this->build_attribute_string($args->attributes);
|
1715 |
+
if ( strlen($args->attributes) > 0 ) {
|
1716 |
+
$args->attributes = ' ' . $args->attributes;
|
1717 |
+
}
|
1718 |
+
|
1719 |
+
// Build output
|
1720 |
+
$args->format = (object) $args->format;
|
1721 |
+
$ret = sprintf( $args->format->open, $args->tag . $args->attributes);
|
1722 |
+
|
1723 |
+
// Wrap content if necessary
|
1724 |
+
if ( $args->wrap || ( is_string($args->content) && !empty($args->content) ) ) {
|
1725 |
+
$ret .= $args->content . sprintf( $args->format->close, $args->tag);
|
1726 |
+
}
|
1727 |
+
|
1728 |
+
return $ret;
|
1729 |
+
}
|
1730 |
+
|
1731 |
/**
|
1732 |
* Parse string of attributes into array
|
1733 |
* For XML/XHTML tag attributes
|
1737 |
function parse_attribute_string($txt, $defaults = array()) {
|
1738 |
$txt = trim($txt, ' >');
|
1739 |
$matches = $attr = array();
|
1740 |
+
// Strip tag
|
1741 |
if ( $txt[0] == '<' && ($s = strpos($txt, ' ')) && $s !== false ) {
|
1742 |
$txt = trim(substr($txt, $s + 1));
|
1743 |
}
|
1744 |
+
// Parse attributes
|
1745 |
$rgx = "/\b(\w+.*?)=([\"'])(.*?)\\2(?:\s|$)/i";
|
1746 |
preg_match_all($rgx, $txt, $matches);
|
1747 |
if ( count($matches) > 3 ) {
|
1750 |
$attr[trim($val)] = trim($matches[3][$sub_idx]);
|
1751 |
}
|
1752 |
}
|
1753 |
+
// Destroy parsing vars
|
1754 |
unset($txt, $matches);
|
1755 |
|
1756 |
return array_merge($defaults, $attr);
|
1763 |
*/
|
1764 |
function build_attribute_string($attr) {
|
1765 |
$ret = '';
|
1766 |
+
if ( is_object($attr) ) {
|
1767 |
$attr = (array) $attr;
|
1768 |
+
}
|
1769 |
+
if ( is_array($attr) && !empty($attr) ) {
|
1770 |
array_map('esc_attr', $attr);
|
1771 |
$attr_str = array();
|
1772 |
foreach ( $attr as $key => $val ) {
|
1777 |
return $ret;
|
1778 |
}
|
1779 |
|
1780 |
+
/* HTML */
|
1781 |
+
|
1782 |
+
/**
|
1783 |
+
* Generate HTML element based on values
|
1784 |
+
* @param $args Element arguments
|
1785 |
+
* @return string Generated HTML element
|
1786 |
+
*/
|
1787 |
+
public function build_html_element($args) {
|
1788 |
+
$args_default = array(
|
1789 |
+
'tag' => 'span',
|
1790 |
+
'content' => '',
|
1791 |
+
'attributes' => array()
|
1792 |
+
);
|
1793 |
+
$args = wp_parse_args($args, $args_default);
|
1794 |
+
$args['format'] = array(
|
1795 |
+
'open' => '<%s>',
|
1796 |
+
'close' => '</%s>',
|
1797 |
+
);
|
1798 |
+
// Build element
|
1799 |
+
return $this->build_element($args);
|
1800 |
+
}
|
1801 |
+
|
1802 |
+
/**
|
1803 |
+
* Build HTML link element
|
1804 |
+
* @uses build_html_element() to build link output
|
1805 |
+
* @param string $uri Link URI
|
1806 |
+
* @param string $content Link content
|
1807 |
+
* @param $array (optional) $attributes Additional link attributes
|
1808 |
+
* @return string HTML link element
|
1809 |
+
*/
|
1810 |
function build_html_link($uri, $content, $attributes = array()) {
|
1811 |
$attributes = array_merge(array('href' => $uri, 'title' => $content), $attributes);
|
1812 |
return $this->build_html_element(array('tag' => 'a', 'wrap' => true, 'content' => $content, 'attributes' => $attributes));
|
1817 |
* @param $url Stylesheet URL
|
1818 |
* @return string Stylesheet element
|
1819 |
*/
|
1820 |
+
function build_stylesheet_element($url) {
|
1821 |
$attributes = array('href' => $url, 'type' => 'text/css', 'rel' => 'stylesheet');
|
1822 |
return $this->build_html_element(array('tag' => 'link', 'wrap' => false, 'attributes' => $attributes));
|
1823 |
}
|
1831 |
* @param bool $wait_doc_ready (optional) Wait until document is fully loaded before executing commands? (Default: No)
|
1832 |
*/
|
1833 |
function build_script_element($content = '', $id = '', $wrap_jquery = true, $wait_doc_ready = false) {
|
1834 |
+
// Stop processing invalid content
|
1835 |
if ( is_array($content) && !empty($content) ) {
|
1836 |
+
$content = implode(PHP_EOL, $content);
|
1837 |
}
|
1838 |
if ( empty($content) || !is_string($content) ) {
|
1839 |
return '';
|
1842 |
$start = array('/* <![CDATA[ */');
|
1843 |
$end = array('/* ]]> */');
|
1844 |
if ( $wrap_jquery ) {
|
1845 |
+
$start[] = 'if ( !!window.jQuery ) {(function($){';
|
1846 |
+
$end[] = '})(jQuery);}';
|
1847 |
|
1848 |
+
// Add event handler (if necessary)
|
1849 |
if ( $wait_doc_ready ) {
|
1850 |
$start[] = '$(document).ready(function(){';
|
1851 |
$end[] = '})';
|
1852 |
}
|
1853 |
}
|
1854 |
|
1855 |
+
// Reverse order of end values
|
1856 |
$end = array_reverse($end);
|
1857 |
$content = implode('', array_merge($start, array($content), $end));
|
1858 |
if ( is_string($id) && !empty($id) ) {
|
1859 |
$attributes['id'] = $this->add_prefix($id);
|
1860 |
}
|
1861 |
+
return $this->build_html_element(array('tag' => 'script', 'content' => $content, 'wrap' => true, 'attributes' => $attributes)) . PHP_EOL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1862 |
}
|
1863 |
}
|
l10n/simple-lightbox.pot
CHANGED
@@ -1,218 +1,260 @@
|
|
1 |
-
# Copyright (C)
|
2 |
-
# This file is distributed under the same license as the
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
-
"Project-Id-Version:
|
6 |
-
"Report-Msgid-Bugs-To: https://
|
7 |
-
"POT-Creation-Date:
|
8 |
"MIME-Version: 1.0\n"
|
9 |
"Content-Type: text/plain; charset=UTF-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
11 |
-
"PO-Revision-Date:
|
12 |
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
13 |
"Language-Team: LANGUAGE <LL@li.org>\n"
|
14 |
|
15 |
-
#:
|
16 |
-
msgid "
|
17 |
msgstr ""
|
18 |
|
19 |
-
#:
|
20 |
-
msgid "
|
21 |
msgstr ""
|
22 |
|
23 |
-
#:
|
24 |
-
|
25 |
-
msgid "Access Denied"
|
26 |
msgstr ""
|
27 |
|
28 |
-
#:
|
29 |
-
msgid "
|
30 |
msgstr ""
|
31 |
|
32 |
-
#:
|
33 |
-
msgid "
|
34 |
msgstr ""
|
35 |
|
36 |
-
#:
|
37 |
-
msgid "
|
38 |
msgstr ""
|
39 |
|
40 |
-
#:
|
41 |
-
msgid "
|
42 |
msgstr ""
|
43 |
|
44 |
-
#:
|
45 |
-
msgid "
|
46 |
msgstr ""
|
47 |
|
48 |
-
#:
|
49 |
-
msgid "
|
50 |
msgstr ""
|
51 |
|
52 |
-
#:
|
53 |
-
msgid "
|
54 |
msgstr ""
|
55 |
|
56 |
-
#:
|
57 |
-
msgid "
|
58 |
msgstr ""
|
59 |
|
60 |
-
#:
|
61 |
-
msgid "
|
62 |
msgstr ""
|
63 |
|
64 |
-
#:
|
65 |
-
msgid "
|
66 |
msgstr ""
|
67 |
|
68 |
-
#:
|
69 |
-
msgid "
|
70 |
msgstr ""
|
71 |
|
72 |
-
#:
|
73 |
-
msgid "
|
74 |
msgstr ""
|
75 |
|
76 |
-
#:
|
77 |
-
msgid "
|
78 |
msgstr ""
|
79 |
|
80 |
-
#:
|
81 |
-
msgid "
|
82 |
msgstr ""
|
83 |
|
84 |
-
#:
|
85 |
-
msgid "
|
86 |
msgstr ""
|
87 |
|
88 |
-
#:
|
89 |
-
msgid "
|
90 |
msgstr ""
|
91 |
|
92 |
-
#:
|
93 |
-
msgid "
|
94 |
msgstr ""
|
95 |
|
96 |
-
#:
|
97 |
-
msgid "
|
98 |
msgstr ""
|
99 |
|
100 |
-
#:
|
101 |
-
msgid "
|
102 |
msgstr ""
|
103 |
|
104 |
-
#:
|
105 |
-
msgid "
|
106 |
msgstr ""
|
107 |
|
108 |
-
#:
|
109 |
-
msgid "
|
110 |
msgstr ""
|
111 |
|
112 |
-
#:
|
113 |
-
msgid "
|
114 |
msgstr ""
|
115 |
|
116 |
-
#:
|
117 |
-
msgid "
|
118 |
msgstr ""
|
119 |
|
120 |
-
#:
|
121 |
-
msgid "
|
122 |
msgstr ""
|
123 |
|
124 |
-
#:
|
125 |
-
msgid "
|
126 |
msgstr ""
|
127 |
|
128 |
-
#:
|
129 |
-
msgid "
|
130 |
msgstr ""
|
131 |
|
132 |
-
#:
|
133 |
-
msgid "
|
134 |
msgstr ""
|
135 |
|
136 |
-
#:
|
137 |
-
msgid "
|
138 |
msgstr ""
|
139 |
|
140 |
-
#:
|
141 |
-
msgid "
|
142 |
msgstr ""
|
143 |
|
144 |
-
#:
|
145 |
-
msgid "
|
146 |
msgstr ""
|
147 |
|
148 |
-
#:
|
149 |
-
msgid "
|
150 |
msgstr ""
|
151 |
|
152 |
-
#:
|
153 |
-
msgid "
|
154 |
msgstr ""
|
155 |
|
156 |
-
#:
|
157 |
-
msgid "
|
158 |
msgstr ""
|
159 |
|
160 |
-
#:
|
161 |
-
msgid "
|
|
|
|
|
|
|
162 |
msgstr ""
|
163 |
|
164 |
-
#:
|
165 |
-
msgid "
|
166 |
msgstr ""
|
167 |
|
168 |
-
#:
|
169 |
-
msgid "
|
170 |
msgstr ""
|
171 |
|
172 |
-
#:
|
173 |
-
msgid "
|
|
|
|
|
|
|
174 |
msgstr ""
|
175 |
|
176 |
-
#:
|
177 |
-
|
|
|
178 |
msgstr ""
|
179 |
|
180 |
-
#:
|
181 |
-
msgid "
|
182 |
msgstr ""
|
183 |
|
184 |
-
#:
|
185 |
-
msgid "
|
186 |
msgstr ""
|
187 |
|
188 |
-
#:
|
189 |
-
msgid "
|
190 |
msgstr ""
|
191 |
|
192 |
-
#:
|
193 |
-
msgid "
|
194 |
msgstr ""
|
195 |
|
196 |
-
#:
|
197 |
-
msgid "
|
198 |
msgstr ""
|
199 |
|
200 |
-
#:
|
201 |
-
msgid "
|
202 |
msgstr ""
|
203 |
|
204 |
-
#:
|
205 |
-
msgid "
|
206 |
msgstr ""
|
207 |
|
208 |
-
#:
|
209 |
-
msgid "
|
210 |
msgstr ""
|
211 |
|
212 |
-
#:
|
213 |
-
msgid "
|
214 |
msgstr ""
|
215 |
|
216 |
-
#:
|
217 |
-
msgid "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
218 |
msgstr ""
|
1 |
+
# Copyright (C) 2015 Simple Lightbox
|
2 |
+
# This file is distributed under the same license as the Simple Lightbox package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
+
"Project-Id-Version: Simple Lightbox 2.5.1\n"
|
6 |
+
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/simple-lightbox\n"
|
7 |
+
"POT-Creation-Date: 2015-09-24 03:20:40+00:00\n"
|
8 |
"MIME-Version: 1.0\n"
|
9 |
"Content-Type: text/plain; charset=UTF-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
11 |
+
"PO-Revision-Date: 2015-MO-DA HO:MI+ZONE\n"
|
12 |
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
13 |
"Language-Team: LANGUAGE <LL@li.org>\n"
|
14 |
|
15 |
+
#: controller.php:240
|
16 |
+
msgid "Activation"
|
17 |
msgstr ""
|
18 |
|
19 |
+
#: controller.php:241
|
20 |
+
msgid "Grouping"
|
21 |
msgstr ""
|
22 |
|
23 |
+
#: controller.php:242
|
24 |
+
msgid "UI"
|
|
|
25 |
msgstr ""
|
26 |
|
27 |
+
#: controller.php:243
|
28 |
+
msgid "Labels"
|
29 |
msgstr ""
|
30 |
|
31 |
+
#: controller.php:246
|
32 |
+
msgid "Enable Lightbox Functionality"
|
33 |
msgstr ""
|
34 |
|
35 |
+
#: controller.php:247
|
36 |
+
msgid "Enable on Home page"
|
37 |
msgstr ""
|
38 |
|
39 |
+
#: controller.php:248
|
40 |
+
msgid "Enable on Single Posts"
|
41 |
msgstr ""
|
42 |
|
43 |
+
#: controller.php:249
|
44 |
+
msgid "Enable on Pages"
|
45 |
msgstr ""
|
46 |
|
47 |
+
#: controller.php:250
|
48 |
+
msgid "Enable on Archive Pages (tags, categories, etc.)"
|
49 |
msgstr ""
|
50 |
|
51 |
+
#: controller.php:251
|
52 |
+
msgid "Enable for Widgets"
|
53 |
msgstr ""
|
54 |
|
55 |
+
#: controller.php:252
|
56 |
+
msgid "Group items (for displaying as a slideshow)"
|
57 |
msgstr ""
|
58 |
|
59 |
+
#: controller.php:253
|
60 |
+
msgid "Group items by Post (e.g. on pages with multiple posts)"
|
61 |
msgstr ""
|
62 |
|
63 |
+
#: controller.php:254
|
64 |
+
msgid "Group gallery items separately"
|
65 |
msgstr ""
|
66 |
|
67 |
+
#: controller.php:255
|
68 |
+
msgid "Group widget items separately"
|
69 |
msgstr ""
|
70 |
|
71 |
+
#: controller.php:256
|
72 |
+
msgid "Resize lightbox to fit in window"
|
73 |
msgstr ""
|
74 |
|
75 |
+
#: controller.php:257
|
76 |
+
msgid "Enable animations"
|
77 |
msgstr ""
|
78 |
|
79 |
+
#: controller.php:258
|
80 |
+
msgid "Start Slideshow Automatically"
|
81 |
msgstr ""
|
82 |
|
83 |
+
#: controller.php:259
|
84 |
+
msgid "Slide Duration (Seconds)"
|
85 |
msgstr ""
|
86 |
|
87 |
+
#: controller.php:260
|
88 |
+
msgid "Loop through items"
|
89 |
msgstr ""
|
90 |
|
91 |
+
#: controller.php:261
|
92 |
+
msgid "Overlay Opacity (0 - 1)"
|
93 |
msgstr ""
|
94 |
|
95 |
+
#: controller.php:262
|
96 |
+
msgid "Enable default title"
|
97 |
msgstr ""
|
98 |
|
99 |
+
#: controller.php:263
|
100 |
+
msgid "Loading indicator"
|
101 |
msgstr ""
|
102 |
|
103 |
+
#: controller.php:264
|
104 |
+
msgid "Close button"
|
105 |
msgstr ""
|
106 |
|
107 |
+
#: controller.php:265
|
108 |
+
msgid "Next Item button"
|
109 |
msgstr ""
|
110 |
|
111 |
+
#: controller.php:266
|
112 |
+
msgid "Previous Item button"
|
113 |
msgstr ""
|
114 |
|
115 |
+
#: controller.php:267
|
116 |
+
msgid "Start Slideshow button"
|
117 |
msgstr ""
|
118 |
|
119 |
+
#: controller.php:268
|
120 |
+
msgid "Stop Slideshow button"
|
121 |
msgstr ""
|
122 |
|
123 |
+
#: controller.php:269
|
124 |
+
msgid "Slideshow status format"
|
125 |
msgstr ""
|
126 |
|
127 |
+
#: controller.php:319
|
128 |
+
msgid "Lightbox"
|
129 |
msgstr ""
|
130 |
|
131 |
+
#: controller.php:320
|
132 |
+
msgid "Lightbox Settings"
|
133 |
msgstr ""
|
134 |
|
135 |
+
#: controller.php:321
|
136 |
+
msgid "Settings"
|
137 |
msgstr ""
|
138 |
|
139 |
+
#: controller.php:330
|
140 |
+
msgid "Feedback & Support"
|
141 |
msgstr ""
|
142 |
|
143 |
+
#: controller.php:335
|
144 |
+
msgid "Reset"
|
145 |
msgstr ""
|
146 |
|
147 |
+
#: controller.php:336
|
148 |
+
msgid "Are you sure you want to reset settings?"
|
149 |
msgstr ""
|
150 |
|
151 |
+
#: controller.php:337
|
152 |
+
msgid "Settings have been reset"
|
153 |
msgstr ""
|
154 |
|
155 |
+
#: controller.php:338
|
156 |
+
msgid "Settings were not reset"
|
157 |
msgstr ""
|
158 |
|
159 |
+
#: controller.php:348
|
160 |
+
msgid ""
|
161 |
+
"<p>Simple Lightbox thrives on your feedback!</p><p>Click the button below to "
|
162 |
+
"<strong>get help</strong>, <strong>request a feature</strong>, or "
|
163 |
+
"<strong>provide some feedback</strong>!</p>"
|
164 |
msgstr ""
|
165 |
|
166 |
+
#: controller.php:352
|
167 |
+
msgid "Get Support & Provide Feedback"
|
168 |
msgstr ""
|
169 |
|
170 |
+
#: includes/class.admin.php:644
|
171 |
+
msgid "The settings have been reset"
|
172 |
msgstr ""
|
173 |
|
174 |
+
#: includes/class.admin.php:645
|
175 |
+
msgid ""
|
176 |
+
"<strong class=\"%1$s\">Notice:</strong> This update is a <strong class=\"%1$s"
|
177 |
+
"\">Beta version</strong>. It is highly recommended that you test the update "
|
178 |
+
"on a test server before updating the plugin on a production server."
|
179 |
msgstr ""
|
180 |
|
181 |
+
#: includes/class.admin.php:646 includes/class.admin_action.php:45
|
182 |
+
#: includes/class.admin_page.php:146
|
183 |
+
msgid "Access Denied"
|
184 |
msgstr ""
|
185 |
|
186 |
+
#: includes/class.fields.php:43
|
187 |
+
msgid "Default Element"
|
188 |
msgstr ""
|
189 |
|
190 |
+
#: includes/class.fields.php:55
|
191 |
+
msgid "Default Element (Closed Tag)"
|
192 |
msgstr ""
|
193 |
|
194 |
+
#: includes/class.fields.php:63
|
195 |
+
msgid "Default Input Element"
|
196 |
msgstr ""
|
197 |
|
198 |
+
#: includes/class.fields.php:71
|
199 |
+
msgid "Text Box"
|
200 |
msgstr ""
|
201 |
|
202 |
+
#: includes/class.fields.php:102
|
203 |
+
msgid "Hidden Field"
|
204 |
msgstr ""
|
205 |
|
206 |
+
#: includes/class.fields.php:108
|
207 |
+
msgid "Select tag"
|
208 |
msgstr ""
|
209 |
|
210 |
+
#: includes/class.fields.php:120
|
211 |
+
msgid "Inline wrapper"
|
212 |
msgstr ""
|
213 |
|
214 |
+
#: includes/class.option.php:113
|
215 |
+
msgid "Enabled"
|
216 |
msgstr ""
|
217 |
|
218 |
+
#: includes/class.option.php:113
|
219 |
+
msgid "Disabled"
|
220 |
msgstr ""
|
221 |
|
222 |
+
#: includes/class.options.php:222
|
223 |
+
msgid "Default"
|
224 |
+
msgstr ""
|
225 |
+
|
226 |
+
#: includes/class.themes.php:40
|
227 |
+
msgid "Theme"
|
228 |
+
msgstr ""
|
229 |
+
|
230 |
+
#: includes/class.themes.php:65
|
231 |
+
msgid "Baseline"
|
232 |
+
msgstr ""
|
233 |
+
|
234 |
+
#: includes/class.themes.php:76
|
235 |
+
msgid "Default (Light)"
|
236 |
+
msgstr ""
|
237 |
+
|
238 |
+
#: includes/class.themes.php:87
|
239 |
+
msgid "Default (Dark)"
|
240 |
+
msgstr ""
|
241 |
+
|
242 |
+
#. Plugin Name of the plugin/theme
|
243 |
+
msgid "Simple Lightbox"
|
244 |
+
msgstr ""
|
245 |
+
|
246 |
+
#. Plugin URI of the plugin/theme
|
247 |
+
msgid "http://archetyped.com/tools/simple-lightbox/"
|
248 |
+
msgstr ""
|
249 |
+
|
250 |
+
#. Description of the plugin/theme
|
251 |
+
msgid "The highly customizable lightbox for WordPress"
|
252 |
+
msgstr ""
|
253 |
+
|
254 |
+
#. Author of the plugin/theme
|
255 |
+
msgid "Archetyped"
|
256 |
+
msgstr ""
|
257 |
+
|
258 |
+
#. Author URI of the plugin/theme
|
259 |
+
msgid "http://archetyped.com"
|
260 |
msgstr ""
|
load.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/* Constants */
|
4 |
+
|
5 |
+
if ( !defined('SLB_DEV') ) {
|
6 |
+
define('SLB_DEV', ( isset( $_REQUEST['slb_dev'] ) && !!$_REQUEST['slb_dev'] ) );
|
7 |
+
}
|
8 |
+
|
9 |
+
/* Class Management */
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Class loading handler
|
13 |
+
* @param string $classname Class to load
|
14 |
+
*/
|
15 |
+
function slb_autoload($classname) {
|
16 |
+
$prefix = 'slb_';
|
17 |
+
$cls = strtolower($classname);
|
18 |
+
// Remove prefix
|
19 |
+
if ( 0 !== strpos($cls, $prefix) ) {
|
20 |
+
return false;
|
21 |
+
}
|
22 |
+
// Format class for filename
|
23 |
+
$fn = 'class.' . substr($cls, strlen($prefix)) . '.php';
|
24 |
+
// Build path
|
25 |
+
$path = dirname(__FILE__) . '/' . "includes/" . $fn;
|
26 |
+
// Load file
|
27 |
+
if ( is_readable($path) ) {
|
28 |
+
require $path;
|
29 |
+
}
|
30 |
+
}
|
31 |
+
spl_autoload_register('slb_autoload');
|
32 |
+
|
33 |
+
/* Load Assets */
|
34 |
+
|
35 |
+
$path = dirname(__FILE__) . '/';
|
36 |
+
require_once $path . 'controller.php';
|
37 |
+
$GLOBALS['slb'] = new SLB_Lightbox();
|
38 |
+
require_once $path . 'functions.php';
|
main.php
CHANGED
@@ -1,57 +1,48 @@
|
|
1 |
-
<?php
|
2 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
Plugin Name: Simple Lightbox
|
4 |
-
Plugin URI: http://archetyped.com/
|
5 |
Description: The highly customizable lightbox for WordPress
|
6 |
-
Version: 2.
|
|
|
|
|
7 |
Author: Archetyped
|
8 |
Author URI: http://archetyped.com
|
9 |
-
|
10 |
-
/*
|
11 |
-
Copyright 2013 Solomon Marchessault (sol@archetyped.com)
|
12 |
-
|
13 |
-
This program is free software; you can redistribute it and/or
|
14 |
-
modify it under the terms of the GNU General Public License
|
15 |
-
as published by the Free Software Foundation; either version 2
|
16 |
-
of the License, or (at your option) any later version.
|
17 |
-
|
18 |
-
This program is distributed in the hope that it will be useful,
|
19 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
20 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
21 |
-
GNU General Public License for more details.
|
22 |
-
|
23 |
-
You should have received a copy of the GNU General Public License
|
24 |
-
along with this program; if not, write to the Free Software
|
25 |
-
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
26 |
*/
|
27 |
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
|
|
|
|
|
|
|
|
|
|
45 |
}
|
|
|
46 |
}
|
47 |
|
48 |
-
|
49 |
-
|
50 |
-
require_once 'model.php';
|
51 |
-
|
52 |
-
$slb = new SLB_Lightbox();
|
53 |
-
|
54 |
-
function slb_register_theme($name, $title, $stylesheet_url, $layout) {
|
55 |
-
global $slb;
|
56 |
-
$slb->register_theme($name, $title, $stylesheet_url, $layout);
|
57 |
-
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Plugin entrypoint
|
4 |
+
*
|
5 |
+
* @package Simple Lightbox
|
6 |
+
* @author Archetyped <support@archetyped.com>
|
7 |
+
* @copyright 2018 Archetyped
|
8 |
+
*/
|
9 |
+
|
10 |
+
/*
|
11 |
Plugin Name: Simple Lightbox
|
12 |
+
Plugin URI: http://archetyped.com/tools/simple-lightbox/
|
13 |
Description: The highly customizable lightbox for WordPress
|
14 |
+
Version: 2.7.1
|
15 |
+
Text Domain: simple-lightbox
|
16 |
+
Domain Path: /l10n
|
17 |
Author: Archetyped
|
18 |
Author URI: http://archetyped.com
|
19 |
+
Support URI: https://github.com/archetyped/simple-lightbox/wiki/Feedback-&-Support
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
*/
|
21 |
|
22 |
+
require_once dirname( __FILE__ ) . '/includes/class-requirements-check.php';
|
23 |
+
|
24 |
+
/* @var array Plugin Requirements */
|
25 |
+
$slb_requirements = new SLB_Requirements_Check(
|
26 |
+
array(
|
27 |
+
'name' => __( 'Simple Lightbox', 'simple-lightbox' ),
|
28 |
+
'file' => __FILE__,
|
29 |
+
'uri' => array(
|
30 |
+
'reference' => 'https://github.com/archetyped/simple-lightbox/wiki/Requirements',
|
31 |
+
),
|
32 |
+
)
|
33 |
+
);
|
34 |
+
|
35 |
+
// Check requirements before initializing plugin.
|
36 |
+
if ( $slb_requirements->passes() ) {
|
37 |
+
/**
|
38 |
+
* Initialize SLB
|
39 |
+
*
|
40 |
+
* @return void
|
41 |
+
*/
|
42 |
+
function slb_init() {
|
43 |
+
require_once dirname( __FILE__ ) . '/load.php';
|
44 |
}
|
45 |
+
add_action( 'init', 'slb_init', 1 );
|
46 |
}
|
47 |
|
48 |
+
unset( $slb_requirements );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
model.php
DELETED
@@ -1,1097 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Model (Core functionality)
|
5 |
-
* @package Simple Lightbox
|
6 |
-
* @author Archetyped
|
7 |
-
*/
|
8 |
-
class SLB_Lightbox extends SLB_Base {
|
9 |
-
|
10 |
-
/*-** Properties **-*/
|
11 |
-
|
12 |
-
protected $model = true;
|
13 |
-
|
14 |
-
/* Files */
|
15 |
-
|
16 |
-
var $scripts = array (
|
17 |
-
'core' => array (
|
18 |
-
'file' => 'client/js/lib.core.js',
|
19 |
-
'deps' => 'jquery',
|
20 |
-
'enqueue' => false,
|
21 |
-
'in_footer' => true,
|
22 |
-
),
|
23 |
-
'view' => array (
|
24 |
-
'file' => 'client/js/lib.view.js',
|
25 |
-
'deps' => array('jquery', '[core]'),
|
26 |
-
'context' => array( array('public', '[is_enabled]') ),
|
27 |
-
'in_footer' => true,
|
28 |
-
),
|
29 |
-
);
|
30 |
-
|
31 |
-
/**
|
32 |
-
* Fields
|
33 |
-
* @var SLB_Fields
|
34 |
-
*/
|
35 |
-
public $fields = null;
|
36 |
-
|
37 |
-
/**
|
38 |
-
* Themes collection
|
39 |
-
* @var SLB_Themes
|
40 |
-
*/
|
41 |
-
var $themes = null;
|
42 |
-
|
43 |
-
/**
|
44 |
-
* Content types
|
45 |
-
* @var SLB_Content_Handlers
|
46 |
-
*/
|
47 |
-
var $handlers = null;
|
48 |
-
|
49 |
-
/**
|
50 |
-
* Template tags
|
51 |
-
* @var SLB_Template_Tags
|
52 |
-
*/
|
53 |
-
var $template_tags = null;
|
54 |
-
|
55 |
-
/**
|
56 |
-
* Properties for media attachments in current request
|
57 |
-
* > Key (string) Attachment URI
|
58 |
-
* > Value (assoc-array) Attachment properties (url, etc.)
|
59 |
-
* > source: Source URL
|
60 |
-
* @var array
|
61 |
-
*/
|
62 |
-
var $media_items = array();
|
63 |
-
|
64 |
-
/**
|
65 |
-
* Raw media items
|
66 |
-
* Used for populating media object on client-side
|
67 |
-
* > Key: Item URI
|
68 |
-
* > Value: Associative array of media properties
|
69 |
-
* > type: Item type (Default: null)
|
70 |
-
* > id: Item ID (Default: null)
|
71 |
-
* @var array
|
72 |
-
*/
|
73 |
-
private $media_items_raw = array();
|
74 |
-
|
75 |
-
/* Widget properties */
|
76 |
-
|
77 |
-
/**
|
78 |
-
* Widget callback key
|
79 |
-
* @var string
|
80 |
-
*/
|
81 |
-
var $widget_callback = 'callback';
|
82 |
-
|
83 |
-
/**
|
84 |
-
* Key to use to store original callback
|
85 |
-
* @var string
|
86 |
-
*/
|
87 |
-
var $widget_callback_orig = 'callback_orig';
|
88 |
-
|
89 |
-
/**
|
90 |
-
* Used to track if widget is currently being processed or not
|
91 |
-
* @var bool
|
92 |
-
*/
|
93 |
-
var $widget_processing = false;
|
94 |
-
|
95 |
-
/**
|
96 |
-
* Constructor
|
97 |
-
*/
|
98 |
-
function __construct() {
|
99 |
-
parent::__construct();
|
100 |
-
//Init instances
|
101 |
-
$this->fields = new SLB_Fields();
|
102 |
-
$this->themes = new SLB_Themes($this);
|
103 |
-
if ( !is_admin() ) {
|
104 |
-
$this->template_tags = new SLB_Template_Tags($this);
|
105 |
-
}
|
106 |
-
}
|
107 |
-
|
108 |
-
/* Init */
|
109 |
-
|
110 |
-
/**
|
111 |
-
* Register hooks
|
112 |
-
* @uses parent::_hooks()
|
113 |
-
*/
|
114 |
-
protected function _hooks() {
|
115 |
-
parent::_hooks();
|
116 |
-
|
117 |
-
/* Admin */
|
118 |
-
add_action('admin_menu', $this->m('admin_menus'));
|
119 |
-
|
120 |
-
/* Client-side */
|
121 |
-
|
122 |
-
//Init lightbox
|
123 |
-
$priority = $this->util->priority('low');
|
124 |
-
add_action('wp_footer', $this->m('client_init'), $this->util->priority('client_footer_output'));
|
125 |
-
add_action('wp_footer', $this->m('client_footer'), $priority);
|
126 |
-
//Link activation
|
127 |
-
add_filter('the_content', $this->m('activate_links'), $priority);
|
128 |
-
//Gallery wrapping
|
129 |
-
add_filter('the_content', $this->m('gallery_wrap'), 1);
|
130 |
-
add_filter('the_content', $this->m('gallery_unwrap'), $priority + 1);
|
131 |
-
|
132 |
-
/* Widgets */
|
133 |
-
add_filter('sidebars_widgets', $this->m('sidebars_widgets'));
|
134 |
-
}
|
135 |
-
|
136 |
-
/**
|
137 |
-
* Init options
|
138 |
-
*
|
139 |
-
*/
|
140 |
-
protected function _options() {
|
141 |
-
//Setup options
|
142 |
-
$opts = array (
|
143 |
-
'groups' => array (
|
144 |
-
'activation' => array ( 'title' => __('Activation', 'simple-lightbox'), 'priority' => 10),
|
145 |
-
'grouping' => array ( 'title' => __('Grouping', 'simple-lightbox'), 'priority' => 20),
|
146 |
-
'ui' => array ( 'title' => __('UI', 'simple-lightbox'), 'priority' => 30),
|
147 |
-
'labels' => array ( 'title' => __('Labels', 'simple-lightbox'), 'priority' => 40),
|
148 |
-
),
|
149 |
-
'items' => array (
|
150 |
-
'enabled' => array('title' => __('Enable Lightbox Functionality', 'simple-lightbox'), 'default' => true, 'group' => array('activation', 10)),
|
151 |
-
'enabled_home' => array('title' => __('Enable on Home page', 'simple-lightbox'), 'default' => true, 'group' => array('activation', 20)),
|
152 |
-
'enabled_post' => array('title' => __('Enable on Posts', 'simple-lightbox'), 'default' => true, 'group' => array('activation', 30)),
|
153 |
-
'enabled_page' => array('title' => __('Enable on Pages', 'simple-lightbox'), 'default' => true, 'group' => array('activation', 40)),
|
154 |
-
'enabled_archive' => array('title' => __('Enable on Archive Pages (tags, categories, etc.)', 'simple-lightbox'), 'default' => true, 'group' => array('activation', 50)),
|
155 |
-
'enabled_widget' => array('title' => __('Enable for Widgets', 'simple-lightbox'), 'default' => false, 'group' => array('activation', 60)),
|
156 |
-
'group_links' => array('title' => __('Group items (for displaying as a slideshow)', 'simple-lightbox'), 'default' => true, 'group' => array('grouping', 10)),
|
157 |
-
'group_post' => array('title' => __('Group items by Post (e.g. on pages with multiple posts)', 'simple-lightbox'), 'default' => true, 'group' => array('grouping', 20)),
|
158 |
-
'group_gallery' => array('title' => __('Group gallery items separately', 'simple-lightbox'), 'default' => false, 'group' => array('grouping', 30)),
|
159 |
-
'group_widget' => array('title' => __('Group widget items separately', 'simple-lightbox'), 'default' => false, 'group' => array('grouping', 40)),
|
160 |
-
'ui_autofit' => array('title' => __('Resize lightbox to fit in window', 'simple-lightbox'), 'default' => true, 'group' => array('ui', 10), 'in_client' => true),
|
161 |
-
'ui_animate' => array('title' => __('Enable animations', 'simple-lightbox'), 'default' => true, 'group' => array('ui', 20), 'in_client' => true),
|
162 |
-
'slideshow_autostart' => array('title' => __('Start Slideshow Automatically', 'simple-lightbox'), 'default' => true, 'group' => array('ui', 30), 'in_client' => true),
|
163 |
-
'slideshow_duration' => array('title' => __('Slide Duration (Seconds)', 'simple-lightbox'), 'default' => '6', 'attr' => array('size' => 3, 'maxlength' => 3), 'group' => array('ui', 40), 'in_client' => true),
|
164 |
-
'group_loop' => array('title' => __('Loop through items', 'simple-lightbox'),'default' => true, 'group' => array('ui', 50), 'in_client' => true),
|
165 |
-
'ui_overlay_opacity' => array('title' => __('Overlay Opacity (0 - 1)', 'simple-lightbox'), 'default' => '0.8', 'attr' => array('size' => 3, 'maxlength' => 3), 'group' => array('ui', 60), 'in_client' => true),
|
166 |
-
'txt_loading' => array('title' => __('Loading indicator', 'simple-lightbox'), 'default' => 'Loading', 'group' => array('labels', 20)),
|
167 |
-
'txt_close' => array('title' => __('Close button', 'simple-lightbox'), 'default' => 'Close', 'group' => array('labels', 10)),
|
168 |
-
'txt_nav_next' => array('title' => __('Next Item button', 'simple-lightbox'), 'default' => 'Next', 'group' => array('labels', 30)),
|
169 |
-
'txt_nav_prev' => array('title' => __('Previous Item button', 'simple-lightbox'), 'default' => 'Previous', 'group' => array('labels', 40)),
|
170 |
-
'txt_slideshow_start' => array('title' => __('Start Slideshow button', 'simple-lightbox'), 'default' => 'Start slideshow', 'group' => array('labels', 50)),
|
171 |
-
'txt_slideshow_stop' => array('title' => __('Stop Slideshow button', 'simple-lightbox'),'default' => 'Stop slideshow', 'group' => array('labels', 60)),
|
172 |
-
'txt_group_status' => array('title' => __('Slideshow status format', 'simple-lightbox'), 'default' => 'Item %current% of %total%', 'group' => array('labels', 70))
|
173 |
-
),
|
174 |
-
'legacy' => array (
|
175 |
-
'header_activation' => null,
|
176 |
-
'header_enabled' => null,
|
177 |
-
'header_strings' => null,
|
178 |
-
'header_ui' => null,
|
179 |
-
'activate_attachments' => null,
|
180 |
-
'validate_links' => null,
|
181 |
-
'enabled_compat' => null,
|
182 |
-
'enabled_single' => array('enabled_post', 'enabled_page'),
|
183 |
-
'enabled_caption' => null,
|
184 |
-
'enabled_desc' => null,
|
185 |
-
'ui_enabled_caption' => null,
|
186 |
-
'ui_caption_src' => null,
|
187 |
-
'ui_enabled_desc' => null,
|
188 |
-
'caption_src' => null,
|
189 |
-
'animate' => 'ui_animate',
|
190 |
-
'overlay_opacity' => 'ui_overlay_opacity',
|
191 |
-
'loop' => 'group_loop',
|
192 |
-
'autostart' => 'slideshow_autostart',
|
193 |
-
'duration' => 'slideshow_duration',
|
194 |
-
'txt_numDisplayPrefix' => null,
|
195 |
-
'txt_numDisplaySeparator' => null,
|
196 |
-
'txt_closeLink' => 'txt_link_close',
|
197 |
-
'txt_nextLink' => 'txt_link_next',
|
198 |
-
'txt_prevLink' => 'txt_link_prev',
|
199 |
-
'txt_startSlideshow' => 'txt_slideshow_start',
|
200 |
-
'txt_stopSlideshow' => 'txt_slideshow_stop',
|
201 |
-
'txt_loadingMsg' => 'txt_loading',
|
202 |
-
'txt_link_next' => 'txt_nav_next',
|
203 |
-
'txt_link_prev' => 'txt_nav_prev',
|
204 |
-
'txt_link_close' => 'txt_close',
|
205 |
-
)
|
206 |
-
);
|
207 |
-
|
208 |
-
parent::_options($opts);
|
209 |
-
}
|
210 |
-
|
211 |
-
/* Methods */
|
212 |
-
|
213 |
-
/*-** Admin **-*/
|
214 |
-
|
215 |
-
/**
|
216 |
-
* Add admin menus
|
217 |
-
* @uses this->admin->add_theme_page
|
218 |
-
*/
|
219 |
-
function admin_menus() {
|
220 |
-
$options_labels = array(
|
221 |
-
'menu' => __('Lightbox', 'simple-lightbox'),
|
222 |
-
'header' => __('Lightbox Settings', 'simple-lightbox'),
|
223 |
-
'plugin_action' => __('Settings', 'simple-lightbox')
|
224 |
-
);
|
225 |
-
|
226 |
-
$labels_reset = array (
|
227 |
-
'title' => __('Reset', 'simple-lightbox'),
|
228 |
-
'confirm' => __('Are you sure you want to reset settings?', 'simple-lightbox'),
|
229 |
-
'success' => __('Settings have been reset', 'simple-lightbox'),
|
230 |
-
'failure' => __('Settings were not reset', 'simple-lightbox')
|
231 |
-
);
|
232 |
-
|
233 |
-
$this->admin->add_theme_page('options', $options_labels, $this->options);
|
234 |
-
$this->admin->add_reset('reset', $labels_reset, $this->options);
|
235 |
-
}
|
236 |
-
|
237 |
-
/*-** Functionality **-*/
|
238 |
-
|
239 |
-
/**
|
240 |
-
* Checks whether lightbox is currently enabled/disabled
|
241 |
-
* @return bool TRUE if lightbox is currently enabled, FALSE otherwise
|
242 |
-
*/
|
243 |
-
function is_enabled($check_request = true) {
|
244 |
-
$ret = ( $this->options->get_bool('enabled') && !is_feed() ) ? true : false;
|
245 |
-
if ( $ret && $check_request ) {
|
246 |
-
$opt = '';
|
247 |
-
//Determine option to check
|
248 |
-
if ( is_home() )
|
249 |
-
$opt = 'home';
|
250 |
-
elseif ( is_singular() ) {
|
251 |
-
$opt = ( is_page() ) ? 'page' : 'post';
|
252 |
-
}
|
253 |
-
elseif ( is_archive() || is_search() )
|
254 |
-
$opt = 'archive';
|
255 |
-
//Check option
|
256 |
-
if ( !empty($opt) && ( $opt = 'enabled_' . $opt ) && $this->options->has($opt) ) {
|
257 |
-
$ret = $this->options->get_bool($opt);
|
258 |
-
}
|
259 |
-
}
|
260 |
-
return $ret;
|
261 |
-
}
|
262 |
-
|
263 |
-
/**
|
264 |
-
* Scans post content for image links and activates them
|
265 |
-
*
|
266 |
-
* Lightbox will not be activated for feeds
|
267 |
-
* @param $content
|
268 |
-
* @return string Post content
|
269 |
-
*/
|
270 |
-
function activate_links($content) {
|
271 |
-
//Activate links only if enabled
|
272 |
-
if ( !$this->is_enabled() ) {
|
273 |
-
return $content;
|
274 |
-
}
|
275 |
-
|
276 |
-
$groups = array();
|
277 |
-
$w = $this->group_get_wrapper();
|
278 |
-
$g_ph_f = '[%s]';
|
279 |
-
|
280 |
-
//Strip groups
|
281 |
-
if ( $this->options->get_bool('group_gallery') ) {
|
282 |
-
$groups = array();
|
283 |
-
static $g_idx = 1;
|
284 |
-
$g_end_idx = 0;
|
285 |
-
//Iterate through galleries
|
286 |
-
while ( ($g_start_idx = strpos($content, $w->open, $g_end_idx)) && $g_start_idx !== false
|
287 |
-
&& ($g_end_idx = strpos($content, $w->close, $g_start_idx)) && $g_end_idx != false ) {
|
288 |
-
$g_start_idx += strlen($w->open);
|
289 |
-
//Extract gallery content & save for processing
|
290 |
-
$g_len = $g_end_idx - $g_start_idx;
|
291 |
-
$groups[$g_idx] = substr($content, $g_start_idx, $g_len);
|
292 |
-
//Replace content with placeholder
|
293 |
-
$g_ph = sprintf($g_ph_f, $g_idx);
|
294 |
-
$content = substr_replace($content, $g_ph, $g_start_idx, $g_len);
|
295 |
-
//Increment gallery count
|
296 |
-
$g_idx++;
|
297 |
-
//Update end index
|
298 |
-
$g_end_idx = $g_start_idx + strlen($w->open);
|
299 |
-
}
|
300 |
-
}
|
301 |
-
|
302 |
-
//General link processing
|
303 |
-
$content = $this->process_links($content);
|
304 |
-
|
305 |
-
//Reintegrate Groups
|
306 |
-
foreach ( $groups as $group => $g_content ) {
|
307 |
-
$g_ph = $w->open . sprintf($g_ph_f, $group) . $w->close;
|
308 |
-
//Skip group if placeholder does not exist in content
|
309 |
-
if ( strpos($content, $g_ph) === false ) {
|
310 |
-
continue;
|
311 |
-
}
|
312 |
-
//Replace placeholder with processed content
|
313 |
-
$content = str_replace($g_ph, $w->open . $this->process_links($g_content, 'gallery_' . $group) . $w->close, $content);
|
314 |
-
}
|
315 |
-
return $content;
|
316 |
-
}
|
317 |
-
|
318 |
-
/**
|
319 |
-
* Process links in content
|
320 |
-
* @global obj $wpdb DB instance
|
321 |
-
* @global obj $post Current post
|
322 |
-
* @param string $content Text containing links
|
323 |
-
* @param string (optional) $group Group to add links to (Default: none)
|
324 |
-
* @return string Content with processed links
|
325 |
-
*/
|
326 |
-
function process_links($content, $group = null) {
|
327 |
-
//Validate
|
328 |
-
if ( !is_string($content) || empty($content) ) {
|
329 |
-
return $content;
|
330 |
-
}
|
331 |
-
//Extract links
|
332 |
-
$links = $this->get_links($content, true);
|
333 |
-
//Do not process content without links
|
334 |
-
if ( empty($links) ) {
|
335 |
-
return $content;
|
336 |
-
}
|
337 |
-
//Process links
|
338 |
-
$protocol = array('http://', 'https://');
|
339 |
-
$domain = str_replace($protocol, '', strtolower(get_bloginfo('url')));
|
340 |
-
$qv_att = 'attachment_id';
|
341 |
-
|
342 |
-
//Setup group properties
|
343 |
-
$g_props = (object) array(
|
344 |
-
'enabled' => $this->options->get_bool('group_links'),
|
345 |
-
'attr' => 'group',
|
346 |
-
'base' => '',
|
347 |
-
'legacy_prefix' => 'lightbox[',
|
348 |
-
'legacy_suffix' => ']'
|
349 |
-
);
|
350 |
-
if ( $g_props->enabled ) {
|
351 |
-
$g_props->base = ( is_scalar($group) ) ? trim(strval($group)) : '';
|
352 |
-
}
|
353 |
-
|
354 |
-
//Initialize content handlers
|
355 |
-
if ( !( $this->handlers instanceof SLB_Content_Handlers ) ) {
|
356 |
-
$this->handlers = new SLB_Content_Handlers($this);
|
357 |
-
}
|
358 |
-
|
359 |
-
//Iterate through links & add lightbox if necessary
|
360 |
-
foreach ( $links as $link ) {
|
361 |
-
//Init vars
|
362 |
-
$pid = 0;
|
363 |
-
$link_new = $link;
|
364 |
-
$internal = false;
|
365 |
-
$q = null;
|
366 |
-
$uri = (object) array('raw' => '', 'base' => '', 'source' => '');
|
367 |
-
$type = false;
|
368 |
-
|
369 |
-
//Parse link attributes
|
370 |
-
$attrs = $this->util->parse_attribute_string($link_new, array('href' => ''));
|
371 |
-
$attrs_legacy = ( isset($attrs['rel']) && !empty($attrs['rel']) ) ? explode(' ', trim($attrs['rel'])) : array();
|
372 |
-
//Get URI
|
373 |
-
$uri->raw = $uri->base = $uri->source = $attrs['href'];
|
374 |
-
|
375 |
-
//Stop processing invalid links
|
376 |
-
if ( empty($uri->raw) //Empty
|
377 |
-
|| 0 === strpos($uri->raw, '#') //Invalid
|
378 |
-
|| $this->has_attribute($attrs, 'active', false) //Prev-processed
|
379 |
-
|| in_array($this->add_prefix('off'), $attrs_legacy) //Disabled
|
380 |
-
) {
|
381 |
-
continue;
|
382 |
-
}
|
383 |
-
|
384 |
-
//Process legacy attributes
|
385 |
-
if ( !empty($attrs_legacy) ) {
|
386 |
-
//Group
|
387 |
-
if ( $g_props->enabled ) {
|
388 |
-
foreach ( $attrs_legacy as $attr ) {
|
389 |
-
if ( 0 === strpos($attr, $g_props->legacy_prefix) && substr($attr, -1) == $g_props->legacy_suffix ) {
|
390 |
-
$this->set_attribute($attrs, $g_props->attr, substr($attr, strlen($g_props->legacy_prefix), -1));
|
391 |
-
break;
|
392 |
-
}
|
393 |
-
}
|
394 |
-
unset($attr);
|
395 |
-
}
|
396 |
-
}
|
397 |
-
|
398 |
-
//Check if item links to internal media (attachment)
|
399 |
-
$uri_dom = str_replace($protocol, '', strtolower($uri->raw));
|
400 |
-
if ( strpos($uri_dom, $domain) === 0 ) {
|
401 |
-
//Save URL for further processing
|
402 |
-
$internal = true;
|
403 |
-
}
|
404 |
-
|
405 |
-
//Sanitize URI
|
406 |
-
$qpos = strpos($uri->raw, '?');
|
407 |
-
if ( $qpos !== false ) {
|
408 |
-
$uri->base = substr($uri->raw, 0, $qpos);
|
409 |
-
if ( $internal ) {
|
410 |
-
//Extract query string
|
411 |
-
$q = substr($uri->raw, $qpos + 1);
|
412 |
-
//Check for attachment ID
|
413 |
-
if ( strpos($q, $qv_att . '=') !== false ) {
|
414 |
-
//Parse query string
|
415 |
-
wp_parse_str($q, $q);
|
416 |
-
//Strip other variables from query string
|
417 |
-
$uri->base = add_query_arg($qv_att, $q[$qv_att], $uri->base);
|
418 |
-
}
|
419 |
-
}
|
420 |
-
}
|
421 |
-
|
422 |
-
//Get source URI
|
423 |
-
$uri->source = $uri->base;
|
424 |
-
if ( $internal && is_local_attachment($uri->source) ) {
|
425 |
-
$pid = url_to_postid($uri->base);
|
426 |
-
$src = wp_get_attachment_url($pid);
|
427 |
-
if ( !!$src ) {
|
428 |
-
$uri->source = $src;
|
429 |
-
}
|
430 |
-
unset($src);
|
431 |
-
}
|
432 |
-
|
433 |
-
/* Determine link type */
|
434 |
-
|
435 |
-
//Check if URI has already been processed
|
436 |
-
if ( $this->media_item_cached($uri->base) ) {
|
437 |
-
$i = $this->get_cached_media_item($uri->base);
|
438 |
-
$type = $i->type;
|
439 |
-
}
|
440 |
-
|
441 |
-
//Get handler match
|
442 |
-
else {
|
443 |
-
$handler = $this->handlers->match($uri->source);
|
444 |
-
if ( !!$handler ) {
|
445 |
-
$type = $handler->get_id();
|
446 |
-
}
|
447 |
-
}
|
448 |
-
|
449 |
-
//Stop processing if link type not valid
|
450 |
-
if ( !$type ) {
|
451 |
-
continue;
|
452 |
-
}
|
453 |
-
|
454 |
-
//Set group (if necessary)
|
455 |
-
if ( $g_props->enabled ) {
|
456 |
-
//Get preset group attribute
|
457 |
-
$g = ( $this->has_attribute($attrs, $g_props->attr) ) ? $this->get_attribute($attrs, $g_props->attr) : '';
|
458 |
-
if ( is_string($g) && ($g = trim($g)) && !empty($g) ) {
|
459 |
-
$group = $g;
|
460 |
-
} else {
|
461 |
-
$group = $g_props->base;
|
462 |
-
}
|
463 |
-
//Group links by post?
|
464 |
-
if ( !$this->widget_processing && $this->options->get_bool('group_post') ) {
|
465 |
-
global $post;
|
466 |
-
$group = ( !empty($group) ) ? implode('_', array($post->ID, $group)) : $post->ID;
|
467 |
-
}
|
468 |
-
//Default group
|
469 |
-
if ( empty($group) ) {
|
470 |
-
$group = $this->get_prefix();
|
471 |
-
}
|
472 |
-
|
473 |
-
//Set group attribute
|
474 |
-
$this->set_attribute($attrs, $g_props->attr, $group);
|
475 |
-
unset($g);
|
476 |
-
}
|
477 |
-
|
478 |
-
//Activate link
|
479 |
-
$this->set_attribute($attrs, 'active');
|
480 |
-
|
481 |
-
//Process internal links
|
482 |
-
if ( $internal ) {
|
483 |
-
//Mark as internal
|
484 |
-
$this->set_attribute($attrs, 'internal', $pid);
|
485 |
-
}
|
486 |
-
|
487 |
-
//Cache item attributes
|
488 |
-
$this->cache_media_item($uri, $type, $internal, $pid);
|
489 |
-
|
490 |
-
//Update link in content
|
491 |
-
$link_new = '<a ' . $this->util->build_attribute_string($attrs) . '>';
|
492 |
-
$content = str_replace($link, $link_new, $content);
|
493 |
-
}
|
494 |
-
return $content;
|
495 |
-
}
|
496 |
-
|
497 |
-
/**
|
498 |
-
* Retrieve HTML links in content
|
499 |
-
* @param string $content Content to get links from
|
500 |
-
* @param bool (optional) $unique Remove duplicates from returned links (Default: FALSE)
|
501 |
-
* @return array Links in content
|
502 |
-
*/
|
503 |
-
function get_links($content, $unique = false) {
|
504 |
-
$rgx = "/\<a[^\>]+href=.*?\>/i";
|
505 |
-
$links = array();
|
506 |
-
preg_match_all($rgx, $content, $links);
|
507 |
-
$links = $links[0];
|
508 |
-
if ( $unique )
|
509 |
-
$links = array_unique($links);
|
510 |
-
return $links;
|
511 |
-
}
|
512 |
-
|
513 |
-
/**
|
514 |
-
* Sets options/settings to initialize lightbox functionality on page load
|
515 |
-
* @return void
|
516 |
-
*/
|
517 |
-
function client_init() {
|
518 |
-
if ( ! $this->is_enabled() ) {
|
519 |
-
return;
|
520 |
-
}
|
521 |
-
echo PHP_EOL . '<!-- SLB -->' . PHP_EOL;
|
522 |
-
//Get options
|
523 |
-
$options = $this->options->build_client_output();
|
524 |
-
|
525 |
-
//Load UI Strings
|
526 |
-
if ( ($labels = $this->build_labels()) && !empty($labels) ) {
|
527 |
-
$options['ui_labels'] = $labels;
|
528 |
-
}
|
529 |
-
|
530 |
-
//Build client output
|
531 |
-
echo $this->util->build_script_element($this->util->call_client_method('View.init', $options), 'init', true, true);
|
532 |
-
echo '<!-- /SLB -->' . PHP_EOL;
|
533 |
-
}
|
534 |
-
|
535 |
-
/**
|
536 |
-
* Output code in footer
|
537 |
-
* > Media attachment URLs
|
538 |
-
* @uses `_wp_attached_file` to match attachment ID to URI
|
539 |
-
* @uses `_wp_attachment_metadata` to retrieve attachment metadata
|
540 |
-
*/
|
541 |
-
function client_footer() {
|
542 |
-
echo '<!-- X-M -->';
|
543 |
-
//Stop if not enabled
|
544 |
-
if ( !$this->is_enabled() ) {
|
545 |
-
return;
|
546 |
-
}
|
547 |
-
echo '<!-- SLB-M -->' . PHP_EOL;
|
548 |
-
|
549 |
-
$client_out = array();
|
550 |
-
|
551 |
-
/* Load cached media */
|
552 |
-
if ( $this->has_cached_media_items() ) {
|
553 |
-
global $wpdb;
|
554 |
-
|
555 |
-
$this->media_items = array();
|
556 |
-
$props = array('id', 'type', 'description', 'title', 'source', 'caption');
|
557 |
-
$props = (object) array_combine($props, $props);
|
558 |
-
$props_map = array('description' => 'post_content', 'title' => 'post_title', 'caption' => 'post_excerpt');
|
559 |
-
|
560 |
-
//Separate media into buckets by type
|
561 |
-
$m_bucket = array();
|
562 |
-
$m_internals = array();
|
563 |
-
$type = $id = null;
|
564 |
-
|
565 |
-
$m_items = $this->media_items = $this->get_cached_media_items();
|
566 |
-
foreach ( $m_items as $uri => $p ) {
|
567 |
-
$type = $p->{$props->type};
|
568 |
-
//Initialize bucket (if necessary)
|
569 |
-
if ( !isset($m_bucket[$type]) ) {
|
570 |
-
$m_bucket[$type] = array();
|
571 |
-
}
|
572 |
-
//Add item to bucket
|
573 |
-
$m_bucket[$type][$uri] =& $m_items[$uri];
|
574 |
-
//Set aside internal links for additional processing
|
575 |
-
if ( $p->internal && !isset($m_internals[$uri]) ) {
|
576 |
-
$m_internals[$uri] =& $m_items[$uri];
|
577 |
-
}
|
578 |
-
}
|
579 |
-
unset($uri, $p);
|
580 |
-
|
581 |
-
//Process internal links
|
582 |
-
if ( !empty($m_internals) ) {
|
583 |
-
$uris_base = array();
|
584 |
-
$uri_prefix = wp_upload_dir();
|
585 |
-
$uri_prefix = $this->util->normalize_path($uri_prefix['baseurl'], true);
|
586 |
-
foreach ( $m_internals as $uri => $p ) {
|
587 |
-
//Prepare internal links
|
588 |
-
if ( !$p->id && strpos($p->source, $uri_prefix) === 0 ) {
|
589 |
-
$uris_base[str_replace($uri_prefix, '', $p->source)] = $uri;
|
590 |
-
}
|
591 |
-
}
|
592 |
-
unset($uri, $p);
|
593 |
-
|
594 |
-
//Retrieve attachment IDs
|
595 |
-
$uris_flat = "('" . implode("','", array_keys($uris_base)) . "')";
|
596 |
-
$q = $wpdb->prepare("SELECT post_id, meta_value FROM $wpdb->postmeta WHERE `meta_key` = %s AND LOWER(`meta_value`) IN $uris_flat LIMIT %d", '_wp_attached_file', count($uris_base));
|
597 |
-
$pids = $wpdb->get_results($q);
|
598 |
-
//Match IDs to URIs
|
599 |
-
if ( $pids ) {
|
600 |
-
foreach ( $pids as $pd ) {
|
601 |
-
$file =& $pd->meta_value;
|
602 |
-
if ( isset($uris_base[$file]) ) {
|
603 |
-
$m_internals[ $uris_base[$file] ]->{$props->id} = absint($pd->post_id);
|
604 |
-
}
|
605 |
-
}
|
606 |
-
}
|
607 |
-
//Destroy worker vars
|
608 |
-
unset($uris_base, $uris_flat, $q, $pids, $pd);
|
609 |
-
}
|
610 |
-
|
611 |
-
//Process items with attachment IDs
|
612 |
-
$pids = array();
|
613 |
-
foreach ( $m_items as $uri => $p ) {
|
614 |
-
//Add post ID to query
|
615 |
-
if ( !!$p->id ) {
|
616 |
-
//Create array for ID (support multiple URIs per ID)
|
617 |
-
if ( !isset($pids[$p->id]) ) {
|
618 |
-
$pids[$p->id] = array();
|
619 |
-
}
|
620 |
-
//Add URI to ID
|
621 |
-
$pids[$p->id][] = $uri;
|
622 |
-
}
|
623 |
-
}
|
624 |
-
unset($uri, $p);
|
625 |
-
|
626 |
-
//Retrieve attachment properties
|
627 |
-
if ( !empty($pids) ) {
|
628 |
-
$pids_flat = array_keys($pids);
|
629 |
-
//Retrieve attachment post data
|
630 |
-
$atts = get_posts(array('post_type' => 'attachment', 'include' => $pids_flat));
|
631 |
-
|
632 |
-
//Process attachments
|
633 |
-
if ( $atts ) {
|
634 |
-
//Retrieve attachment metadata
|
635 |
-
$pids_flat = "('" . implode("','", $pids_flat) . "')";
|
636 |
-
$atts_meta = $wpdb->get_results($wpdb->prepare("SELECT `post_id`,`meta_value` FROM $wpdb->postmeta WHERE `post_id` IN $pids_flat AND `meta_key` = %s LIMIT %d", '_wp_attachment_metadata', count($atts)));
|
637 |
-
//Restructure metadata array by post ID
|
638 |
-
if ( $atts_meta ) {
|
639 |
-
$meta = array();
|
640 |
-
foreach ( $atts_meta as $att_meta ) {
|
641 |
-
$meta[$att_meta->post_id] = $att_meta->meta_value;
|
642 |
-
}
|
643 |
-
$atts_meta = $meta;
|
644 |
-
unset($meta);
|
645 |
-
} else {
|
646 |
-
$atts_meta = array();
|
647 |
-
}
|
648 |
-
$props_size = array('file', 'width', 'height');
|
649 |
-
$props_exclude = array('hwstring_small');
|
650 |
-
foreach ( $atts as $att ) {
|
651 |
-
//Set post data
|
652 |
-
$m = array();
|
653 |
-
//Remap post data to properties
|
654 |
-
foreach ( $props_map as $prop_key => $prop_source ) {
|
655 |
-
$m[$props->{$prop_key}] = $att->{$prop_source};
|
656 |
-
}
|
657 |
-
unset($prop_key, $prop_source);
|
658 |
-
|
659 |
-
//Add metadata
|
660 |
-
if ( isset($atts_meta[$att->ID]) && ($a = unserialize($atts_meta[$att->ID])) && is_array($a) ) {
|
661 |
-
//Move original size into `sizes` array
|
662 |
-
foreach ( $props_size as $d ) {
|
663 |
-
if ( !isset($a[$d]) ) {
|
664 |
-
continue;
|
665 |
-
}
|
666 |
-
$a['sizes']['original'][$d] = $a[$d];
|
667 |
-
unset($a[$d]);
|
668 |
-
}
|
669 |
-
|
670 |
-
//Strip extraneous metadata
|
671 |
-
foreach ( $props_exclude as $d ) {
|
672 |
-
if ( isset($a[$d]) ) {
|
673 |
-
unset($a[$d]);
|
674 |
-
}
|
675 |
-
}
|
676 |
-
|
677 |
-
//Merge post data & meta data
|
678 |
-
$m = array_merge($a, $m);
|
679 |
-
//Destroy worker vars
|
680 |
-
unset($a, $d);
|
681 |
-
}
|
682 |
-
|
683 |
-
//Save attachment data (post & meta) to original object(s)
|
684 |
-
foreach ( $pids[$att->ID] as $uri ) {
|
685 |
-
$this->media_items[$uri] = (object) array_merge( (array) $m_items[$uri], $m);
|
686 |
-
}
|
687 |
-
}
|
688 |
-
}
|
689 |
-
unset($atts, $atts_meta, $m, $a, $uri, $pids, $pids_flat);
|
690 |
-
}
|
691 |
-
|
692 |
-
//Build client output
|
693 |
-
$obj = 'View.assets';
|
694 |
-
$client_out[] = $this->util->extend_client_object($obj, $this->media_items);
|
695 |
-
}
|
696 |
-
if ( !empty($client_out) ) {
|
697 |
-
echo $this->util->build_script_element($client_out, 'footer', true, true);
|
698 |
-
}
|
699 |
-
echo PHP_EOL . '<!-- /SLB-M -->' . PHP_EOL;
|
700 |
-
}
|
701 |
-
|
702 |
-
/*-** Media **-*/
|
703 |
-
|
704 |
-
/**
|
705 |
-
* Cache media properties for later processing
|
706 |
-
* @param object $uri URI to cache
|
707 |
-
* Members
|
708 |
-
* > raw: Raw Link URI
|
709 |
-
* > base: Sanitized URI
|
710 |
-
* > source: Source URI (e.g. for attachment URIs)
|
711 |
-
* @param string $type Media type (image, attachment, etc.)
|
712 |
-
* @param int $id (optional) ID of media item (for internal items) (Default: NULL)
|
713 |
-
*/
|
714 |
-
private function cache_media_item($uri, $type, $internal, $id = null) {
|
715 |
-
//Validate
|
716 |
-
if ( !is_object($uri) || !is_string($type) ) {
|
717 |
-
return false;
|
718 |
-
}
|
719 |
-
if ( !$this->media_item_cached($uri->base) ) {
|
720 |
-
//Set properties
|
721 |
-
$i = array('type' => $type, 'source' => $uri->source, 'internal' => $internal, 'id' => null, '_entries' => array());
|
722 |
-
//ID
|
723 |
-
if ( is_numeric($id) && !!$id ) {
|
724 |
-
$i['id'] = absint($id);
|
725 |
-
}
|
726 |
-
//Cache media item
|
727 |
-
$this->media_items_raw[$uri->base] = (object) $i;
|
728 |
-
}
|
729 |
-
//Add URI variants
|
730 |
-
$entries =& $this->media_items_raw[$uri->base]->_entries;
|
731 |
-
if ( !in_array($uri->raw, $entries) ) {
|
732 |
-
$entries[] = $uri->raw;
|
733 |
-
}
|
734 |
-
}
|
735 |
-
|
736 |
-
/**
|
737 |
-
* Checks if media item has already been cached
|
738 |
-
* @param string $uri URI of media item
|
739 |
-
* @return boolean Whether media item has been cached
|
740 |
-
*/
|
741 |
-
private function media_item_cached($uri) {
|
742 |
-
return ( is_string($uri) && isset($this->media_items_raw[$uri]) ) ? true : false;
|
743 |
-
}
|
744 |
-
|
745 |
-
/**
|
746 |
-
* Retrieve cached media item
|
747 |
-
* @param string $uri Media item URI
|
748 |
-
* @return object|null Media item properties (NULL if not set)
|
749 |
-
*/
|
750 |
-
private function get_cached_media_item($uri) {
|
751 |
-
return ( $this->media_item_cached($uri) ) ? $this->media_items_raw[$uri] : null;
|
752 |
-
}
|
753 |
-
|
754 |
-
/**
|
755 |
-
* Retrieve cached media items
|
756 |
-
* @return array Cached media items
|
757 |
-
*/
|
758 |
-
private function &get_cached_media_items() {
|
759 |
-
return $this->media_items_raw;
|
760 |
-
}
|
761 |
-
|
762 |
-
/**
|
763 |
-
* Check if media items have been cached
|
764 |
-
* @return boolean
|
765 |
-
*/
|
766 |
-
private function has_cached_media_items() {
|
767 |
-
return ( empty($this->media_items_raw) ) ? false : true;
|
768 |
-
}
|
769 |
-
|
770 |
-
/*-** Theme **-*/
|
771 |
-
|
772 |
-
/**
|
773 |
-
* Retrieve theme
|
774 |
-
* @param string $id ID of theme to retrieve
|
775 |
-
* @return SLB_Theme Theme instance
|
776 |
-
* @TODO Refactor
|
777 |
-
*/
|
778 |
-
function get_theme($id = '') {
|
779 |
-
//Default: Get current theme if no theme specified
|
780 |
-
if ( !$this->themes->has_item($id) ) {
|
781 |
-
$id = $this->options->get_value('theme');
|
782 |
-
if ( !$this->themes->has_item($id) ) {
|
783 |
-
$id = $this->themes->get_default_id();
|
784 |
-
}
|
785 |
-
}
|
786 |
-
return $this->themes->get_item($id);
|
787 |
-
}
|
788 |
-
|
789 |
-
/*-** Grouping **-*/
|
790 |
-
|
791 |
-
/**
|
792 |
-
* Builds wrapper for grouping
|
793 |
-
* @return object Wrapper properties
|
794 |
-
* > open
|
795 |
-
* > close
|
796 |
-
*/
|
797 |
-
function group_get_wrapper() {
|
798 |
-
static $wrapper = null;
|
799 |
-
if ( is_null($wrapper) ) {
|
800 |
-
$start = '<';
|
801 |
-
$end = '>';
|
802 |
-
$terminate = '/';
|
803 |
-
$val = $this->add_prefix('group');
|
804 |
-
//Build properties
|
805 |
-
$wrapper = array(
|
806 |
-
'open' => $start . $val . $end,
|
807 |
-
'close' => $start . $terminate . $val . $end
|
808 |
-
);
|
809 |
-
//Convert to object
|
810 |
-
$wrapper = (object) $wrapper;
|
811 |
-
}
|
812 |
-
return $wrapper;
|
813 |
-
}
|
814 |
-
|
815 |
-
/**
|
816 |
-
* Wraps galleries for grouping
|
817 |
-
* @uses `the_content` Filter hook
|
818 |
-
* @uses gallery_wrap_callback to Wrap shortcodes for grouping
|
819 |
-
* @param string $content Post content
|
820 |
-
* @return string Modified post content
|
821 |
-
*/
|
822 |
-
function gallery_wrap($content) {
|
823 |
-
if ( !$this->is_enabled() )
|
824 |
-
return $content;
|
825 |
-
//Stop processing if option not enabled
|
826 |
-
if ( !$this->options->get_bool('group_gallery') )
|
827 |
-
return $content;
|
828 |
-
global $shortcode_tags;
|
829 |
-
//Save default shortcode handlers to temp variable
|
830 |
-
$sc_temp = $shortcode_tags;
|
831 |
-
//Find gallery shortcodes
|
832 |
-
$shortcodes = array('gallery', 'nggallery');
|
833 |
-
$m = $this->m('gallery_wrap_callback');
|
834 |
-
$shortcode_tags = array();
|
835 |
-
foreach ( $shortcodes as $tag ) {
|
836 |
-
$shortcode_tags[$tag] = $m;
|
837 |
-
}
|
838 |
-
//Wrap gallery shortcodes
|
839 |
-
$content = do_shortcode($content);
|
840 |
-
//Restore default shortcode handlers
|
841 |
-
$shortcode_tags = $sc_temp;
|
842 |
-
|
843 |
-
return $content;
|
844 |
-
}
|
845 |
-
|
846 |
-
/**
|
847 |
-
* Wraps gallery shortcodes for later processing
|
848 |
-
* @param array $attr Shortcode attributes
|
849 |
-
* @param string $content Content enclosed in shortcode
|
850 |
-
* @param string $tag Shortcode name
|
851 |
-
* @return string Wrapped gallery shortcode
|
852 |
-
*/
|
853 |
-
function gallery_wrap_callback($attr, $content = null, $tag) {
|
854 |
-
//Rebuild shortcode
|
855 |
-
$sc = '[' . $tag . ' ' . $this->util->build_attribute_string($attr) . ']';
|
856 |
-
if ( !empty($content) )
|
857 |
-
$sc .= $content . '[/' . $tag .']';
|
858 |
-
//Wrap shortcode
|
859 |
-
$w = $this->group_get_wrapper();
|
860 |
-
$sc = $w->open . $sc . $w->close;
|
861 |
-
return $sc;
|
862 |
-
}
|
863 |
-
|
864 |
-
/**
|
865 |
-
* Removes wrapping from galleries
|
866 |
-
* @uses `the_content` filter hook
|
867 |
-
* @param $content Post content
|
868 |
-
* @return string Modified post content
|
869 |
-
*/
|
870 |
-
function gallery_unwrap($content) {
|
871 |
-
if ( !$this->is_enabled() )
|
872 |
-
return $content;
|
873 |
-
//Stop processing if option not enabled
|
874 |
-
if ( !$this->options->get_bool('group_gallery') )
|
875 |
-
return $content;
|
876 |
-
$w = $this->group_get_wrapper();
|
877 |
-
if ( strpos($content, $w->open) !== false ) {
|
878 |
-
$content = str_replace($w->open, '', $content);
|
879 |
-
$content = str_replace($w->close, '', $content);
|
880 |
-
}
|
881 |
-
return $content;
|
882 |
-
}
|
883 |
-
|
884 |
-
/*-** Widgets **-*/
|
885 |
-
|
886 |
-
/**
|
887 |
-
* Reroute widget display handlers to internal method
|
888 |
-
* @param array $sidebar_widgets List of sidebars & their widgets
|
889 |
-
* @uses WP Hook `sidebars_widgets` to intercept widget list
|
890 |
-
* @global $wp_registered_widgets to reroute display callback
|
891 |
-
* @return array Sidebars and widgets (unmodified)
|
892 |
-
*/
|
893 |
-
function sidebars_widgets($sidebars_widgets) {
|
894 |
-
global $wp_registered_widgets;
|
895 |
-
static $widgets_processed = false;
|
896 |
-
if ( is_admin() || empty($wp_registered_widgets) || $widgets_processed || !is_object($this->options) || !$this->is_enabled() || !$this->options->get_bool('enabled_widget') )
|
897 |
-
return $sidebars_widgets;
|
898 |
-
$widgets_processed = true;
|
899 |
-
//Fetch active widgets from all sidebars
|
900 |
-
foreach ( $sidebars_widgets as $sb => $ws ) {
|
901 |
-
//Skip inactive widgets and empty sidebars
|
902 |
-
if ( 'wp_inactive_widgets' == $sb || empty($ws) || !is_array($ws) )
|
903 |
-
continue;
|
904 |
-
foreach ( $ws as $w ) {
|
905 |
-
if ( isset($wp_registered_widgets[$w]) && isset($wp_registered_widgets[$w][$this->widget_callback]) ) {
|
906 |
-
$wref =& $wp_registered_widgets[$w];
|
907 |
-
//Backup original callback
|
908 |
-
$wref[$this->widget_callback_orig] = $wref[$this->widget_callback];
|
909 |
-
//Reroute callback
|
910 |
-
$wref[$this->widget_callback] = $this->m('widget_callback');
|
911 |
-
unset($wref);
|
912 |
-
}
|
913 |
-
}
|
914 |
-
}
|
915 |
-
|
916 |
-
return $sidebars_widgets;
|
917 |
-
}
|
918 |
-
|
919 |
-
/**
|
920 |
-
* Widget display handler
|
921 |
-
* Original widget display handler is called inside of an output buffer & links in output are processed before sending to browser
|
922 |
-
* @param array $args Widget instance properties
|
923 |
-
* @param int (optional) $widget_args Additional widget args (usually the widget's instance number)
|
924 |
-
* @see WP_Widget::display_callback() for more information
|
925 |
-
* @see sidebars_widgets() for callback modification
|
926 |
-
* @global $wp_registered_widgets
|
927 |
-
* @uses widget_process_links() to Process links in widget content
|
928 |
-
* @return void
|
929 |
-
*/
|
930 |
-
function widget_callback($args, $widget_args = 1) {
|
931 |
-
global $wp_registered_widgets;
|
932 |
-
$wid = ( isset($args['widget_id']) ) ? $args['widget_id'] : false;
|
933 |
-
//Stop processing if widget data invalid
|
934 |
-
if ( !$wid || !isset($wp_registered_widgets[$wid]) || !($w =& $wp_registered_widgets[$wid]) || !isset($w['id']) || $wid != $w['id'] )
|
935 |
-
return false;
|
936 |
-
//Get original callback
|
937 |
-
if ( !isset($w[$this->widget_callback_orig]) || !($cb = $w[$this->widget_callback_orig]) || !is_callable($cb) )
|
938 |
-
return false;
|
939 |
-
$params = func_get_args();
|
940 |
-
$this->widget_processing = true;
|
941 |
-
//Start output buffer
|
942 |
-
ob_start();
|
943 |
-
//Call original callback
|
944 |
-
call_user_func_array($cb, $params);
|
945 |
-
//Flush output buffer
|
946 |
-
echo $this->widget_process_links(ob_get_clean(), $wid);
|
947 |
-
$this->widget_processing = false;
|
948 |
-
}
|
949 |
-
|
950 |
-
/**
|
951 |
-
* Process links in widget content
|
952 |
-
* @param string $content Widget content
|
953 |
-
* @return string Processed widget content
|
954 |
-
* @uses process_links() to process links
|
955 |
-
*/
|
956 |
-
function widget_process_links($content, $id) {
|
957 |
-
$id = ( $this->options->get_bool('group_widget') ) ? "widget_$id" : null;
|
958 |
-
return $this->process_links($content, $id);
|
959 |
-
}
|
960 |
-
|
961 |
-
/*-** Helpers **-*/
|
962 |
-
|
963 |
-
/**
|
964 |
-
* Build attribute name
|
965 |
-
* Makes sure name is only prefixed once
|
966 |
-
* @param string $name (optional) Attribute base name
|
967 |
-
* @return string Formatted attribute name
|
968 |
-
*/
|
969 |
-
function make_attribute_name($name = '') {
|
970 |
-
//Validate
|
971 |
-
if ( !is_string($name) ) {
|
972 |
-
$name = '';
|
973 |
-
} else {
|
974 |
-
$name = trim($name);
|
975 |
-
}
|
976 |
-
//Setup
|
977 |
-
$sep = '-';
|
978 |
-
$top = 'data';
|
979 |
-
//Generate valid name
|
980 |
-
if ( strpos($name, $top . $sep . $this->get_prefix()) !== 0 ) {
|
981 |
-
$name = $top . $sep . $this->add_prefix($name, $sep);
|
982 |
-
}
|
983 |
-
return $name;
|
984 |
-
}
|
985 |
-
|
986 |
-
/**
|
987 |
-
* Set attribute to array
|
988 |
-
* Attribute is added to array if it does not exist
|
989 |
-
* @param array $attrs Array to add attribute to (Passed by reference)
|
990 |
-
* @param string $name Name of attribute to add
|
991 |
-
* @param string (optional) $value Attribute value
|
992 |
-
* @return array Updated attribute array
|
993 |
-
*/
|
994 |
-
function set_attribute(&$attrs, $name, $value = true) {
|
995 |
-
//Validate
|
996 |
-
$attrs = $this->get_attributes($attrs, false);
|
997 |
-
if ( !is_string($name) || empty($name) ) {
|
998 |
-
return $attrs;
|
999 |
-
}
|
1000 |
-
if ( !is_scalar($value) ) {
|
1001 |
-
$value = true;
|
1002 |
-
}
|
1003 |
-
//Add attribute
|
1004 |
-
$attrs = array_merge($attrs, array( $this->make_attribute_name($name) => strval($value) ));
|
1005 |
-
|
1006 |
-
return $attrs;
|
1007 |
-
}
|
1008 |
-
|
1009 |
-
/**
|
1010 |
-
* Convert attribute string into array
|
1011 |
-
* @param string $attr_string Attribute string
|
1012 |
-
* @param bool (optional) $internal Whether only internal attributes should be evaluated (Default: TRUE)
|
1013 |
-
* @return array Attributes as associative array
|
1014 |
-
*/
|
1015 |
-
function get_attributes($attr_string, $internal = true) {
|
1016 |
-
if ( is_string($attr_string) ) {
|
1017 |
-
$attr_string = $this->util->parse_attribute_string($attr_string);
|
1018 |
-
}
|
1019 |
-
$ret = ( is_array($attr_string) ) ? $attr_string : array();
|
1020 |
-
//Filter out external attributes
|
1021 |
-
if ( !empty($ret) && is_bool($internal) && $internal ) {
|
1022 |
-
$ret_f = array();
|
1023 |
-
foreach ( $ret as $key => $val ) {
|
1024 |
-
if ( strpos($key, $this->make_attribute_name()) == 0 ) {
|
1025 |
-
$ret_f[$key] = $val;
|
1026 |
-
}
|
1027 |
-
}
|
1028 |
-
if ( !empty($ret_f) ) {
|
1029 |
-
$ret = $ret_f;
|
1030 |
-
}
|
1031 |
-
}
|
1032 |
-
|
1033 |
-
return $ret;
|
1034 |
-
}
|
1035 |
-
|
1036 |
-
/**
|
1037 |
-
* Retrieve attribute value
|
1038 |
-
* @param string|array $attrs Attributes to retrieve attribute value from
|
1039 |
-
* @param string $attr Attribute name to retrieve
|
1040 |
-
* @param bool (optional) $internal Whether only internal attributes should be evaluated (Default: TRUE)
|
1041 |
-
* @return string|bool Attribute value (Default: FALSE)
|
1042 |
-
*/
|
1043 |
-
function get_attribute($attrs, $attr, $internal = true) {
|
1044 |
-
$ret = false;
|
1045 |
-
//Validate
|
1046 |
-
$attrs = $this->get_attributes($attrs, $internal);
|
1047 |
-
if ( $internal ) {
|
1048 |
-
$attr = $this->make_attribute_name($attr);
|
1049 |
-
}
|
1050 |
-
if ( isset($attrs[$attr]) ) {
|
1051 |
-
$ret = $attrs[$attr];
|
1052 |
-
}
|
1053 |
-
return $ret;
|
1054 |
-
}
|
1055 |
-
|
1056 |
-
/**
|
1057 |
-
* Checks if attribute exists
|
1058 |
-
* If supplied, the attribute's value is also validated
|
1059 |
-
* @param string|array $attrs Attributes to retrieve attribute value from
|
1060 |
-
* @param string $attr Attribute name to retrieve
|
1061 |
-
* @param mixed $value (optional) Attribute value to check for
|
1062 |
-
* @param bool $internal (optional) Whether to check only internal attributes (Default: TRUE)
|
1063 |
-
* @see get_attribute()
|
1064 |
-
* @return bool Whether or not attribute (with matching value if specified) exists
|
1065 |
-
*/
|
1066 |
-
function has_attribute($attrs, $attr, $value = null, $internal = true) {
|
1067 |
-
$a = $this->get_attribute($attrs, $attr, $internal);
|
1068 |
-
$ret = false;
|
1069 |
-
if ( $a !== false ) {
|
1070 |
-
$ret = true;
|
1071 |
-
//Check value
|
1072 |
-
if ( null != $value && is_scalar($value) ) {
|
1073 |
-
$ret = ( $a == strval($value) ) ? true : false;
|
1074 |
-
}
|
1075 |
-
}
|
1076 |
-
return $ret;
|
1077 |
-
}
|
1078 |
-
|
1079 |
-
/**
|
1080 |
-
* Build JS object of UI strings when initializing lightbox
|
1081 |
-
* @return array UI strings
|
1082 |
-
*/
|
1083 |
-
function build_labels() {
|
1084 |
-
$ret = array();
|
1085 |
-
//Get all UI options
|
1086 |
-
$prefix = 'txt_';
|
1087 |
-
$opt_strings = array_filter(array_keys($this->options->get_items()), create_function('$opt', 'return ( strpos($opt, "' . $prefix . '") === 0 );'));
|
1088 |
-
if ( count($opt_strings) ) {
|
1089 |
-
//Build array of UI options
|
1090 |
-
foreach ( $opt_strings as $key ) {
|
1091 |
-
$name = substr($key, strlen($prefix));
|
1092 |
-
$ret[$name] = $this->options->get_value($key);
|
1093 |
-
}
|
1094 |
-
}
|
1095 |
-
return $ret;
|
1096 |
-
}
|
1097 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
package-lock.json
ADDED
@@ -0,0 +1,2941 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "simple-lightbox",
|
3 |
+
"version": "2.7.1",
|
4 |
+
"lockfileVersion": 1,
|
5 |
+
"requires": true,
|
6 |
+
"dependencies": {
|
7 |
+
"abbrev": {
|
8 |
+
"version": "1.1.1",
|
9 |
+
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
10 |
+
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
11 |
+
"dev": true
|
12 |
+
},
|
13 |
+
"amdefine": {
|
14 |
+
"version": "1.0.1",
|
15 |
+
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
|
16 |
+
"integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
|
17 |
+
"dev": true
|
18 |
+
},
|
19 |
+
"ansi-regex": {
|
20 |
+
"version": "2.1.1",
|
21 |
+
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
22 |
+
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
23 |
+
"dev": true
|
24 |
+
},
|
25 |
+
"ansi-styles": {
|
26 |
+
"version": "2.2.1",
|
27 |
+
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
28 |
+
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
|
29 |
+
"dev": true
|
30 |
+
},
|
31 |
+
"aproba": {
|
32 |
+
"version": "1.2.0",
|
33 |
+
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
|
34 |
+
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
|
35 |
+
"dev": true
|
36 |
+
},
|
37 |
+
"are-we-there-yet": {
|
38 |
+
"version": "1.1.4",
|
39 |
+
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz",
|
40 |
+
"integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
|
41 |
+
"dev": true,
|
42 |
+
"requires": {
|
43 |
+
"delegates": "1.0.0",
|
44 |
+
"readable-stream": "2.3.6"
|
45 |
+
},
|
46 |
+
"dependencies": {
|
47 |
+
"isarray": {
|
48 |
+
"version": "1.0.0",
|
49 |
+
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
50 |
+
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
51 |
+
"dev": true
|
52 |
+
},
|
53 |
+
"readable-stream": {
|
54 |
+
"version": "2.3.6",
|
55 |
+
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
56 |
+
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
57 |
+
"dev": true,
|
58 |
+
"requires": {
|
59 |
+
"core-util-is": "1.0.2",
|
60 |
+
"inherits": "2.0.3",
|
61 |
+
"isarray": "1.0.0",
|
62 |
+
"process-nextick-args": "2.0.0",
|
63 |
+
"safe-buffer": "5.1.2",
|
64 |
+
"string_decoder": "1.1.1",
|
65 |
+
"util-deprecate": "1.0.2"
|
66 |
+
}
|
67 |
+
},
|
68 |
+
"string_decoder": {
|
69 |
+
"version": "1.1.1",
|
70 |
+
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
71 |
+
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
72 |
+
"dev": true,
|
73 |
+
"requires": {
|
74 |
+
"safe-buffer": "5.1.2"
|
75 |
+
}
|
76 |
+
}
|
77 |
+
}
|
78 |
+
},
|
79 |
+
"argparse": {
|
80 |
+
"version": "1.0.10",
|
81 |
+
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
82 |
+
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
83 |
+
"dev": true,
|
84 |
+
"requires": {
|
85 |
+
"sprintf-js": "1.0.3"
|
86 |
+
}
|
87 |
+
},
|
88 |
+
"array-differ": {
|
89 |
+
"version": "1.0.0",
|
90 |
+
"resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz",
|
91 |
+
"integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=",
|
92 |
+
"dev": true
|
93 |
+
},
|
94 |
+
"array-find-index": {
|
95 |
+
"version": "1.0.2",
|
96 |
+
"resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
|
97 |
+
"integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
|
98 |
+
"dev": true
|
99 |
+
},
|
100 |
+
"array-union": {
|
101 |
+
"version": "1.0.2",
|
102 |
+
"resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
|
103 |
+
"integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
|
104 |
+
"dev": true,
|
105 |
+
"requires": {
|
106 |
+
"array-uniq": "1.0.3"
|
107 |
+
}
|
108 |
+
},
|
109 |
+
"array-uniq": {
|
110 |
+
"version": "1.0.3",
|
111 |
+
"resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
|
112 |
+
"integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
|
113 |
+
"dev": true
|
114 |
+
},
|
115 |
+
"arrify": {
|
116 |
+
"version": "1.0.1",
|
117 |
+
"resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
|
118 |
+
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
|
119 |
+
"dev": true
|
120 |
+
},
|
121 |
+
"asn1": {
|
122 |
+
"version": "0.2.3",
|
123 |
+
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
|
124 |
+
"integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
|
125 |
+
"dev": true
|
126 |
+
},
|
127 |
+
"assert-plus": {
|
128 |
+
"version": "0.2.0",
|
129 |
+
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
|
130 |
+
"integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
|
131 |
+
"dev": true
|
132 |
+
},
|
133 |
+
"async": {
|
134 |
+
"version": "1.5.2",
|
135 |
+
"resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
|
136 |
+
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
|
137 |
+
"dev": true
|
138 |
+
},
|
139 |
+
"async-foreach": {
|
140 |
+
"version": "0.1.3",
|
141 |
+
"resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
|
142 |
+
"integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=",
|
143 |
+
"dev": true
|
144 |
+
},
|
145 |
+
"asynckit": {
|
146 |
+
"version": "0.4.0",
|
147 |
+
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
148 |
+
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
|
149 |
+
"dev": true
|
150 |
+
},
|
151 |
+
"aws-sign2": {
|
152 |
+
"version": "0.6.0",
|
153 |
+
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
|
154 |
+
"integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
|
155 |
+
"dev": true
|
156 |
+
},
|
157 |
+
"aws4": {
|
158 |
+
"version": "1.7.0",
|
159 |
+
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz",
|
160 |
+
"integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==",
|
161 |
+
"dev": true
|
162 |
+
},
|
163 |
+
"balanced-match": {
|
164 |
+
"version": "1.0.0",
|
165 |
+
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
166 |
+
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
167 |
+
"dev": true
|
168 |
+
},
|
169 |
+
"bcrypt-pbkdf": {
|
170 |
+
"version": "1.0.1",
|
171 |
+
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
|
172 |
+
"integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
|
173 |
+
"dev": true,
|
174 |
+
"optional": true,
|
175 |
+
"requires": {
|
176 |
+
"tweetnacl": "0.14.5"
|
177 |
+
}
|
178 |
+
},
|
179 |
+
"beeper": {
|
180 |
+
"version": "1.1.1",
|
181 |
+
"resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz",
|
182 |
+
"integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=",
|
183 |
+
"dev": true
|
184 |
+
},
|
185 |
+
"block-stream": {
|
186 |
+
"version": "0.0.9",
|
187 |
+
"resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
|
188 |
+
"integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
|
189 |
+
"dev": true,
|
190 |
+
"requires": {
|
191 |
+
"inherits": "2.0.3"
|
192 |
+
}
|
193 |
+
},
|
194 |
+
"body-parser": {
|
195 |
+
"version": "1.14.2",
|
196 |
+
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.14.2.tgz",
|
197 |
+
"integrity": "sha1-EBXLH+LEQ4WCWVgdtTMy+NDPUPk=",
|
198 |
+
"dev": true,
|
199 |
+
"requires": {
|
200 |
+
"bytes": "2.2.0",
|
201 |
+
"content-type": "1.0.4",
|
202 |
+
"debug": "2.2.0",
|
203 |
+
"depd": "1.1.2",
|
204 |
+
"http-errors": "1.3.1",
|
205 |
+
"iconv-lite": "0.4.13",
|
206 |
+
"on-finished": "2.3.0",
|
207 |
+
"qs": "5.2.0",
|
208 |
+
"raw-body": "2.1.7",
|
209 |
+
"type-is": "1.6.16"
|
210 |
+
},
|
211 |
+
"dependencies": {
|
212 |
+
"iconv-lite": {
|
213 |
+
"version": "0.4.13",
|
214 |
+
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz",
|
215 |
+
"integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=",
|
216 |
+
"dev": true
|
217 |
+
},
|
218 |
+
"qs": {
|
219 |
+
"version": "5.2.0",
|
220 |
+
"resolved": "https://registry.npmjs.org/qs/-/qs-5.2.0.tgz",
|
221 |
+
"integrity": "sha1-qfMRQq9GjLcrJbMBNrokVoNJFr4=",
|
222 |
+
"dev": true
|
223 |
+
}
|
224 |
+
}
|
225 |
+
},
|
226 |
+
"boom": {
|
227 |
+
"version": "2.10.1",
|
228 |
+
"resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
|
229 |
+
"integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
|
230 |
+
"dev": true,
|
231 |
+
"requires": {
|
232 |
+
"hoek": "2.16.3"
|
233 |
+
}
|
234 |
+
},
|
235 |
+
"brace-expansion": {
|
236 |
+
"version": "1.1.11",
|
237 |
+
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
238 |
+
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
239 |
+
"dev": true,
|
240 |
+
"requires": {
|
241 |
+
"balanced-match": "1.0.0",
|
242 |
+
"concat-map": "0.0.1"
|
243 |
+
}
|
244 |
+
},
|
245 |
+
"browserify-zlib": {
|
246 |
+
"version": "0.1.4",
|
247 |
+
"resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz",
|
248 |
+
"integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=",
|
249 |
+
"dev": true,
|
250 |
+
"requires": {
|
251 |
+
"pako": "0.2.9"
|
252 |
+
}
|
253 |
+
},
|
254 |
+
"buffer-from": {
|
255 |
+
"version": "1.0.0",
|
256 |
+
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz",
|
257 |
+
"integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==",
|
258 |
+
"dev": true
|
259 |
+
},
|
260 |
+
"builtin-modules": {
|
261 |
+
"version": "1.1.1",
|
262 |
+
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
|
263 |
+
"integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
|
264 |
+
"dev": true
|
265 |
+
},
|
266 |
+
"bytes": {
|
267 |
+
"version": "2.2.0",
|
268 |
+
"resolved": "https://registry.npmjs.org/bytes/-/bytes-2.2.0.tgz",
|
269 |
+
"integrity": "sha1-/TVGSkA/b5EXwt42Cez/nK4ABYg=",
|
270 |
+
"dev": true
|
271 |
+
},
|
272 |
+
"cache-swap": {
|
273 |
+
"version": "0.3.0",
|
274 |
+
"resolved": "https://registry.npmjs.org/cache-swap/-/cache-swap-0.3.0.tgz",
|
275 |
+
"integrity": "sha1-HFQaoQilAQb2ML3Zj+HeyLoTP1E=",
|
276 |
+
"dev": true,
|
277 |
+
"requires": {
|
278 |
+
"graceful-fs": "4.1.11",
|
279 |
+
"mkdirp": "0.5.1",
|
280 |
+
"object-assign": "4.1.1",
|
281 |
+
"rimraf": "2.6.2"
|
282 |
+
},
|
283 |
+
"dependencies": {
|
284 |
+
"rimraf": {
|
285 |
+
"version": "2.6.2",
|
286 |
+
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
|
287 |
+
"integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
|
288 |
+
"dev": true,
|
289 |
+
"requires": {
|
290 |
+
"glob": "7.0.6"
|
291 |
+
}
|
292 |
+
}
|
293 |
+
}
|
294 |
+
},
|
295 |
+
"camelcase": {
|
296 |
+
"version": "2.1.1",
|
297 |
+
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
|
298 |
+
"integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
|
299 |
+
"dev": true
|
300 |
+
},
|
301 |
+
"camelcase-keys": {
|
302 |
+
"version": "2.1.0",
|
303 |
+
"resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
|
304 |
+
"integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
|
305 |
+
"dev": true,
|
306 |
+
"requires": {
|
307 |
+
"camelcase": "2.1.1",
|
308 |
+
"map-obj": "1.0.1"
|
309 |
+
}
|
310 |
+
},
|
311 |
+
"caseless": {
|
312 |
+
"version": "0.11.0",
|
313 |
+
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
|
314 |
+
"integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=",
|
315 |
+
"dev": true
|
316 |
+
},
|
317 |
+
"chalk": {
|
318 |
+
"version": "1.1.3",
|
319 |
+
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
320 |
+
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
321 |
+
"dev": true,
|
322 |
+
"requires": {
|
323 |
+
"ansi-styles": "2.2.1",
|
324 |
+
"escape-string-regexp": "1.0.5",
|
325 |
+
"has-ansi": "2.0.0",
|
326 |
+
"strip-ansi": "3.0.1",
|
327 |
+
"supports-color": "2.0.0"
|
328 |
+
}
|
329 |
+
},
|
330 |
+
"cli": {
|
331 |
+
"version": "1.0.1",
|
332 |
+
"resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz",
|
333 |
+
"integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=",
|
334 |
+
"dev": true,
|
335 |
+
"requires": {
|
336 |
+
"exit": "0.1.2",
|
337 |
+
"glob": "7.1.2"
|
338 |
+
},
|
339 |
+
"dependencies": {
|
340 |
+
"glob": {
|
341 |
+
"version": "7.1.2",
|
342 |
+
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
|
343 |
+
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
344 |
+
"dev": true,
|
345 |
+
"requires": {
|
346 |
+
"fs.realpath": "1.0.0",
|
347 |
+
"inflight": "1.0.6",
|
348 |
+
"inherits": "2.0.3",
|
349 |
+
"minimatch": "3.0.4",
|
350 |
+
"once": "1.4.0",
|
351 |
+
"path-is-absolute": "1.0.1"
|
352 |
+
}
|
353 |
+
}
|
354 |
+
}
|
355 |
+
},
|
356 |
+
"cliui": {
|
357 |
+
"version": "3.2.0",
|
358 |
+
"resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
|
359 |
+
"integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
|
360 |
+
"dev": true,
|
361 |
+
"requires": {
|
362 |
+
"string-width": "1.0.2",
|
363 |
+
"strip-ansi": "3.0.1",
|
364 |
+
"wrap-ansi": "2.1.0"
|
365 |
+
}
|
366 |
+
},
|
367 |
+
"code-point-at": {
|
368 |
+
"version": "1.1.0",
|
369 |
+
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
370 |
+
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
|
371 |
+
"dev": true
|
372 |
+
},
|
373 |
+
"coffeescript": {
|
374 |
+
"version": "1.10.0",
|
375 |
+
"resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.10.0.tgz",
|
376 |
+
"integrity": "sha1-56qDAZF+9iGzXYo580jc3R234z4=",
|
377 |
+
"dev": true
|
378 |
+
},
|
379 |
+
"colors": {
|
380 |
+
"version": "1.1.2",
|
381 |
+
"resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
|
382 |
+
"integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
|
383 |
+
"dev": true
|
384 |
+
},
|
385 |
+
"combined-stream": {
|
386 |
+
"version": "1.0.6",
|
387 |
+
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
|
388 |
+
"integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
|
389 |
+
"dev": true,
|
390 |
+
"requires": {
|
391 |
+
"delayed-stream": "1.0.0"
|
392 |
+
}
|
393 |
+
},
|
394 |
+
"commander": {
|
395 |
+
"version": "2.15.1",
|
396 |
+
"resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
|
397 |
+
"integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
|
398 |
+
"dev": true
|
399 |
+
},
|
400 |
+
"concat-map": {
|
401 |
+
"version": "0.0.1",
|
402 |
+
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
403 |
+
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
404 |
+
"dev": true
|
405 |
+
},
|
406 |
+
"concat-stream": {
|
407 |
+
"version": "1.6.2",
|
408 |
+
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
|
409 |
+
"integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
|
410 |
+
"dev": true,
|
411 |
+
"requires": {
|
412 |
+
"buffer-from": "1.0.0",
|
413 |
+
"inherits": "2.0.3",
|
414 |
+
"readable-stream": "2.3.6",
|
415 |
+
"typedarray": "0.0.6"
|
416 |
+
},
|
417 |
+
"dependencies": {
|
418 |
+
"isarray": {
|
419 |
+
"version": "1.0.0",
|
420 |
+
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
421 |
+
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
422 |
+
"dev": true
|
423 |
+
},
|
424 |
+
"readable-stream": {
|
425 |
+
"version": "2.3.6",
|
426 |
+
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
427 |
+
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
428 |
+
"dev": true,
|
429 |
+
"requires": {
|
430 |
+
"core-util-is": "1.0.2",
|
431 |
+
"inherits": "2.0.3",
|
432 |
+
"isarray": "1.0.0",
|
433 |
+
"process-nextick-args": "2.0.0",
|
434 |
+
"safe-buffer": "5.1.2",
|
435 |
+
"string_decoder": "1.1.1",
|
436 |
+
"util-deprecate": "1.0.2"
|
437 |
+
}
|
438 |
+
},
|
439 |
+
"string_decoder": {
|
440 |
+
"version": "1.1.1",
|
441 |
+
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
442 |
+
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
443 |
+
"dev": true,
|
444 |
+
"requires": {
|
445 |
+
"safe-buffer": "5.1.2"
|
446 |
+
}
|
447 |
+
}
|
448 |
+
}
|
449 |
+
},
|
450 |
+
"console-browserify": {
|
451 |
+
"version": "1.1.0",
|
452 |
+
"resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
|
453 |
+
"integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
|
454 |
+
"dev": true,
|
455 |
+
"requires": {
|
456 |
+
"date-now": "0.1.4"
|
457 |
+
}
|
458 |
+
},
|
459 |
+
"console-control-strings": {
|
460 |
+
"version": "1.1.0",
|
461 |
+
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
462 |
+
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
|
463 |
+
"dev": true
|
464 |
+
},
|
465 |
+
"content-type": {
|
466 |
+
"version": "1.0.4",
|
467 |
+
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
|
468 |
+
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
|
469 |
+
"dev": true
|
470 |
+
},
|
471 |
+
"core-util-is": {
|
472 |
+
"version": "1.0.2",
|
473 |
+
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
474 |
+
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
475 |
+
"dev": true
|
476 |
+
},
|
477 |
+
"cross-spawn": {
|
478 |
+
"version": "3.0.1",
|
479 |
+
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
|
480 |
+
"integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
|
481 |
+
"dev": true,
|
482 |
+
"requires": {
|
483 |
+
"lru-cache": "4.1.2",
|
484 |
+
"which": "1.2.14"
|
485 |
+
},
|
486 |
+
"dependencies": {
|
487 |
+
"lru-cache": {
|
488 |
+
"version": "4.1.2",
|
489 |
+
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.2.tgz",
|
490 |
+
"integrity": "sha512-wgeVXhrDwAWnIF/yZARsFnMBtdFXOg1b8RIrhilp+0iDYN4mdQcNZElDZ0e4B64BhaxeQ5zN7PMyvu7we1kPeQ==",
|
491 |
+
"dev": true,
|
492 |
+
"requires": {
|
493 |
+
"pseudomap": "1.0.2",
|
494 |
+
"yallist": "2.1.2"
|
495 |
+
}
|
496 |
+
}
|
497 |
+
}
|
498 |
+
},
|
499 |
+
"cryptiles": {
|
500 |
+
"version": "2.0.5",
|
501 |
+
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
|
502 |
+
"integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
|
503 |
+
"dev": true,
|
504 |
+
"requires": {
|
505 |
+
"boom": "2.10.1"
|
506 |
+
}
|
507 |
+
},
|
508 |
+
"currently-unhandled": {
|
509 |
+
"version": "0.4.1",
|
510 |
+
"resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
|
511 |
+
"integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
|
512 |
+
"dev": true,
|
513 |
+
"requires": {
|
514 |
+
"array-find-index": "1.0.2"
|
515 |
+
}
|
516 |
+
},
|
517 |
+
"dashdash": {
|
518 |
+
"version": "1.14.1",
|
519 |
+
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
|
520 |
+
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
|
521 |
+
"dev": true,
|
522 |
+
"requires": {
|
523 |
+
"assert-plus": "1.0.0"
|
524 |
+
},
|
525 |
+
"dependencies": {
|
526 |
+
"assert-plus": {
|
527 |
+
"version": "1.0.0",
|
528 |
+
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
529 |
+
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
530 |
+
"dev": true
|
531 |
+
}
|
532 |
+
}
|
533 |
+
},
|
534 |
+
"date-now": {
|
535 |
+
"version": "0.1.4",
|
536 |
+
"resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
|
537 |
+
"integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=",
|
538 |
+
"dev": true
|
539 |
+
},
|
540 |
+
"date-time": {
|
541 |
+
"version": "1.1.0",
|
542 |
+
"resolved": "https://registry.npmjs.org/date-time/-/date-time-1.1.0.tgz",
|
543 |
+
"integrity": "sha1-GIdtC9pMGf5w3Tv0sDTygbEqQLY=",
|
544 |
+
"dev": true,
|
545 |
+
"requires": {
|
546 |
+
"time-zone": "0.1.0"
|
547 |
+
}
|
548 |
+
},
|
549 |
+
"dateformat": {
|
550 |
+
"version": "1.0.12",
|
551 |
+
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz",
|
552 |
+
"integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=",
|
553 |
+
"dev": true,
|
554 |
+
"requires": {
|
555 |
+
"get-stdin": "4.0.1",
|
556 |
+
"meow": "3.7.0"
|
557 |
+
}
|
558 |
+
},
|
559 |
+
"debug": {
|
560 |
+
"version": "2.2.0",
|
561 |
+
"resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
|
562 |
+
"integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
|
563 |
+
"dev": true,
|
564 |
+
"requires": {
|
565 |
+
"ms": "0.7.1"
|
566 |
+
}
|
567 |
+
},
|
568 |
+
"decamelize": {
|
569 |
+
"version": "1.2.0",
|
570 |
+
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
571 |
+
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
|
572 |
+
"dev": true
|
573 |
+
},
|
574 |
+
"delayed-stream": {
|
575 |
+
"version": "1.0.0",
|
576 |
+
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
577 |
+
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
|
578 |
+
"dev": true
|
579 |
+
},
|
580 |
+
"delegates": {
|
581 |
+
"version": "1.0.0",
|
582 |
+
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
583 |
+
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
|
584 |
+
"dev": true
|
585 |
+
},
|
586 |
+
"depd": {
|
587 |
+
"version": "1.1.2",
|
588 |
+
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
589 |
+
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
|
590 |
+
"dev": true
|
591 |
+
},
|
592 |
+
"dom-serializer": {
|
593 |
+
"version": "0.1.0",
|
594 |
+
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
|
595 |
+
"integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=",
|
596 |
+
"dev": true,
|
597 |
+
"requires": {
|
598 |
+
"domelementtype": "1.1.3",
|
599 |
+
"entities": "1.1.1"
|
600 |
+
},
|
601 |
+
"dependencies": {
|
602 |
+
"domelementtype": {
|
603 |
+
"version": "1.1.3",
|
604 |
+
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
|
605 |
+
"integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=",
|
606 |
+
"dev": true
|
607 |
+
},
|
608 |
+
"entities": {
|
609 |
+
"version": "1.1.1",
|
610 |
+
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz",
|
611 |
+
"integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=",
|
612 |
+
"dev": true
|
613 |
+
}
|
614 |
+
}
|
615 |
+
},
|
616 |
+
"domelementtype": {
|
617 |
+
"version": "1.3.0",
|
618 |
+
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
|
619 |
+
"integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=",
|
620 |
+
"dev": true
|
621 |
+
},
|
622 |
+
"domhandler": {
|
623 |
+
"version": "2.3.0",
|
624 |
+
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz",
|
625 |
+
"integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=",
|
626 |
+
"dev": true,
|
627 |
+
"requires": {
|
628 |
+
"domelementtype": "1.3.0"
|
629 |
+
}
|
630 |
+
},
|
631 |
+
"domutils": {
|
632 |
+
"version": "1.5.1",
|
633 |
+
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
|
634 |
+
"integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
|
635 |
+
"dev": true,
|
636 |
+
"requires": {
|
637 |
+
"dom-serializer": "0.1.0",
|
638 |
+
"domelementtype": "1.3.0"
|
639 |
+
}
|
640 |
+
},
|
641 |
+
"each-async": {
|
642 |
+
"version": "1.1.1",
|
643 |
+
"resolved": "https://registry.npmjs.org/each-async/-/each-async-1.1.1.tgz",
|
644 |
+
"integrity": "sha1-3uUim98KtrogEqOV4bhpq/iBNHM=",
|
645 |
+
"dev": true,
|
646 |
+
"requires": {
|
647 |
+
"onetime": "1.1.0",
|
648 |
+
"set-immediate-shim": "1.0.1"
|
649 |
+
}
|
650 |
+
},
|
651 |
+
"ecc-jsbn": {
|
652 |
+
"version": "0.1.1",
|
653 |
+
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
|
654 |
+
"integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
|
655 |
+
"dev": true,
|
656 |
+
"optional": true,
|
657 |
+
"requires": {
|
658 |
+
"jsbn": "0.1.1"
|
659 |
+
}
|
660 |
+
},
|
661 |
+
"ee-first": {
|
662 |
+
"version": "1.1.1",
|
663 |
+
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
664 |
+
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
|
665 |
+
"dev": true
|
666 |
+
},
|
667 |
+
"entities": {
|
668 |
+
"version": "1.0.0",
|
669 |
+
"resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz",
|
670 |
+
"integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=",
|
671 |
+
"dev": true
|
672 |
+
},
|
673 |
+
"error-ex": {
|
674 |
+
"version": "1.3.1",
|
675 |
+
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
|
676 |
+
"integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
|
677 |
+
"dev": true,
|
678 |
+
"requires": {
|
679 |
+
"is-arrayish": "0.2.1"
|
680 |
+
}
|
681 |
+
},
|
682 |
+
"escape-string-regexp": {
|
683 |
+
"version": "1.0.5",
|
684 |
+
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
685 |
+
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
|
686 |
+
"dev": true
|
687 |
+
},
|
688 |
+
"esprima": {
|
689 |
+
"version": "2.7.3",
|
690 |
+
"resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
|
691 |
+
"integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
|
692 |
+
"dev": true
|
693 |
+
},
|
694 |
+
"eventemitter2": {
|
695 |
+
"version": "0.4.14",
|
696 |
+
"resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
|
697 |
+
"integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=",
|
698 |
+
"dev": true
|
699 |
+
},
|
700 |
+
"exit": {
|
701 |
+
"version": "0.1.2",
|
702 |
+
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
|
703 |
+
"integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
|
704 |
+
"dev": true
|
705 |
+
},
|
706 |
+
"extend": {
|
707 |
+
"version": "3.0.1",
|
708 |
+
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
|
709 |
+
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
|
710 |
+
"dev": true
|
711 |
+
},
|
712 |
+
"extsprintf": {
|
713 |
+
"version": "1.3.0",
|
714 |
+
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
|
715 |
+
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
|
716 |
+
"dev": true
|
717 |
+
},
|
718 |
+
"faye-websocket": {
|
719 |
+
"version": "0.10.0",
|
720 |
+
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
|
721 |
+
"integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=",
|
722 |
+
"dev": true,
|
723 |
+
"requires": {
|
724 |
+
"websocket-driver": "0.7.0"
|
725 |
+
}
|
726 |
+
},
|
727 |
+
"figures": {
|
728 |
+
"version": "1.7.0",
|
729 |
+
"resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
|
730 |
+
"integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
|
731 |
+
"dev": true,
|
732 |
+
"requires": {
|
733 |
+
"escape-string-regexp": "1.0.5",
|
734 |
+
"object-assign": "4.1.1"
|
735 |
+
}
|
736 |
+
},
|
737 |
+
"find-up": {
|
738 |
+
"version": "1.1.2",
|
739 |
+
"resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
|
740 |
+
"integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
|
741 |
+
"dev": true,
|
742 |
+
"requires": {
|
743 |
+
"path-exists": "2.1.0",
|
744 |
+
"pinkie-promise": "2.0.1"
|
745 |
+
}
|
746 |
+
},
|
747 |
+
"findup-sync": {
|
748 |
+
"version": "0.3.0",
|
749 |
+
"resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz",
|
750 |
+
"integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=",
|
751 |
+
"dev": true,
|
752 |
+
"requires": {
|
753 |
+
"glob": "5.0.15"
|
754 |
+
},
|
755 |
+
"dependencies": {
|
756 |
+
"glob": {
|
757 |
+
"version": "5.0.15",
|
758 |
+
"resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
|
759 |
+
"integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
|
760 |
+
"dev": true,
|
761 |
+
"requires": {
|
762 |
+
"inflight": "1.0.6",
|
763 |
+
"inherits": "2.0.3",
|
764 |
+
"minimatch": "3.0.4",
|
765 |
+
"once": "1.4.0",
|
766 |
+
"path-is-absolute": "1.0.1"
|
767 |
+
}
|
768 |
+
}
|
769 |
+
}
|
770 |
+
},
|
771 |
+
"forever-agent": {
|
772 |
+
"version": "0.6.1",
|
773 |
+
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
|
774 |
+
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
|
775 |
+
"dev": true
|
776 |
+
},
|
777 |
+
"form-data": {
|
778 |
+
"version": "2.1.4",
|
779 |
+
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
|
780 |
+
"integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
|
781 |
+
"dev": true,
|
782 |
+
"requires": {
|
783 |
+
"asynckit": "0.4.0",
|
784 |
+
"combined-stream": "1.0.6",
|
785 |
+
"mime-types": "2.1.18"
|
786 |
+
}
|
787 |
+
},
|
788 |
+
"fs.realpath": {
|
789 |
+
"version": "1.0.0",
|
790 |
+
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
791 |
+
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
792 |
+
"dev": true
|
793 |
+
},
|
794 |
+
"fstream": {
|
795 |
+
"version": "1.0.11",
|
796 |
+
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
|
797 |
+
"integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
|
798 |
+
"dev": true,
|
799 |
+
"requires": {
|
800 |
+
"graceful-fs": "4.1.11",
|
801 |
+
"inherits": "2.0.3",
|
802 |
+
"mkdirp": "0.5.1",
|
803 |
+
"rimraf": "2.2.8"
|
804 |
+
}
|
805 |
+
},
|
806 |
+
"gauge": {
|
807 |
+
"version": "2.7.4",
|
808 |
+
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
|
809 |
+
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
|
810 |
+
"dev": true,
|
811 |
+
"requires": {
|
812 |
+
"aproba": "1.2.0",
|
813 |
+
"console-control-strings": "1.1.0",
|
814 |
+
"has-unicode": "2.0.1",
|
815 |
+
"object-assign": "4.1.1",
|
816 |
+
"signal-exit": "3.0.2",
|
817 |
+
"string-width": "1.0.2",
|
818 |
+
"strip-ansi": "3.0.1",
|
819 |
+
"wide-align": "1.1.2"
|
820 |
+
}
|
821 |
+
},
|
822 |
+
"gaze": {
|
823 |
+
"version": "1.1.2",
|
824 |
+
"resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz",
|
825 |
+
"integrity": "sha1-hHIkZ3rbiHDWeSV+0ziP22HkAQU=",
|
826 |
+
"dev": true,
|
827 |
+
"requires": {
|
828 |
+
"globule": "1.2.0"
|
829 |
+
}
|
830 |
+
},
|
831 |
+
"generate-function": {
|
832 |
+
"version": "2.0.0",
|
833 |
+
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz",
|
834 |
+
"integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=",
|
835 |
+
"dev": true
|
836 |
+
},
|
837 |
+
"generate-object-property": {
|
838 |
+
"version": "1.2.0",
|
839 |
+
"resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
|
840 |
+
"integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=",
|
841 |
+
"dev": true,
|
842 |
+
"requires": {
|
843 |
+
"is-property": "1.0.2"
|
844 |
+
}
|
845 |
+
},
|
846 |
+
"get-caller-file": {
|
847 |
+
"version": "1.0.2",
|
848 |
+
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
|
849 |
+
"integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=",
|
850 |
+
"dev": true
|
851 |
+
},
|
852 |
+
"get-stdin": {
|
853 |
+
"version": "4.0.1",
|
854 |
+
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
|
855 |
+
"integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
|
856 |
+
"dev": true
|
857 |
+
},
|
858 |
+
"getobject": {
|
859 |
+
"version": "0.1.0",
|
860 |
+
"resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz",
|
861 |
+
"integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=",
|
862 |
+
"dev": true
|
863 |
+
},
|
864 |
+
"getpass": {
|
865 |
+
"version": "0.1.7",
|
866 |
+
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
|
867 |
+
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
|
868 |
+
"dev": true,
|
869 |
+
"requires": {
|
870 |
+
"assert-plus": "1.0.0"
|
871 |
+
},
|
872 |
+
"dependencies": {
|
873 |
+
"assert-plus": {
|
874 |
+
"version": "1.0.0",
|
875 |
+
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
876 |
+
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
877 |
+
"dev": true
|
878 |
+
}
|
879 |
+
}
|
880 |
+
},
|
881 |
+
"glob": {
|
882 |
+
"version": "7.0.6",
|
883 |
+
"resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz",
|
884 |
+
"integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=",
|
885 |
+
"dev": true,
|
886 |
+
"requires": {
|
887 |
+
"fs.realpath": "1.0.0",
|
888 |
+
"inflight": "1.0.6",
|
889 |
+
"inherits": "2.0.3",
|
890 |
+
"minimatch": "3.0.4",
|
891 |
+
"once": "1.4.0",
|
892 |
+
"path-is-absolute": "1.0.1"
|
893 |
+
}
|
894 |
+
},
|
895 |
+
"globule": {
|
896 |
+
"version": "1.2.0",
|
897 |
+
"resolved": "https://registry.npmjs.org/globule/-/globule-1.2.0.tgz",
|
898 |
+
"integrity": "sha1-HcScaCLdnoovoAuiopUAboZkvQk=",
|
899 |
+
"dev": true,
|
900 |
+
"requires": {
|
901 |
+
"glob": "7.1.2",
|
902 |
+
"lodash": "4.17.10",
|
903 |
+
"minimatch": "3.0.4"
|
904 |
+
},
|
905 |
+
"dependencies": {
|
906 |
+
"glob": {
|
907 |
+
"version": "7.1.2",
|
908 |
+
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
|
909 |
+
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
910 |
+
"dev": true,
|
911 |
+
"requires": {
|
912 |
+
"fs.realpath": "1.0.0",
|
913 |
+
"inflight": "1.0.6",
|
914 |
+
"inherits": "2.0.3",
|
915 |
+
"minimatch": "3.0.4",
|
916 |
+
"once": "1.4.0",
|
917 |
+
"path-is-absolute": "1.0.1"
|
918 |
+
}
|
919 |
+
}
|
920 |
+
}
|
921 |
+
},
|
922 |
+
"graceful-fs": {
|
923 |
+
"version": "4.1.11",
|
924 |
+
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
|
925 |
+
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
|
926 |
+
"dev": true
|
927 |
+
},
|
928 |
+
"grunt": {
|
929 |
+
"version": "1.0.2",
|
930 |
+
"resolved": "https://registry.npmjs.org/grunt/-/grunt-1.0.2.tgz",
|
931 |
+
"integrity": "sha1-TmpeaVtwRy/VME9fqeNCNoNqc7w=",
|
932 |
+
"dev": true,
|
933 |
+
"requires": {
|
934 |
+
"coffeescript": "1.10.0",
|
935 |
+
"dateformat": "1.0.12",
|
936 |
+
"eventemitter2": "0.4.14",
|
937 |
+
"exit": "0.1.2",
|
938 |
+
"findup-sync": "0.3.0",
|
939 |
+
"glob": "7.0.6",
|
940 |
+
"grunt-cli": "1.2.0",
|
941 |
+
"grunt-known-options": "1.1.0",
|
942 |
+
"grunt-legacy-log": "1.0.2",
|
943 |
+
"grunt-legacy-util": "1.0.0",
|
944 |
+
"iconv-lite": "0.4.21",
|
945 |
+
"js-yaml": "3.5.5",
|
946 |
+
"minimatch": "3.0.4",
|
947 |
+
"nopt": "3.0.6",
|
948 |
+
"path-is-absolute": "1.0.1",
|
949 |
+
"rimraf": "2.2.8"
|
950 |
+
},
|
951 |
+
"dependencies": {
|
952 |
+
"grunt-cli": {
|
953 |
+
"version": "1.2.0",
|
954 |
+
"resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz",
|
955 |
+
"integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=",
|
956 |
+
"dev": true,
|
957 |
+
"requires": {
|
958 |
+
"findup-sync": "0.3.0",
|
959 |
+
"grunt-known-options": "1.1.0",
|
960 |
+
"nopt": "3.0.6",
|
961 |
+
"resolve": "1.1.7"
|
962 |
+
}
|
963 |
+
}
|
964 |
+
}
|
965 |
+
},
|
966 |
+
"grunt-contrib-jshint": {
|
967 |
+
"version": "1.1.0",
|
968 |
+
"resolved": "https://registry.npmjs.org/grunt-contrib-jshint/-/grunt-contrib-jshint-1.1.0.tgz",
|
969 |
+
"integrity": "sha1-Np2QmyWTxA6L55lAshNAhQx5Oaw=",
|
970 |
+
"dev": true,
|
971 |
+
"requires": {
|
972 |
+
"chalk": "1.1.3",
|
973 |
+
"hooker": "0.2.3",
|
974 |
+
"jshint": "2.9.5"
|
975 |
+
}
|
976 |
+
},
|
977 |
+
"grunt-contrib-uglify": {
|
978 |
+
"version": "3.3.0",
|
979 |
+
"resolved": "https://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-3.3.0.tgz",
|
980 |
+
"integrity": "sha512-W9O7lJE3PlD8VCc5fyaf98QV7f5wEDiU4PBIh0+/6UBbk2LhgzEFS0/p+taH5UD3+PlEn7QPN0o06Z0To6SqXw==",
|
981 |
+
"dev": true,
|
982 |
+
"requires": {
|
983 |
+
"chalk": "1.1.3",
|
984 |
+
"maxmin": "1.1.0",
|
985 |
+
"uglify-js": "3.3.22",
|
986 |
+
"uri-path": "1.0.0"
|
987 |
+
}
|
988 |
+
},
|
989 |
+
"grunt-contrib-watch": {
|
990 |
+
"version": "1.0.1",
|
991 |
+
"resolved": "https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-1.0.1.tgz",
|
992 |
+
"integrity": "sha512-8Zka/svGl6+ZwF7d6z/CfXwsb4cDODnajmZsY4nUAs9Ob0kJEcsLiDf5qm2HdDoEcm3NHjWCrFiWx+PZ2y4D7A==",
|
993 |
+
"dev": true,
|
994 |
+
"requires": {
|
995 |
+
"async": "1.5.2",
|
996 |
+
"gaze": "1.1.2",
|
997 |
+
"lodash": "4.17.10",
|
998 |
+
"tiny-lr": "0.2.1"
|
999 |
+
}
|
1000 |
+
},
|
1001 |
+
"grunt-known-options": {
|
1002 |
+
"version": "1.1.0",
|
1003 |
+
"resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.0.tgz",
|
1004 |
+
"integrity": "sha1-pCdO6zL6dl2lp6OxcSYXzjsUQUk=",
|
1005 |
+
"dev": true
|
1006 |
+
},
|
1007 |
+
"grunt-legacy-log": {
|
1008 |
+
"version": "1.0.2",
|
1009 |
+
"resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-1.0.2.tgz",
|
1010 |
+
"integrity": "sha512-WdedTJ/6zCXnI/coaouzqvkI19uwqbcPkdsXiDRKJyB5rOUlOxnCnTVbpeUdEckKVir2uHF3rDBYppj2p6N3+g==",
|
1011 |
+
"dev": true,
|
1012 |
+
"requires": {
|
1013 |
+
"colors": "1.1.2",
|
1014 |
+
"grunt-legacy-log-utils": "1.0.0",
|
1015 |
+
"hooker": "0.2.3",
|
1016 |
+
"lodash": "4.17.10"
|
1017 |
+
}
|
1018 |
+
},
|
1019 |
+
"grunt-legacy-log-utils": {
|
1020 |
+
"version": "1.0.0",
|
1021 |
+
"resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-1.0.0.tgz",
|
1022 |
+
"integrity": "sha1-p7ji0Ps1taUPSvmG/BEnSevJbz0=",
|
1023 |
+
"dev": true,
|
1024 |
+
"requires": {
|
1025 |
+
"chalk": "1.1.3",
|
1026 |
+
"lodash": "4.3.0"
|
1027 |
+
},
|
1028 |
+
"dependencies": {
|
1029 |
+
"lodash": {
|
1030 |
+
"version": "4.3.0",
|
1031 |
+
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.3.0.tgz",
|
1032 |
+
"integrity": "sha1-79nEpuxT87BUEkKZFcPkgk5NJaQ=",
|
1033 |
+
"dev": true
|
1034 |
+
}
|
1035 |
+
}
|
1036 |
+
},
|
1037 |
+
"grunt-legacy-util": {
|
1038 |
+
"version": "1.0.0",
|
1039 |
+
"resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.0.0.tgz",
|
1040 |
+
"integrity": "sha1-OGqnjcbtUJhsKxiVcmWxtIq7m4Y=",
|
1041 |
+
"dev": true,
|
1042 |
+
"requires": {
|
1043 |
+
"async": "1.5.2",
|
1044 |
+
"exit": "0.1.2",
|
1045 |
+
"getobject": "0.1.0",
|
1046 |
+
"hooker": "0.2.3",
|
1047 |
+
"lodash": "4.3.0",
|
1048 |
+
"underscore.string": "3.2.3",
|
1049 |
+
"which": "1.2.14"
|
1050 |
+
},
|
1051 |
+
"dependencies": {
|
1052 |
+
"lodash": {
|
1053 |
+
"version": "4.3.0",
|
1054 |
+
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.3.0.tgz",
|
1055 |
+
"integrity": "sha1-79nEpuxT87BUEkKZFcPkgk5NJaQ=",
|
1056 |
+
"dev": true
|
1057 |
+
}
|
1058 |
+
}
|
1059 |
+
},
|
1060 |
+
"grunt-phplint": {
|
1061 |
+
"version": "0.1.0",
|
1062 |
+
"resolved": "https://registry.npmjs.org/grunt-phplint/-/grunt-phplint-0.1.0.tgz",
|
1063 |
+
"integrity": "sha1-bb4uauxTqiKc+sCtmnyZ4kGEhI0=",
|
1064 |
+
"dev": true,
|
1065 |
+
"requires": {
|
1066 |
+
"cache-swap": "0.3.0",
|
1067 |
+
"grunt": "0.4.5"
|
1068 |
+
},
|
1069 |
+
"dependencies": {
|
1070 |
+
"argparse": {
|
1071 |
+
"version": "0.1.16",
|
1072 |
+
"resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.16.tgz",
|
1073 |
+
"integrity": "sha1-z9AeD7uj1srtBJ+9dY1A9lGW9Xw=",
|
1074 |
+
"dev": true,
|
1075 |
+
"requires": {
|
1076 |
+
"underscore": "1.7.0",
|
1077 |
+
"underscore.string": "2.4.0"
|
1078 |
+
},
|
1079 |
+
"dependencies": {
|
1080 |
+
"underscore.string": {
|
1081 |
+
"version": "2.4.0",
|
1082 |
+
"resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz",
|
1083 |
+
"integrity": "sha1-jN2PusTi0uoefi6Al8QvRCKA+Fs=",
|
1084 |
+
"dev": true
|
1085 |
+
}
|
1086 |
+
}
|
1087 |
+
},
|
1088 |
+
"async": {
|
1089 |
+
"version": "0.1.22",
|
1090 |
+
"resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz",
|
1091 |
+
"integrity": "sha1-D8GqoIig4+8Ovi2IMbqw3PiEUGE=",
|
1092 |
+
"dev": true
|
1093 |
+
},
|
1094 |
+
"coffee-script": {
|
1095 |
+
"version": "1.3.3",
|
1096 |
+
"resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz",
|
1097 |
+
"integrity": "sha1-FQ1rTLUiiUNp7+1qIQHCC8f0pPQ=",
|
1098 |
+
"dev": true
|
1099 |
+
},
|
1100 |
+
"colors": {
|
1101 |
+
"version": "0.6.2",
|
1102 |
+
"resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz",
|
1103 |
+
"integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=",
|
1104 |
+
"dev": true
|
1105 |
+
},
|
1106 |
+
"dateformat": {
|
1107 |
+
"version": "1.0.2-1.2.3",
|
1108 |
+
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz",
|
1109 |
+
"integrity": "sha1-sCIMAt6YYXQztyhRz0fePfLNvuk=",
|
1110 |
+
"dev": true
|
1111 |
+
},
|
1112 |
+
"esprima": {
|
1113 |
+
"version": "1.0.4",
|
1114 |
+
"resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz",
|
1115 |
+
"integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=",
|
1116 |
+
"dev": true
|
1117 |
+
},
|
1118 |
+
"findup-sync": {
|
1119 |
+
"version": "0.1.3",
|
1120 |
+
"resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.3.tgz",
|
1121 |
+
"integrity": "sha1-fz56l7gjksZTvwZYm9hRkOk8NoM=",
|
1122 |
+
"dev": true,
|
1123 |
+
"requires": {
|
1124 |
+
"glob": "3.2.11",
|
1125 |
+
"lodash": "2.4.2"
|
1126 |
+
},
|
1127 |
+
"dependencies": {
|
1128 |
+
"glob": {
|
1129 |
+
"version": "3.2.11",
|
1130 |
+
"resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz",
|
1131 |
+
"integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=",
|
1132 |
+
"dev": true,
|
1133 |
+
"requires": {
|
1134 |
+
"inherits": "2.0.3",
|
1135 |
+
"minimatch": "0.3.0"
|
1136 |
+
}
|
1137 |
+
},
|
1138 |
+
"lodash": {
|
1139 |
+
"version": "2.4.2",
|
1140 |
+
"resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
|
1141 |
+
"integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=",
|
1142 |
+
"dev": true
|
1143 |
+
},
|
1144 |
+
"minimatch": {
|
1145 |
+
"version": "0.3.0",
|
1146 |
+
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz",
|
1147 |
+
"integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=",
|
1148 |
+
"dev": true,
|
1149 |
+
"requires": {
|
1150 |
+
"lru-cache": "2.7.3",
|
1151 |
+
"sigmund": "1.0.1"
|
1152 |
+
}
|
1153 |
+
}
|
1154 |
+
}
|
1155 |
+
},
|
1156 |
+
"glob": {
|
1157 |
+
"version": "3.1.21",
|
1158 |
+
"resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz",
|
1159 |
+
"integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=",
|
1160 |
+
"dev": true,
|
1161 |
+
"requires": {
|
1162 |
+
"graceful-fs": "1.2.3",
|
1163 |
+
"inherits": "1.0.2",
|
1164 |
+
"minimatch": "0.2.14"
|
1165 |
+
},
|
1166 |
+
"dependencies": {
|
1167 |
+
"inherits": {
|
1168 |
+
"version": "1.0.2",
|
1169 |
+
"resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz",
|
1170 |
+
"integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=",
|
1171 |
+
"dev": true
|
1172 |
+
}
|
1173 |
+
}
|
1174 |
+
},
|
1175 |
+
"graceful-fs": {
|
1176 |
+
"version": "1.2.3",
|
1177 |
+
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz",
|
1178 |
+
"integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=",
|
1179 |
+
"dev": true
|
1180 |
+
},
|
1181 |
+
"grunt": {
|
1182 |
+
"version": "0.4.5",
|
1183 |
+
"resolved": "https://registry.npmjs.org/grunt/-/grunt-0.4.5.tgz",
|
1184 |
+
"integrity": "sha1-VpN81RlDJK3/bSB2MYMqnWuk5/A=",
|
1185 |
+
"dev": true,
|
1186 |
+
"requires": {
|
1187 |
+
"async": "0.1.22",
|
1188 |
+
"coffee-script": "1.3.3",
|
1189 |
+
"colors": "0.6.2",
|
1190 |
+
"dateformat": "1.0.2-1.2.3",
|
1191 |
+
"eventemitter2": "0.4.14",
|
1192 |
+
"exit": "0.1.2",
|
1193 |
+
"findup-sync": "0.1.3",
|
1194 |
+
"getobject": "0.1.0",
|
1195 |
+
"glob": "3.1.21",
|
1196 |
+
"grunt-legacy-log": "0.1.3",
|
1197 |
+
"grunt-legacy-util": "0.2.0",
|
1198 |
+
"hooker": "0.2.3",
|
1199 |
+
"iconv-lite": "0.2.11",
|
1200 |
+
"js-yaml": "2.0.5",
|
1201 |
+
"lodash": "0.9.2",
|
1202 |
+
"minimatch": "0.2.14",
|
1203 |
+
"nopt": "1.0.10",
|
1204 |
+
"rimraf": "2.2.8",
|
1205 |
+
"underscore.string": "2.2.1",
|
1206 |
+
"which": "1.0.9"
|
1207 |
+
}
|
1208 |
+
},
|
1209 |
+
"grunt-legacy-log": {
|
1210 |
+
"version": "0.1.3",
|
1211 |
+
"resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-0.1.3.tgz",
|
1212 |
+
"integrity": "sha1-7ClCboAwIa9ZAp+H0vnNczWgVTE=",
|
1213 |
+
"dev": true,
|
1214 |
+
"requires": {
|
1215 |
+
"colors": "0.6.2",
|
1216 |
+
"grunt-legacy-log-utils": "0.1.1",
|
1217 |
+
"hooker": "0.2.3",
|
1218 |
+
"lodash": "2.4.2",
|
1219 |
+
"underscore.string": "2.3.3"
|
1220 |
+
},
|
1221 |
+
"dependencies": {
|
1222 |
+
"lodash": {
|
1223 |
+
"version": "2.4.2",
|
1224 |
+
"resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
|
1225 |
+
"integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=",
|
1226 |
+
"dev": true
|
1227 |
+
},
|
1228 |
+
"underscore.string": {
|
1229 |
+
"version": "2.3.3",
|
1230 |
+
"resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz",
|
1231 |
+
"integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=",
|
1232 |
+
"dev": true
|
1233 |
+
}
|
1234 |
+
}
|
1235 |
+
},
|
1236 |
+
"grunt-legacy-log-utils": {
|
1237 |
+
"version": "0.1.1",
|
1238 |
+
"resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-0.1.1.tgz",
|
1239 |
+
"integrity": "sha1-wHBrndkGThFvNvI/5OawSGcsD34=",
|
1240 |
+
"dev": true,
|
1241 |
+
"requires": {
|
1242 |
+
"colors": "0.6.2",
|
1243 |
+
"lodash": "2.4.2",
|
1244 |
+
"underscore.string": "2.3.3"
|
1245 |
+
},
|
1246 |
+
"dependencies": {
|
1247 |
+
"lodash": {
|
1248 |
+
"version": "2.4.2",
|
1249 |
+
"resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
|
1250 |
+
"integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=",
|
1251 |
+
"dev": true
|
1252 |
+
},
|
1253 |
+
"underscore.string": {
|
1254 |
+
"version": "2.3.3",
|
1255 |
+
"resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz",
|
1256 |
+
"integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=",
|
1257 |
+
"dev": true
|
1258 |
+
}
|
1259 |
+
}
|
1260 |
+
},
|
1261 |
+
"grunt-legacy-util": {
|
1262 |
+
"version": "0.2.0",
|
1263 |
+
"resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-0.2.0.tgz",
|
1264 |
+
"integrity": "sha1-kzJIhNv343qf98Am3/RR2UqeVUs=",
|
1265 |
+
"dev": true,
|
1266 |
+
"requires": {
|
1267 |
+
"async": "0.1.22",
|
1268 |
+
"exit": "0.1.2",
|
1269 |
+
"getobject": "0.1.0",
|
1270 |
+
"hooker": "0.2.3",
|
1271 |
+
"lodash": "0.9.2",
|
1272 |
+
"underscore.string": "2.2.1",
|
1273 |
+
"which": "1.0.9"
|
1274 |
+
}
|
1275 |
+
},
|
1276 |
+
"iconv-lite": {
|
1277 |
+
"version": "0.2.11",
|
1278 |
+
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz",
|
1279 |
+
"integrity": "sha1-HOYKOleGSiktEyH/RgnKS7llrcg=",
|
1280 |
+
"dev": true
|
1281 |
+
},
|
1282 |
+
"js-yaml": {
|
1283 |
+
"version": "2.0.5",
|
1284 |
+
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-2.0.5.tgz",
|
1285 |
+
"integrity": "sha1-olrmUJmZ6X3yeMZxnaEb0Gh3Q6g=",
|
1286 |
+
"dev": true,
|
1287 |
+
"requires": {
|
1288 |
+
"argparse": "0.1.16",
|
1289 |
+
"esprima": "1.0.4"
|
1290 |
+
}
|
1291 |
+
},
|
1292 |
+
"lodash": {
|
1293 |
+
"version": "0.9.2",
|
1294 |
+
"resolved": "https://registry.npmjs.org/lodash/-/lodash-0.9.2.tgz",
|
1295 |
+
"integrity": "sha1-jzSZxSRdNG1oLlsNO0B2fgnxqSw=",
|
1296 |
+
"dev": true
|
1297 |
+
},
|
1298 |
+
"minimatch": {
|
1299 |
+
"version": "0.2.14",
|
1300 |
+
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz",
|
1301 |
+
"integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=",
|
1302 |
+
"dev": true,
|
1303 |
+
"requires": {
|
1304 |
+
"lru-cache": "2.7.3",
|
1305 |
+
"sigmund": "1.0.1"
|
1306 |
+
}
|
1307 |
+
},
|
1308 |
+
"nopt": {
|
1309 |
+
"version": "1.0.10",
|
1310 |
+
"resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
|
1311 |
+
"integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
|
1312 |
+
"dev": true,
|
1313 |
+
"requires": {
|
1314 |
+
"abbrev": "1.1.1"
|
1315 |
+
}
|
1316 |
+
},
|
1317 |
+
"underscore.string": {
|
1318 |
+
"version": "2.2.1",
|
1319 |
+
"resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.2.1.tgz",
|
1320 |
+
"integrity": "sha1-18D6KvXVoaZ/QlPa7pgTLnM/Dxk=",
|
1321 |
+
"dev": true
|
1322 |
+
},
|
1323 |
+
"which": {
|
1324 |
+
"version": "1.0.9",
|
1325 |
+
"resolved": "https://registry.npmjs.org/which/-/which-1.0.9.tgz",
|
1326 |
+
"integrity": "sha1-RgwdoPgQED0DIam2M6+eV15kSG8=",
|
1327 |
+
"dev": true
|
1328 |
+
}
|
1329 |
+
}
|
1330 |
+
},
|
1331 |
+
"grunt-sass": {
|
1332 |
+
"version": "2.1.0",
|
1333 |
+
"resolved": "https://registry.npmjs.org/grunt-sass/-/grunt-sass-2.1.0.tgz",
|
1334 |
+
"integrity": "sha512-XkexnQt/9rhReNd+Y7T0n/2g5FqYOQKfi2iSlpwDqvgs7EgEaGTxNhnWzHnbW5oNRvzL9AHopBG3AgRxL0d+DA==",
|
1335 |
+
"dev": true,
|
1336 |
+
"requires": {
|
1337 |
+
"each-async": "1.1.1",
|
1338 |
+
"node-sass": "4.9.0",
|
1339 |
+
"object-assign": "4.1.1"
|
1340 |
+
}
|
1341 |
+
},
|
1342 |
+
"gzip-size": {
|
1343 |
+
"version": "1.0.0",
|
1344 |
+
"resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-1.0.0.tgz",
|
1345 |
+
"integrity": "sha1-Zs+LEBBHInuVus5uodoMF37Vwi8=",
|
1346 |
+
"dev": true,
|
1347 |
+
"requires": {
|
1348 |
+
"browserify-zlib": "0.1.4",
|
1349 |
+
"concat-stream": "1.6.2"
|
1350 |
+
}
|
1351 |
+
},
|
1352 |
+
"har-validator": {
|
1353 |
+
"version": "2.0.6",
|
1354 |
+
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
|
1355 |
+
"integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=",
|
1356 |
+
"dev": true,
|
1357 |
+
"requires": {
|
1358 |
+
"chalk": "1.1.3",
|
1359 |
+
"commander": "2.15.1",
|
1360 |
+
"is-my-json-valid": "2.17.2",
|
1361 |
+
"pinkie-promise": "2.0.1"
|
1362 |
+
}
|
1363 |
+
},
|
1364 |
+
"has-ansi": {
|
1365 |
+
"version": "2.0.0",
|
1366 |
+
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
|
1367 |
+
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
|
1368 |
+
"dev": true,
|
1369 |
+
"requires": {
|
1370 |
+
"ansi-regex": "2.1.1"
|
1371 |
+
}
|
1372 |
+
},
|
1373 |
+
"has-unicode": {
|
1374 |
+
"version": "2.0.1",
|
1375 |
+
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
1376 |
+
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
|
1377 |
+
"dev": true
|
1378 |
+
},
|
1379 |
+
"hawk": {
|
1380 |
+
"version": "3.1.3",
|
1381 |
+
"resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
|
1382 |
+
"integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
|
1383 |
+
"dev": true,
|
1384 |
+
"requires": {
|
1385 |
+
"boom": "2.10.1",
|
1386 |
+
"cryptiles": "2.0.5",
|
1387 |
+
"hoek": "2.16.3",
|
1388 |
+
"sntp": "1.0.9"
|
1389 |
+
}
|
1390 |
+
},
|
1391 |
+
"hoek": {
|
1392 |
+
"version": "2.16.3",
|
1393 |
+
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
|
1394 |
+
"integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
|
1395 |
+
"dev": true
|
1396 |
+
},
|
1397 |
+
"hooker": {
|
1398 |
+
"version": "0.2.3",
|
1399 |
+
"resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz",
|
1400 |
+
"integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=",
|
1401 |
+
"dev": true
|
1402 |
+
},
|
1403 |
+
"hosted-git-info": {
|
1404 |
+
"version": "2.6.0",
|
1405 |
+
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz",
|
1406 |
+
"integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==",
|
1407 |
+
"dev": true
|
1408 |
+
},
|
1409 |
+
"htmlparser2": {
|
1410 |
+
"version": "3.8.3",
|
1411 |
+
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz",
|
1412 |
+
"integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=",
|
1413 |
+
"dev": true,
|
1414 |
+
"requires": {
|
1415 |
+
"domelementtype": "1.3.0",
|
1416 |
+
"domhandler": "2.3.0",
|
1417 |
+
"domutils": "1.5.1",
|
1418 |
+
"entities": "1.0.0",
|
1419 |
+
"readable-stream": "1.1.14"
|
1420 |
+
}
|
1421 |
+
},
|
1422 |
+
"http-errors": {
|
1423 |
+
"version": "1.3.1",
|
1424 |
+
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz",
|
1425 |
+
"integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=",
|
1426 |
+
"dev": true,
|
1427 |
+
"requires": {
|
1428 |
+
"inherits": "2.0.3",
|
1429 |
+
"statuses": "1.5.0"
|
1430 |
+
}
|
1431 |
+
},
|
1432 |
+
"http-parser-js": {
|
1433 |
+
"version": "0.4.12",
|
1434 |
+
"resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.12.tgz",
|
1435 |
+
"integrity": "sha1-uc+/Sizybw/DSxDKFImid3HjR08=",
|
1436 |
+
"dev": true
|
1437 |
+
},
|
1438 |
+
"http-signature": {
|
1439 |
+
"version": "1.1.1",
|
1440 |
+
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
|
1441 |
+
"integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
|
1442 |
+
"dev": true,
|
1443 |
+
"requires": {
|
1444 |
+
"assert-plus": "0.2.0",
|
1445 |
+
"jsprim": "1.4.1",
|
1446 |
+
"sshpk": "1.14.1"
|
1447 |
+
}
|
1448 |
+
},
|
1449 |
+
"iconv-lite": {
|
1450 |
+
"version": "0.4.21",
|
1451 |
+
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.21.tgz",
|
1452 |
+
"integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==",
|
1453 |
+
"dev": true,
|
1454 |
+
"requires": {
|
1455 |
+
"safer-buffer": "2.1.2"
|
1456 |
+
}
|
1457 |
+
},
|
1458 |
+
"in-publish": {
|
1459 |
+
"version": "2.0.0",
|
1460 |
+
"resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz",
|
1461 |
+
"integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=",
|
1462 |
+
"dev": true
|
1463 |
+
},
|
1464 |
+
"indent-string": {
|
1465 |
+
"version": "2.1.0",
|
1466 |
+
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
|
1467 |
+
"integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
|
1468 |
+
"dev": true,
|
1469 |
+
"requires": {
|
1470 |
+
"repeating": "2.0.1"
|
1471 |
+
}
|
1472 |
+
},
|
1473 |
+
"inflight": {
|
1474 |
+
"version": "1.0.6",
|
1475 |
+
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
1476 |
+
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
1477 |
+
"dev": true,
|
1478 |
+
"requires": {
|
1479 |
+
"once": "1.4.0",
|
1480 |
+
"wrappy": "1.0.2"
|
1481 |
+
}
|
1482 |
+
},
|
1483 |
+
"inherits": {
|
1484 |
+
"version": "2.0.3",
|
1485 |
+
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
1486 |
+
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
|
1487 |
+
"dev": true
|
1488 |
+
},
|
1489 |
+
"invert-kv": {
|
1490 |
+
"version": "1.0.0",
|
1491 |
+
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
|
1492 |
+
"integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
|
1493 |
+
"dev": true
|
1494 |
+
},
|
1495 |
+
"irregular-plurals": {
|
1496 |
+
"version": "1.4.0",
|
1497 |
+
"resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.4.0.tgz",
|
1498 |
+
"integrity": "sha1-LKmwM2UREYVUEvFr5dd8YqRYp2Y=",
|
1499 |
+
"dev": true
|
1500 |
+
},
|
1501 |
+
"is-arrayish": {
|
1502 |
+
"version": "0.2.1",
|
1503 |
+
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
1504 |
+
"integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
|
1505 |
+
"dev": true
|
1506 |
+
},
|
1507 |
+
"is-builtin-module": {
|
1508 |
+
"version": "1.0.0",
|
1509 |
+
"resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
|
1510 |
+
"integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
|
1511 |
+
"dev": true,
|
1512 |
+
"requires": {
|
1513 |
+
"builtin-modules": "1.1.1"
|
1514 |
+
}
|
1515 |
+
},
|
1516 |
+
"is-finite": {
|
1517 |
+
"version": "1.0.2",
|
1518 |
+
"resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
|
1519 |
+
"integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
|
1520 |
+
"dev": true,
|
1521 |
+
"requires": {
|
1522 |
+
"number-is-nan": "1.0.1"
|
1523 |
+
}
|
1524 |
+
},
|
1525 |
+
"is-fullwidth-code-point": {
|
1526 |
+
"version": "1.0.0",
|
1527 |
+
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
1528 |
+
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
1529 |
+
"dev": true,
|
1530 |
+
"requires": {
|
1531 |
+
"number-is-nan": "1.0.1"
|
1532 |
+
}
|
1533 |
+
},
|
1534 |
+
"is-my-ip-valid": {
|
1535 |
+
"version": "1.0.0",
|
1536 |
+
"resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz",
|
1537 |
+
"integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==",
|
1538 |
+
"dev": true
|
1539 |
+
},
|
1540 |
+
"is-my-json-valid": {
|
1541 |
+
"version": "2.17.2",
|
1542 |
+
"resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz",
|
1543 |
+
"integrity": "sha512-IBhBslgngMQN8DDSppmgDv7RNrlFotuuDsKcrCP3+HbFaVivIBU7u9oiiErw8sH4ynx3+gOGQ3q2otkgiSi6kg==",
|
1544 |
+
"dev": true,
|
1545 |
+
"requires": {
|
1546 |
+
"generate-function": "2.0.0",
|
1547 |
+
"generate-object-property": "1.2.0",
|
1548 |
+
"is-my-ip-valid": "1.0.0",
|
1549 |
+
"jsonpointer": "4.0.1",
|
1550 |
+
"xtend": "4.0.1"
|
1551 |
+
}
|
1552 |
+
},
|
1553 |
+
"is-property": {
|
1554 |
+
"version": "1.0.2",
|
1555 |
+
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
|
1556 |
+
"integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=",
|
1557 |
+
"dev": true
|
1558 |
+
},
|
1559 |
+
"is-typedarray": {
|
1560 |
+
"version": "1.0.0",
|
1561 |
+
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
1562 |
+
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
|
1563 |
+
"dev": true
|
1564 |
+
},
|
1565 |
+
"is-utf8": {
|
1566 |
+
"version": "0.2.1",
|
1567 |
+
"resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
|
1568 |
+
"integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
|
1569 |
+
"dev": true
|
1570 |
+
},
|
1571 |
+
"isarray": {
|
1572 |
+
"version": "0.0.1",
|
1573 |
+
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
1574 |
+
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
|
1575 |
+
"dev": true
|
1576 |
+
},
|
1577 |
+
"isexe": {
|
1578 |
+
"version": "2.0.0",
|
1579 |
+
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
1580 |
+
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
|
1581 |
+
"dev": true
|
1582 |
+
},
|
1583 |
+
"isstream": {
|
1584 |
+
"version": "0.1.2",
|
1585 |
+
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
1586 |
+
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
|
1587 |
+
"dev": true
|
1588 |
+
},
|
1589 |
+
"js-base64": {
|
1590 |
+
"version": "2.4.3",
|
1591 |
+
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.3.tgz",
|
1592 |
+
"integrity": "sha512-H7ErYLM34CvDMto3GbD6xD0JLUGYXR3QTcH6B/tr4Hi/QpSThnCsIp+Sy5FRTw3B0d6py4HcNkW7nO/wdtGWEw==",
|
1593 |
+
"dev": true
|
1594 |
+
},
|
1595 |
+
"js-yaml": {
|
1596 |
+
"version": "3.5.5",
|
1597 |
+
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.5.5.tgz",
|
1598 |
+
"integrity": "sha1-A3fDgBfKvHMisNH7zSWkkWQfL74=",
|
1599 |
+
"dev": true,
|
1600 |
+
"requires": {
|
1601 |
+
"argparse": "1.0.10",
|
1602 |
+
"esprima": "2.7.3"
|
1603 |
+
}
|
1604 |
+
},
|
1605 |
+
"jsbn": {
|
1606 |
+
"version": "0.1.1",
|
1607 |
+
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
1608 |
+
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
|
1609 |
+
"dev": true,
|
1610 |
+
"optional": true
|
1611 |
+
},
|
1612 |
+
"jshint": {
|
1613 |
+
"version": "2.9.5",
|
1614 |
+
"resolved": "https://registry.npmjs.org/jshint/-/jshint-2.9.5.tgz",
|
1615 |
+
"integrity": "sha1-HnJSkVzmgbQIJ+4UJIxG006apiw=",
|
1616 |
+
"dev": true,
|
1617 |
+
"requires": {
|
1618 |
+
"cli": "1.0.1",
|
1619 |
+
"console-browserify": "1.1.0",
|
1620 |
+
"exit": "0.1.2",
|
1621 |
+
"htmlparser2": "3.8.3",
|
1622 |
+
"lodash": "3.7.0",
|
1623 |
+
"minimatch": "3.0.4",
|
1624 |
+
"shelljs": "0.3.0",
|
1625 |
+
"strip-json-comments": "1.0.4"
|
1626 |
+
},
|
1627 |
+
"dependencies": {
|
1628 |
+
"lodash": {
|
1629 |
+
"version": "3.7.0",
|
1630 |
+
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.7.0.tgz",
|
1631 |
+
"integrity": "sha1-Nni9irmVBXwHreg27S7wh9qBHUU=",
|
1632 |
+
"dev": true
|
1633 |
+
}
|
1634 |
+
}
|
1635 |
+
},
|
1636 |
+
"jshint-stylish": {
|
1637 |
+
"version": "2.2.1",
|
1638 |
+
"resolved": "https://registry.npmjs.org/jshint-stylish/-/jshint-stylish-2.2.1.tgz",
|
1639 |
+
"integrity": "sha1-JCCCosA1rgP9gQROBXDMQgjPbmE=",
|
1640 |
+
"dev": true,
|
1641 |
+
"requires": {
|
1642 |
+
"beeper": "1.1.1",
|
1643 |
+
"chalk": "1.1.3",
|
1644 |
+
"log-symbols": "1.0.2",
|
1645 |
+
"plur": "2.1.2",
|
1646 |
+
"string-length": "1.0.1",
|
1647 |
+
"text-table": "0.2.0"
|
1648 |
+
}
|
1649 |
+
},
|
1650 |
+
"json-schema": {
|
1651 |
+
"version": "0.2.3",
|
1652 |
+
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
|
1653 |
+
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
|
1654 |
+
"dev": true
|
1655 |
+
},
|
1656 |
+
"json-stringify-safe": {
|
1657 |
+
"version": "5.0.1",
|
1658 |
+
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
1659 |
+
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
|
1660 |
+
"dev": true
|
1661 |
+
},
|
1662 |
+
"jsonpointer": {
|
1663 |
+
"version": "4.0.1",
|
1664 |
+
"resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
|
1665 |
+
"integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=",
|
1666 |
+
"dev": true
|
1667 |
+
},
|
1668 |
+
"jsprim": {
|
1669 |
+
"version": "1.4.1",
|
1670 |
+
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
|
1671 |
+
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
|
1672 |
+
"dev": true,
|
1673 |
+
"requires": {
|
1674 |
+
"assert-plus": "1.0.0",
|
1675 |
+
"extsprintf": "1.3.0",
|
1676 |
+
"json-schema": "0.2.3",
|
1677 |
+
"verror": "1.10.0"
|
1678 |
+
},
|
1679 |
+
"dependencies": {
|
1680 |
+
"assert-plus": {
|
1681 |
+
"version": "1.0.0",
|
1682 |
+
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
1683 |
+
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
1684 |
+
"dev": true
|
1685 |
+
}
|
1686 |
+
}
|
1687 |
+
},
|
1688 |
+
"lcid": {
|
1689 |
+
"version": "1.0.0",
|
1690 |
+
"resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
|
1691 |
+
"integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
|
1692 |
+
"dev": true,
|
1693 |
+
"requires": {
|
1694 |
+
"invert-kv": "1.0.0"
|
1695 |
+
}
|
1696 |
+
},
|
1697 |
+
"livereload-js": {
|
1698 |
+
"version": "2.3.0",
|
1699 |
+
"resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.3.0.tgz",
|
1700 |
+
"integrity": "sha512-j1R0/FeGa64Y+NmqfZhyoVRzcFlOZ8sNlKzHjh4VvLULFACZhn68XrX5DFg2FhMvSMJmROuFxRSa560ECWKBMg==",
|
1701 |
+
"dev": true
|
1702 |
+
},
|
1703 |
+
"load-grunt-tasks": {
|
1704 |
+
"version": "3.5.2",
|
1705 |
+
"resolved": "https://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-3.5.2.tgz",
|
1706 |
+
"integrity": "sha1-ByhWEYD9IP+KaSdQWFL8WKrqDIg=",
|
1707 |
+
"dev": true,
|
1708 |
+
"requires": {
|
1709 |
+
"arrify": "1.0.1",
|
1710 |
+
"multimatch": "2.1.0",
|
1711 |
+
"pkg-up": "1.0.0",
|
1712 |
+
"resolve-pkg": "0.1.0"
|
1713 |
+
}
|
1714 |
+
},
|
1715 |
+
"load-json-file": {
|
1716 |
+
"version": "1.1.0",
|
1717 |
+
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
|
1718 |
+
"integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
|
1719 |
+
"dev": true,
|
1720 |
+
"requires": {
|
1721 |
+
"graceful-fs": "4.1.11",
|
1722 |
+
"parse-json": "2.2.0",
|
1723 |
+
"pify": "2.3.0",
|
1724 |
+
"pinkie-promise": "2.0.1",
|
1725 |
+
"strip-bom": "2.0.0"
|
1726 |
+
}
|
1727 |
+
},
|
1728 |
+
"lodash": {
|
1729 |
+
"version": "4.17.10",
|
1730 |
+
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
|
1731 |
+
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
|
1732 |
+
"dev": true
|
1733 |
+
},
|
1734 |
+
"lodash.assign": {
|
1735 |
+
"version": "4.2.0",
|
1736 |
+
"resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
|
1737 |
+
"integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
|
1738 |
+
"dev": true
|
1739 |
+
},
|
1740 |
+
"lodash.clonedeep": {
|
1741 |
+
"version": "4.5.0",
|
1742 |
+
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
|
1743 |
+
"integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
|
1744 |
+
"dev": true
|
1745 |
+
},
|
1746 |
+
"lodash.mergewith": {
|
1747 |
+
"version": "4.6.1",
|
1748 |
+
"resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz",
|
1749 |
+
"integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==",
|
1750 |
+
"dev": true
|
1751 |
+
},
|
1752 |
+
"log-symbols": {
|
1753 |
+
"version": "1.0.2",
|
1754 |
+
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz",
|
1755 |
+
"integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=",
|
1756 |
+
"dev": true,
|
1757 |
+
"requires": {
|
1758 |
+
"chalk": "1.1.3"
|
1759 |
+
}
|
1760 |
+
},
|
1761 |
+
"loud-rejection": {
|
1762 |
+
"version": "1.6.0",
|
1763 |
+
"resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
|
1764 |
+
"integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
|
1765 |
+
"dev": true,
|
1766 |
+
"requires": {
|
1767 |
+
"currently-unhandled": "0.4.1",
|
1768 |
+
"signal-exit": "3.0.2"
|
1769 |
+
}
|
1770 |
+
},
|
1771 |
+
"lru-cache": {
|
1772 |
+
"version": "2.7.3",
|
1773 |
+
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz",
|
1774 |
+
"integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=",
|
1775 |
+
"dev": true
|
1776 |
+
},
|
1777 |
+
"map-obj": {
|
1778 |
+
"version": "1.0.1",
|
1779 |
+
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
|
1780 |
+
"integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
|
1781 |
+
"dev": true
|
1782 |
+
},
|
1783 |
+
"maxmin": {
|
1784 |
+
"version": "1.1.0",
|
1785 |
+
"resolved": "https://registry.npmjs.org/maxmin/-/maxmin-1.1.0.tgz",
|
1786 |
+
"integrity": "sha1-cTZehKmd2Piz99X94vANHn9zvmE=",
|
1787 |
+
"dev": true,
|
1788 |
+
"requires": {
|
1789 |
+
"chalk": "1.1.3",
|
1790 |
+
"figures": "1.7.0",
|
1791 |
+
"gzip-size": "1.0.0",
|
1792 |
+
"pretty-bytes": "1.0.4"
|
1793 |
+
}
|
1794 |
+
},
|
1795 |
+
"media-typer": {
|
1796 |
+
"version": "0.3.0",
|
1797 |
+
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
1798 |
+
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
|
1799 |
+
"dev": true
|
1800 |
+
},
|
1801 |
+
"meow": {
|
1802 |
+
"version": "3.7.0",
|
1803 |
+
"resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
|
1804 |
+
"integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
|
1805 |
+
"dev": true,
|
1806 |
+
"requires": {
|
1807 |
+
"camelcase-keys": "2.1.0",
|
1808 |
+
"decamelize": "1.2.0",
|
1809 |
+
"loud-rejection": "1.6.0",
|
1810 |
+
"map-obj": "1.0.1",
|
1811 |
+
"minimist": "1.2.0",
|
1812 |
+
"normalize-package-data": "2.4.0",
|
1813 |
+
"object-assign": "4.1.1",
|
1814 |
+
"read-pkg-up": "1.0.1",
|
1815 |
+
"redent": "1.0.0",
|
1816 |
+
"trim-newlines": "1.0.0"
|
1817 |
+
}
|
1818 |
+
},
|
1819 |
+
"mime-db": {
|
1820 |
+
"version": "1.33.0",
|
1821 |
+
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
|
1822 |
+
"integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==",
|
1823 |
+
"dev": true
|
1824 |
+
},
|
1825 |
+
"mime-types": {
|
1826 |
+
"version": "2.1.18",
|
1827 |
+
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
|
1828 |
+
"integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
|
1829 |
+
"dev": true,
|
1830 |
+
"requires": {
|
1831 |
+
"mime-db": "1.33.0"
|
1832 |
+
}
|
1833 |
+
},
|
1834 |
+
"minimatch": {
|
1835 |
+
"version": "3.0.4",
|
1836 |
+
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
1837 |
+
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
1838 |
+
"dev": true,
|
1839 |
+
"requires": {
|
1840 |
+
"brace-expansion": "1.1.11"
|
1841 |
+
}
|
1842 |
+
},
|
1843 |
+
"minimist": {
|
1844 |
+
"version": "1.2.0",
|
1845 |
+
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
1846 |
+
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
1847 |
+
"dev": true
|
1848 |
+
},
|
1849 |
+
"mkdirp": {
|
1850 |
+
"version": "0.5.1",
|
1851 |
+
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
1852 |
+
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
1853 |
+
"dev": true,
|
1854 |
+
"requires": {
|
1855 |
+
"minimist": "0.0.8"
|
1856 |
+
},
|
1857 |
+
"dependencies": {
|
1858 |
+
"minimist": {
|
1859 |
+
"version": "0.0.8",
|
1860 |
+
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
1861 |
+
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
1862 |
+
"dev": true
|
1863 |
+
}
|
1864 |
+
}
|
1865 |
+
},
|
1866 |
+
"ms": {
|
1867 |
+
"version": "0.7.1",
|
1868 |
+
"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
|
1869 |
+
"integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=",
|
1870 |
+
"dev": true
|
1871 |
+
},
|
1872 |
+
"multimatch": {
|
1873 |
+
"version": "2.1.0",
|
1874 |
+
"resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz",
|
1875 |
+
"integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=",
|
1876 |
+
"dev": true,
|
1877 |
+
"requires": {
|
1878 |
+
"array-differ": "1.0.0",
|
1879 |
+
"array-union": "1.0.2",
|
1880 |
+
"arrify": "1.0.1",
|
1881 |
+
"minimatch": "3.0.4"
|
1882 |
+
}
|
1883 |
+
},
|
1884 |
+
"nan": {
|
1885 |
+
"version": "2.10.0",
|
1886 |
+
"resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
|
1887 |
+
"integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==",
|
1888 |
+
"dev": true
|
1889 |
+
},
|
1890 |
+
"node-gyp": {
|
1891 |
+
"version": "3.6.2",
|
1892 |
+
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.2.tgz",
|
1893 |
+
"integrity": "sha1-m/vlRWIoYoSDjnUOrAUpWFP6HGA=",
|
1894 |
+
"dev": true,
|
1895 |
+
"requires": {
|
1896 |
+
"fstream": "1.0.11",
|
1897 |
+
"glob": "7.0.6",
|
1898 |
+
"graceful-fs": "4.1.11",
|
1899 |
+
"minimatch": "3.0.4",
|
1900 |
+
"mkdirp": "0.5.1",
|
1901 |
+
"nopt": "3.0.6",
|
1902 |
+
"npmlog": "4.1.2",
|
1903 |
+
"osenv": "0.1.5",
|
1904 |
+
"request": "2.79.0",
|
1905 |
+
"rimraf": "2.2.8",
|
1906 |
+
"semver": "5.3.0",
|
1907 |
+
"tar": "2.2.1",
|
1908 |
+
"which": "1.2.14"
|
1909 |
+
},
|
1910 |
+
"dependencies": {
|
1911 |
+
"semver": {
|
1912 |
+
"version": "5.3.0",
|
1913 |
+
"resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
|
1914 |
+
"integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
|
1915 |
+
"dev": true
|
1916 |
+
}
|
1917 |
+
}
|
1918 |
+
},
|
1919 |
+
"node-sass": {
|
1920 |
+
"version": "4.9.0",
|
1921 |
+
"resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.9.0.tgz",
|
1922 |
+
"integrity": "sha512-QFHfrZl6lqRU3csypwviz2XLgGNOoWQbo2GOvtsfQqOfL4cy1BtWnhx/XUeAO9LT3ahBzSRXcEO6DdvAH9DzSg==",
|
1923 |
+
"dev": true,
|
1924 |
+
"requires": {
|
1925 |
+
"async-foreach": "0.1.3",
|
1926 |
+
"chalk": "1.1.3",
|
1927 |
+
"cross-spawn": "3.0.1",
|
1928 |
+
"gaze": "1.1.2",
|
1929 |
+
"get-stdin": "4.0.1",
|
1930 |
+
"glob": "7.0.6",
|
1931 |
+
"in-publish": "2.0.0",
|
1932 |
+
"lodash.assign": "4.2.0",
|
1933 |
+
"lodash.clonedeep": "4.5.0",
|
1934 |
+
"lodash.mergewith": "4.6.1",
|
1935 |
+
"meow": "3.7.0",
|
1936 |
+
"mkdirp": "0.5.1",
|
1937 |
+
"nan": "2.10.0",
|
1938 |
+
"node-gyp": "3.6.2",
|
1939 |
+
"npmlog": "4.1.2",
|
1940 |
+
"request": "2.79.0",
|
1941 |
+
"sass-graph": "2.2.4",
|
1942 |
+
"stdout-stream": "1.4.0",
|
1943 |
+
"true-case-path": "1.0.2"
|
1944 |
+
}
|
1945 |
+
},
|
1946 |
+
"nopt": {
|
1947 |
+
"version": "3.0.6",
|
1948 |
+
"resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
|
1949 |
+
"integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
|
1950 |
+
"dev": true,
|
1951 |
+
"requires": {
|
1952 |
+
"abbrev": "1.1.1"
|
1953 |
+
}
|
1954 |
+
},
|
1955 |
+
"normalize-package-data": {
|
1956 |
+
"version": "2.4.0",
|
1957 |
+
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
|
1958 |
+
"integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
|
1959 |
+
"dev": true,
|
1960 |
+
"requires": {
|
1961 |
+
"hosted-git-info": "2.6.0",
|
1962 |
+
"is-builtin-module": "1.0.0",
|
1963 |
+
"semver": "5.5.0",
|
1964 |
+
"validate-npm-package-license": "3.0.3"
|
1965 |
+
}
|
1966 |
+
},
|
1967 |
+
"npmlog": {
|
1968 |
+
"version": "4.1.2",
|
1969 |
+
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
|
1970 |
+
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
|
1971 |
+
"dev": true,
|
1972 |
+
"requires": {
|
1973 |
+
"are-we-there-yet": "1.1.4",
|
1974 |
+
"console-control-strings": "1.1.0",
|
1975 |
+
"gauge": "2.7.4",
|
1976 |
+
"set-blocking": "2.0.0"
|
1977 |
+
}
|
1978 |
+
},
|
1979 |
+
"number-is-nan": {
|
1980 |
+
"version": "1.0.1",
|
1981 |
+
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
|
1982 |
+
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
|
1983 |
+
"dev": true
|
1984 |
+
},
|
1985 |
+
"oauth-sign": {
|
1986 |
+
"version": "0.8.2",
|
1987 |
+
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
|
1988 |
+
"integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
|
1989 |
+
"dev": true
|
1990 |
+
},
|
1991 |
+
"object-assign": {
|
1992 |
+
"version": "4.1.1",
|
1993 |
+
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
1994 |
+
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
1995 |
+
"dev": true
|
1996 |
+
},
|
1997 |
+
"on-finished": {
|
1998 |
+
"version": "2.3.0",
|
1999 |
+
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
2000 |
+
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
|
2001 |
+
"dev": true,
|
2002 |
+
"requires": {
|
2003 |
+
"ee-first": "1.1.1"
|
2004 |
+
}
|
2005 |
+
},
|
2006 |
+
"once": {
|
2007 |
+
"version": "1.4.0",
|
2008 |
+
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
2009 |
+
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
2010 |
+
"dev": true,
|
2011 |
+
"requires": {
|
2012 |
+
"wrappy": "1.0.2"
|
2013 |
+
}
|
2014 |
+
},
|
2015 |
+
"onetime": {
|
2016 |
+
"version": "1.1.0",
|
2017 |
+
"resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
|
2018 |
+
"integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
|
2019 |
+
"dev": true
|
2020 |
+
},
|
2021 |
+
"os-homedir": {
|
2022 |
+
"version": "1.0.2",
|
2023 |
+
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
|
2024 |
+
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
|
2025 |
+
"dev": true
|
2026 |
+
},
|
2027 |
+
"os-locale": {
|
2028 |
+
"version": "1.4.0",
|
2029 |
+
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
|
2030 |
+
"integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
|
2031 |
+
"dev": true,
|
2032 |
+
"requires": {
|
2033 |
+
"lcid": "1.0.0"
|
2034 |
+
}
|
2035 |
+
},
|
2036 |
+
"os-tmpdir": {
|
2037 |
+
"version": "1.0.2",
|
2038 |
+
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
|
2039 |
+
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
|
2040 |
+
"dev": true
|
2041 |
+
},
|
2042 |
+
"osenv": {
|
2043 |
+
"version": "0.1.5",
|
2044 |
+
"resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
|
2045 |
+
"integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
|
2046 |
+
"dev": true,
|
2047 |
+
"requires": {
|
2048 |
+
"os-homedir": "1.0.2",
|
2049 |
+
"os-tmpdir": "1.0.2"
|
2050 |
+
}
|
2051 |
+
},
|
2052 |
+
"pako": {
|
2053 |
+
"version": "0.2.9",
|
2054 |
+
"resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
|
2055 |
+
"integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=",
|
2056 |
+
"dev": true
|
2057 |
+
},
|
2058 |
+
"parse-json": {
|
2059 |
+
"version": "2.2.0",
|
2060 |
+
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
|
2061 |
+
"integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
|
2062 |
+
"dev": true,
|
2063 |
+
"requires": {
|
2064 |
+
"error-ex": "1.3.1"
|
2065 |
+
}
|
2066 |
+
},
|
2067 |
+
"parse-ms": {
|
2068 |
+
"version": "1.0.1",
|
2069 |
+
"resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz",
|
2070 |
+
"integrity": "sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0=",
|
2071 |
+
"dev": true
|
2072 |
+
},
|
2073 |
+
"parseurl": {
|
2074 |
+
"version": "1.3.2",
|
2075 |
+
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
|
2076 |
+
"integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=",
|
2077 |
+
"dev": true
|
2078 |
+
},
|
2079 |
+
"path-exists": {
|
2080 |
+
"version": "2.1.0",
|
2081 |
+
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
|
2082 |
+
"integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
|
2083 |
+
"dev": true,
|
2084 |
+
"requires": {
|
2085 |
+
"pinkie-promise": "2.0.1"
|
2086 |
+
}
|
2087 |
+
},
|
2088 |
+
"path-is-absolute": {
|
2089 |
+
"version": "1.0.1",
|
2090 |
+
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
2091 |
+
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
2092 |
+
"dev": true
|
2093 |
+
},
|
2094 |
+
"path-type": {
|
2095 |
+
"version": "1.1.0",
|
2096 |
+
"resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
|
2097 |
+
"integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
|
2098 |
+
"dev": true,
|
2099 |
+
"requires": {
|
2100 |
+
"graceful-fs": "4.1.11",
|
2101 |
+
"pify": "2.3.0",
|
2102 |
+
"pinkie-promise": "2.0.1"
|
2103 |
+
}
|
2104 |
+
},
|
2105 |
+
"pify": {
|
2106 |
+
"version": "2.3.0",
|
2107 |
+
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
2108 |
+
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
|
2109 |
+
"dev": true
|
2110 |
+
},
|
2111 |
+
"pinkie": {
|
2112 |
+
"version": "2.0.4",
|
2113 |
+
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
|
2114 |
+
"integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
|
2115 |
+
"dev": true
|
2116 |
+
},
|
2117 |
+
"pinkie-promise": {
|
2118 |
+
"version": "2.0.1",
|
2119 |
+
"resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
|
2120 |
+
"integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
|
2121 |
+
"dev": true,
|
2122 |
+
"requires": {
|
2123 |
+
"pinkie": "2.0.4"
|
2124 |
+
}
|
2125 |
+
},
|
2126 |
+
"pkg-up": {
|
2127 |
+
"version": "1.0.0",
|
2128 |
+
"resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz",
|
2129 |
+
"integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=",
|
2130 |
+
"dev": true,
|
2131 |
+
"requires": {
|
2132 |
+
"find-up": "1.1.2"
|
2133 |
+
}
|
2134 |
+
},
|
2135 |
+
"plur": {
|
2136 |
+
"version": "2.1.2",
|
2137 |
+
"resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz",
|
2138 |
+
"integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=",
|
2139 |
+
"dev": true,
|
2140 |
+
"requires": {
|
2141 |
+
"irregular-plurals": "1.4.0"
|
2142 |
+
}
|
2143 |
+
},
|
2144 |
+
"pretty-bytes": {
|
2145 |
+
"version": "1.0.4",
|
2146 |
+
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz",
|
2147 |
+
"integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=",
|
2148 |
+
"dev": true,
|
2149 |
+
"requires": {
|
2150 |
+
"get-stdin": "4.0.1",
|
2151 |
+
"meow": "3.7.0"
|
2152 |
+
}
|
2153 |
+
},
|
2154 |
+
"pretty-ms": {
|
2155 |
+
"version": "2.1.0",
|
2156 |
+
"resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz",
|
2157 |
+
"integrity": "sha1-QlfCVt8/sLRR1q/6qwIYhBJpgdw=",
|
2158 |
+
"dev": true,
|
2159 |
+
"requires": {
|
2160 |
+
"is-finite": "1.0.2",
|
2161 |
+
"parse-ms": "1.0.1",
|
2162 |
+
"plur": "1.0.0"
|
2163 |
+
},
|
2164 |
+
"dependencies": {
|
2165 |
+
"plur": {
|
2166 |
+
"version": "1.0.0",
|
2167 |
+
"resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz",
|
2168 |
+
"integrity": "sha1-24XGgU9eXlo7Se/CjWBP7GKXUVY=",
|
2169 |
+
"dev": true
|
2170 |
+
}
|
2171 |
+
}
|
2172 |
+
},
|
2173 |
+
"process-nextick-args": {
|
2174 |
+
"version": "2.0.0",
|
2175 |
+
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
|
2176 |
+
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
|
2177 |
+
"dev": true
|
2178 |
+
},
|
2179 |
+
"pseudomap": {
|
2180 |
+
"version": "1.0.2",
|
2181 |
+
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
|
2182 |
+
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
|
2183 |
+
"dev": true
|
2184 |
+
},
|
2185 |
+
"punycode": {
|
2186 |
+
"version": "1.4.1",
|
2187 |
+
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
2188 |
+
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
|
2189 |
+
"dev": true
|
2190 |
+
},
|
2191 |
+
"qs": {
|
2192 |
+
"version": "5.1.0",
|
2193 |
+
"resolved": "https://registry.npmjs.org/qs/-/qs-5.1.0.tgz",
|
2194 |
+
"integrity": "sha1-TZMuXH6kEcynajEtOaYGIA/VDNk=",
|
2195 |
+
"dev": true
|
2196 |
+
},
|
2197 |
+
"raw-body": {
|
2198 |
+
"version": "2.1.7",
|
2199 |
+
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.1.7.tgz",
|
2200 |
+
"integrity": "sha1-rf6s4uT7MJgFgBTQjActzFl1h3Q=",
|
2201 |
+
"dev": true,
|
2202 |
+
"requires": {
|
2203 |
+
"bytes": "2.4.0",
|
2204 |
+
"iconv-lite": "0.4.13",
|
2205 |
+
"unpipe": "1.0.0"
|
2206 |
+
},
|
2207 |
+
"dependencies": {
|
2208 |
+
"bytes": {
|
2209 |
+
"version": "2.4.0",
|
2210 |
+
"resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz",
|
2211 |
+
"integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=",
|
2212 |
+
"dev": true
|
2213 |
+
},
|
2214 |
+
"iconv-lite": {
|
2215 |
+
"version": "0.4.13",
|
2216 |
+
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz",
|
2217 |
+
"integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=",
|
2218 |
+
"dev": true
|
2219 |
+
}
|
2220 |
+
}
|
2221 |
+
},
|
2222 |
+
"read-pkg": {
|
2223 |
+
"version": "1.1.0",
|
2224 |
+
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
|
2225 |
+
"integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
|
2226 |
+
"dev": true,
|
2227 |
+
"requires": {
|
2228 |
+
"load-json-file": "1.1.0",
|
2229 |
+
"normalize-package-data": "2.4.0",
|
2230 |
+
"path-type": "1.1.0"
|
2231 |
+
}
|
2232 |
+
},
|
2233 |
+
"read-pkg-up": {
|
2234 |
+
"version": "1.0.1",
|
2235 |
+
"resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
|
2236 |
+
"integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
|
2237 |
+
"dev": true,
|
2238 |
+
"requires": {
|
2239 |
+
"find-up": "1.1.2",
|
2240 |
+
"read-pkg": "1.1.0"
|
2241 |
+
}
|
2242 |
+
},
|
2243 |
+
"readable-stream": {
|
2244 |
+
"version": "1.1.14",
|
2245 |
+
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
|
2246 |
+
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
|
2247 |
+
"dev": true,
|
2248 |
+
"requires": {
|
2249 |
+
"core-util-is": "1.0.2",
|
2250 |
+
"inherits": "2.0.3",
|
2251 |
+
"isarray": "0.0.1",
|
2252 |
+
"string_decoder": "0.10.31"
|
2253 |
+
}
|
2254 |
+
},
|
2255 |
+
"redent": {
|
2256 |
+
"version": "1.0.0",
|
2257 |
+
"resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
|
2258 |
+
"integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
|
2259 |
+
"dev": true,
|
2260 |
+
"requires": {
|
2261 |
+
"indent-string": "2.1.0",
|
2262 |
+
"strip-indent": "1.0.1"
|
2263 |
+
}
|
2264 |
+
},
|
2265 |
+
"repeating": {
|
2266 |
+
"version": "2.0.1",
|
2267 |
+
"resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
|
2268 |
+
"integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
|
2269 |
+
"dev": true,
|
2270 |
+
"requires": {
|
2271 |
+
"is-finite": "1.0.2"
|
2272 |
+
}
|
2273 |
+
},
|
2274 |
+
"request": {
|
2275 |
+
"version": "2.79.0",
|
2276 |
+
"resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz",
|
2277 |
+
"integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=",
|
2278 |
+
"dev": true,
|
2279 |
+
"requires": {
|
2280 |
+
"aws-sign2": "0.6.0",
|
2281 |
+
"aws4": "1.7.0",
|
2282 |
+
"caseless": "0.11.0",
|
2283 |
+
"combined-stream": "1.0.6",
|
2284 |
+
"extend": "3.0.1",
|
2285 |
+
"forever-agent": "0.6.1",
|
2286 |
+
"form-data": "2.1.4",
|
2287 |
+
"har-validator": "2.0.6",
|
2288 |
+
"hawk": "3.1.3",
|
2289 |
+
"http-signature": "1.1.1",
|
2290 |
+
"is-typedarray": "1.0.0",
|
2291 |
+
"isstream": "0.1.2",
|
2292 |
+
"json-stringify-safe": "5.0.1",
|
2293 |
+
"mime-types": "2.1.18",
|
2294 |
+
"oauth-sign": "0.8.2",
|
2295 |
+
"qs": "6.3.2",
|
2296 |
+
"stringstream": "0.0.5",
|
2297 |
+
"tough-cookie": "2.3.4",
|
2298 |
+
"tunnel-agent": "0.4.3",
|
2299 |
+
"uuid": "3.2.1"
|
2300 |
+
},
|
2301 |
+
"dependencies": {
|
2302 |
+
"qs": {
|
2303 |
+
"version": "6.3.2",
|
2304 |
+
"resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz",
|
2305 |
+
"integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=",
|
2306 |
+
"dev": true
|
2307 |
+
}
|
2308 |
+
}
|
2309 |
+
},
|
2310 |
+
"require-directory": {
|
2311 |
+
"version": "2.1.1",
|
2312 |
+
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
2313 |
+
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
|
2314 |
+
"dev": true
|
2315 |
+
},
|
2316 |
+
"require-main-filename": {
|
2317 |
+
"version": "1.0.1",
|
2318 |
+
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
|
2319 |
+
"integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
|
2320 |
+
"dev": true
|
2321 |
+
},
|
2322 |
+
"resolve": {
|
2323 |
+
"version": "1.1.7",
|
2324 |
+
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
|
2325 |
+
"integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
|
2326 |
+
"dev": true
|
2327 |
+
},
|
2328 |
+
"resolve-from": {
|
2329 |
+
"version": "2.0.0",
|
2330 |
+
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz",
|
2331 |
+
"integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=",
|
2332 |
+
"dev": true
|
2333 |
+
},
|
2334 |
+
"resolve-pkg": {
|
2335 |
+
"version": "0.1.0",
|
2336 |
+
"resolved": "https://registry.npmjs.org/resolve-pkg/-/resolve-pkg-0.1.0.tgz",
|
2337 |
+
"integrity": "sha1-AsyZNBDik2livZcWahsHfalyVTE=",
|
2338 |
+
"dev": true,
|
2339 |
+
"requires": {
|
2340 |
+
"resolve-from": "2.0.0"
|
2341 |
+
}
|
2342 |
+
},
|
2343 |
+
"rimraf": {
|
2344 |
+
"version": "2.2.8",
|
2345 |
+
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
|
2346 |
+
"integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=",
|
2347 |
+
"dev": true
|
2348 |
+
},
|
2349 |
+
"safe-buffer": {
|
2350 |
+
"version": "5.1.2",
|
2351 |
+
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
2352 |
+
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
2353 |
+
"dev": true
|
2354 |
+
},
|
2355 |
+
"safer-buffer": {
|
2356 |
+
"version": "2.1.2",
|
2357 |
+
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
2358 |
+
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
2359 |
+
"dev": true
|
2360 |
+
},
|
2361 |
+
"sass-graph": {
|
2362 |
+
"version": "2.2.4",
|
2363 |
+
"resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz",
|
2364 |
+
"integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=",
|
2365 |
+
"dev": true,
|
2366 |
+
"requires": {
|
2367 |
+
"glob": "7.0.6",
|
2368 |
+
"lodash": "4.17.10",
|
2369 |
+
"scss-tokenizer": "0.2.3",
|
2370 |
+
"yargs": "7.1.0"
|
2371 |
+
}
|
2372 |
+
},
|
2373 |
+
"scss-tokenizer": {
|
2374 |
+
"version": "0.2.3",
|
2375 |
+
"resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz",
|
2376 |
+
"integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=",
|
2377 |
+
"dev": true,
|
2378 |
+
"requires": {
|
2379 |
+
"js-base64": "2.4.3",
|
2380 |
+
"source-map": "0.4.4"
|
2381 |
+
},
|
2382 |
+
"dependencies": {
|
2383 |
+
"source-map": {
|
2384 |
+
"version": "0.4.4",
|
2385 |
+
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
|
2386 |
+
"integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
|
2387 |
+
"dev": true,
|
2388 |
+
"requires": {
|
2389 |
+
"amdefine": "1.0.1"
|
2390 |
+
}
|
2391 |
+
}
|
2392 |
+
}
|
2393 |
+
},
|
2394 |
+
"semver": {
|
2395 |
+
"version": "5.5.0",
|
2396 |
+
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
|
2397 |
+
"integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
|
2398 |
+
"dev": true
|
2399 |
+
},
|
2400 |
+
"set-blocking": {
|
2401 |
+
"version": "2.0.0",
|
2402 |
+
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
2403 |
+
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
|
2404 |
+
"dev": true
|
2405 |
+
},
|
2406 |
+
"set-immediate-shim": {
|
2407 |
+
"version": "1.0.1",
|
2408 |
+
"resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
|
2409 |
+
"integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
|
2410 |
+
"dev": true
|
2411 |
+
},
|
2412 |
+
"shelljs": {
|
2413 |
+
"version": "0.3.0",
|
2414 |
+
"resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz",
|
2415 |
+
"integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=",
|
2416 |
+
"dev": true
|
2417 |
+
},
|
2418 |
+
"sigmund": {
|
2419 |
+
"version": "1.0.1",
|
2420 |
+
"resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
|
2421 |
+
"integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=",
|
2422 |
+
"dev": true
|
2423 |
+
},
|
2424 |
+
"signal-exit": {
|
2425 |
+
"version": "3.0.2",
|
2426 |
+
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
2427 |
+
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
|
2428 |
+
"dev": true
|
2429 |
+
},
|
2430 |
+
"sntp": {
|
2431 |
+
"version": "1.0.9",
|
2432 |
+
"resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
|
2433 |
+
"integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
|
2434 |
+
"dev": true,
|
2435 |
+
"requires": {
|
2436 |
+
"hoek": "2.16.3"
|
2437 |
+
}
|
2438 |
+
},
|
2439 |
+
"source-map": {
|
2440 |
+
"version": "0.6.1",
|
2441 |
+
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
2442 |
+
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
2443 |
+
"dev": true
|
2444 |
+
},
|
2445 |
+
"spdx-correct": {
|
2446 |
+
"version": "3.0.0",
|
2447 |
+
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz",
|
2448 |
+
"integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==",
|
2449 |
+
"dev": true,
|
2450 |
+
"requires": {
|
2451 |
+
"spdx-expression-parse": "3.0.0",
|
2452 |
+
"spdx-license-ids": "3.0.0"
|
2453 |
+
}
|
2454 |
+
},
|
2455 |
+
"spdx-exceptions": {
|
2456 |
+
"version": "2.1.0",
|
2457 |
+
"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz",
|
2458 |
+
"integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==",
|
2459 |
+
"dev": true
|
2460 |
+
},
|
2461 |
+
"spdx-expression-parse": {
|
2462 |
+
"version": "3.0.0",
|
2463 |
+
"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
|
2464 |
+
"integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
|
2465 |
+
"dev": true,
|
2466 |
+
"requires": {
|
2467 |
+
"spdx-exceptions": "2.1.0",
|
2468 |
+
"spdx-license-ids": "3.0.0"
|
2469 |
+
}
|
2470 |
+
},
|
2471 |
+
"spdx-license-ids": {
|
2472 |
+
"version": "3.0.0",
|
2473 |
+
"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz",
|
2474 |
+
"integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==",
|
2475 |
+
"dev": true
|
2476 |
+
},
|
2477 |
+
"sprintf-js": {
|
2478 |
+
"version": "1.0.3",
|
2479 |
+
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
2480 |
+
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
|
2481 |
+
"dev": true
|
2482 |
+
},
|
2483 |
+
"sshpk": {
|
2484 |
+
"version": "1.14.1",
|
2485 |
+
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz",
|
2486 |
+
"integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=",
|
2487 |
+
"dev": true,
|
2488 |
+
"requires": {
|
2489 |
+
"asn1": "0.2.3",
|
2490 |
+
"assert-plus": "1.0.0",
|
2491 |
+
"bcrypt-pbkdf": "1.0.1",
|
2492 |
+
"dashdash": "1.14.1",
|
2493 |
+
"ecc-jsbn": "0.1.1",
|
2494 |
+
"getpass": "0.1.7",
|
2495 |
+
"jsbn": "0.1.1",
|
2496 |
+
"tweetnacl": "0.14.5"
|
2497 |
+
},
|
2498 |
+
"dependencies": {
|
2499 |
+
"assert-plus": {
|
2500 |
+
"version": "1.0.0",
|
2501 |
+
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
2502 |
+
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
2503 |
+
"dev": true
|
2504 |
+
}
|
2505 |
+
}
|
2506 |
+
},
|
2507 |
+
"statuses": {
|
2508 |
+
"version": "1.5.0",
|
2509 |
+
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
2510 |
+
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
|
2511 |
+
"dev": true
|
2512 |
+
},
|
2513 |
+
"stdout-stream": {
|
2514 |
+
"version": "1.4.0",
|
2515 |
+
"resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.0.tgz",
|
2516 |
+
"integrity": "sha1-osfIWH5U2UJ+qe2zrD8s1SLfN4s=",
|
2517 |
+
"dev": true,
|
2518 |
+
"requires": {
|
2519 |
+
"readable-stream": "2.3.6"
|
2520 |
+
},
|
2521 |
+
"dependencies": {
|
2522 |
+
"isarray": {
|
2523 |
+
"version": "1.0.0",
|
2524 |
+
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
2525 |
+
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
2526 |
+
"dev": true
|
2527 |
+
},
|
2528 |
+
"readable-stream": {
|
2529 |
+
"version": "2.3.6",
|
2530 |
+
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
2531 |
+
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
2532 |
+
"dev": true,
|
2533 |
+
"requires": {
|
2534 |
+
"core-util-is": "1.0.2",
|
2535 |
+
"inherits": "2.0.3",
|
2536 |
+
"isarray": "1.0.0",
|
2537 |
+
"process-nextick-args": "2.0.0",
|
2538 |
+
"safe-buffer": "5.1.2",
|
2539 |
+
"string_decoder": "1.1.1",
|
2540 |
+
"util-deprecate": "1.0.2"
|
2541 |
+
}
|
2542 |
+
},
|
2543 |
+
"string_decoder": {
|
2544 |
+
"version": "1.1.1",
|
2545 |
+
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
2546 |
+
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
2547 |
+
"dev": true,
|
2548 |
+
"requires": {
|
2549 |
+
"safe-buffer": "5.1.2"
|
2550 |
+
}
|
2551 |
+
}
|
2552 |
+
}
|
2553 |
+
},
|
2554 |
+
"string-length": {
|
2555 |
+
"version": "1.0.1",
|
2556 |
+
"resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz",
|
2557 |
+
"integrity": "sha1-VpcPscOFWOnnC3KL894mmsRa36w=",
|
2558 |
+
"dev": true,
|
2559 |
+
"requires": {
|
2560 |
+
"strip-ansi": "3.0.1"
|
2561 |
+
}
|
2562 |
+
},
|
2563 |
+
"string-width": {
|
2564 |
+
"version": "1.0.2",
|
2565 |
+
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
2566 |
+
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
2567 |
+
"dev": true,
|
2568 |
+
"requires": {
|
2569 |
+
"code-point-at": "1.1.0",
|
2570 |
+
"is-fullwidth-code-point": "1.0.0",
|
2571 |
+
"strip-ansi": "3.0.1"
|
2572 |
+
}
|
2573 |
+
},
|
2574 |
+
"string_decoder": {
|
2575 |
+
"version": "0.10.31",
|
2576 |
+
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
2577 |
+
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
|
2578 |
+
"dev": true
|
2579 |
+
},
|
2580 |
+
"stringstream": {
|
2581 |
+
"version": "0.0.5",
|
2582 |
+
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
|
2583 |
+
"integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
|
2584 |
+
"dev": true
|
2585 |
+
},
|
2586 |
+
"strip-ansi": {
|
2587 |
+
"version": "3.0.1",
|
2588 |
+
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
2589 |
+
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
2590 |
+
"dev": true,
|
2591 |
+
"requires": {
|
2592 |
+
"ansi-regex": "2.1.1"
|
2593 |
+
}
|
2594 |
+
},
|
2595 |
+
"strip-bom": {
|
2596 |
+
"version": "2.0.0",
|
2597 |
+
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
|
2598 |
+
"integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
|
2599 |
+
"dev": true,
|
2600 |
+
"requires": {
|
2601 |
+
"is-utf8": "0.2.1"
|
2602 |
+
}
|
2603 |
+
},
|
2604 |
+
"strip-indent": {
|
2605 |
+
"version": "1.0.1",
|
2606 |
+
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
|
2607 |
+
"integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
|
2608 |
+
"dev": true,
|
2609 |
+
"requires": {
|
2610 |
+
"get-stdin": "4.0.1"
|
2611 |
+
}
|
2612 |
+
},
|
2613 |
+
"strip-json-comments": {
|
2614 |
+
"version": "1.0.4",
|
2615 |
+
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz",
|
2616 |
+
"integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=",
|
2617 |
+
"dev": true
|
2618 |
+
},
|
2619 |
+
"supports-color": {
|
2620 |
+
"version": "2.0.0",
|
2621 |
+
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
2622 |
+
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
2623 |
+
"dev": true
|
2624 |
+
},
|
2625 |
+
"tar": {
|
2626 |
+
"version": "2.2.1",
|
2627 |
+
"resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
|
2628 |
+
"integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
|
2629 |
+
"dev": true,
|
2630 |
+
"requires": {
|
2631 |
+
"block-stream": "0.0.9",
|
2632 |
+
"fstream": "1.0.11",
|
2633 |
+
"inherits": "2.0.3"
|
2634 |
+
}
|
2635 |
+
},
|
2636 |
+
"text-table": {
|
2637 |
+
"version": "0.2.0",
|
2638 |
+
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
2639 |
+
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
|
2640 |
+
"dev": true
|
2641 |
+
},
|
2642 |
+
"time-grunt": {
|
2643 |
+
"version": "1.4.0",
|
2644 |
+
"resolved": "https://registry.npmjs.org/time-grunt/-/time-grunt-1.4.0.tgz",
|
2645 |
+
"integrity": "sha1-BiIT5mDJB+hvRAVWwB6mWXtxJCA=",
|
2646 |
+
"dev": true,
|
2647 |
+
"requires": {
|
2648 |
+
"chalk": "1.1.3",
|
2649 |
+
"date-time": "1.1.0",
|
2650 |
+
"figures": "1.7.0",
|
2651 |
+
"hooker": "0.2.3",
|
2652 |
+
"number-is-nan": "1.0.1",
|
2653 |
+
"pretty-ms": "2.1.0",
|
2654 |
+
"text-table": "0.2.0"
|
2655 |
+
}
|
2656 |
+
},
|
2657 |
+
"time-zone": {
|
2658 |
+
"version": "0.1.0",
|
2659 |
+
"resolved": "https://registry.npmjs.org/time-zone/-/time-zone-0.1.0.tgz",
|
2660 |
+
"integrity": "sha1-Sncotqwo2w4Aj1FAQ/1VW9VXO0Y=",
|
2661 |
+
"dev": true
|
2662 |
+
},
|
2663 |
+
"tiny-lr": {
|
2664 |
+
"version": "0.2.1",
|
2665 |
+
"resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-0.2.1.tgz",
|
2666 |
+
"integrity": "sha1-s/26gC5dVqM8L28QeUsy5Hescp0=",
|
2667 |
+
"dev": true,
|
2668 |
+
"requires": {
|
2669 |
+
"body-parser": "1.14.2",
|
2670 |
+
"debug": "2.2.0",
|
2671 |
+
"faye-websocket": "0.10.0",
|
2672 |
+
"livereload-js": "2.3.0",
|
2673 |
+
"parseurl": "1.3.2",
|
2674 |
+
"qs": "5.1.0"
|
2675 |
+
}
|
2676 |
+
},
|
2677 |
+
"tough-cookie": {
|
2678 |
+
"version": "2.3.4",
|
2679 |
+
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
|
2680 |
+
"integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
|
2681 |
+
"dev": true,
|
2682 |
+
"requires": {
|
2683 |
+
"punycode": "1.4.1"
|
2684 |
+
}
|
2685 |
+
},
|
2686 |
+
"trim-newlines": {
|
2687 |
+
"version": "1.0.0",
|
2688 |
+
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
|
2689 |
+
"integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
|
2690 |
+
"dev": true
|
2691 |
+
},
|
2692 |
+
"true-case-path": {
|
2693 |
+
"version": "1.0.2",
|
2694 |
+
"resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.2.tgz",
|
2695 |
+
"integrity": "sha1-fskRMJJHZsf1c74wIMNPj9/QDWI=",
|
2696 |
+
"dev": true,
|
2697 |
+
"requires": {
|
2698 |
+
"glob": "6.0.4"
|
2699 |
+
},
|
2700 |
+
"dependencies": {
|
2701 |
+
"glob": {
|
2702 |
+
"version": "6.0.4",
|
2703 |
+
"resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
|
2704 |
+
"integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=",
|
2705 |
+
"dev": true,
|
2706 |
+
"requires": {
|
2707 |
+
"inflight": "1.0.6",
|
2708 |
+
"inherits": "2.0.3",
|
2709 |
+
"minimatch": "3.0.4",
|
2710 |
+
"once": "1.4.0",
|
2711 |
+
"path-is-absolute": "1.0.1"
|
2712 |
+
}
|
2713 |
+
}
|
2714 |
+
}
|
2715 |
+
},
|
2716 |
+
"tunnel-agent": {
|
2717 |
+
"version": "0.4.3",
|
2718 |
+
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
|
2719 |
+
"integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=",
|
2720 |
+
"dev": true
|
2721 |
+
},
|
2722 |
+
"tweetnacl": {
|
2723 |
+
"version": "0.14.5",
|
2724 |
+
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
2725 |
+
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
|
2726 |
+
"dev": true,
|
2727 |
+
"optional": true
|
2728 |
+
},
|
2729 |
+
"type-is": {
|
2730 |
+
"version": "1.6.16",
|
2731 |
+
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
|
2732 |
+
"integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
|
2733 |
+
"dev": true,
|
2734 |
+
"requires": {
|
2735 |
+
"media-typer": "0.3.0",
|
2736 |
+
"mime-types": "2.1.18"
|
2737 |
+
}
|
2738 |
+
},
|
2739 |
+
"typedarray": {
|
2740 |
+
"version": "0.0.6",
|
2741 |
+
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
2742 |
+
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
|
2743 |
+
"dev": true
|
2744 |
+
},
|
2745 |
+
"uglify-js": {
|
2746 |
+
"version": "3.3.22",
|
2747 |
+
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.22.tgz",
|
2748 |
+
"integrity": "sha512-tqw96rL6/BG+7LM5VItdhDjTQmL5zG/I0b2RqWytlgeHe2eydZHuBHdA9vuGpCDhH/ZskNGcqDhivoR2xt8RIw==",
|
2749 |
+
"dev": true,
|
2750 |
+
"requires": {
|
2751 |
+
"commander": "2.15.1",
|
2752 |
+
"source-map": "0.6.1"
|
2753 |
+
}
|
2754 |
+
},
|
2755 |
+
"underscore": {
|
2756 |
+
"version": "1.7.0",
|
2757 |
+
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz",
|
2758 |
+
"integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=",
|
2759 |
+
"dev": true
|
2760 |
+
},
|
2761 |
+
"underscore.string": {
|
2762 |
+
"version": "3.2.3",
|
2763 |
+
"resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.2.3.tgz",
|
2764 |
+
"integrity": "sha1-gGmSYzZl1eX8tNsfs6hi62jp5to=",
|
2765 |
+
"dev": true
|
2766 |
+
},
|
2767 |
+
"unpipe": {
|
2768 |
+
"version": "1.0.0",
|
2769 |
+
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
2770 |
+
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
|
2771 |
+
"dev": true
|
2772 |
+
},
|
2773 |
+
"uri-path": {
|
2774 |
+
"version": "1.0.0",
|
2775 |
+
"resolved": "https://registry.npmjs.org/uri-path/-/uri-path-1.0.0.tgz",
|
2776 |
+
"integrity": "sha1-l0fwGDWJM8Md4PzP2C0TjmcmLjI=",
|
2777 |
+
"dev": true
|
2778 |
+
},
|
2779 |
+
"util-deprecate": {
|
2780 |
+
"version": "1.0.2",
|
2781 |
+
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
2782 |
+
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
2783 |
+
"dev": true
|
2784 |
+
},
|
2785 |
+
"uuid": {
|
2786 |
+
"version": "3.2.1",
|
2787 |
+
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz",
|
2788 |
+
"integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==",
|
2789 |
+
"dev": true
|
2790 |
+
},
|
2791 |
+
"validate-npm-package-license": {
|
2792 |
+
"version": "3.0.3",
|
2793 |
+
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz",
|
2794 |
+
"integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==",
|
2795 |
+
"dev": true,
|
2796 |
+
"requires": {
|
2797 |
+
"spdx-correct": "3.0.0",
|
2798 |
+
"spdx-expression-parse": "3.0.0"
|
2799 |
+
}
|
2800 |
+
},
|
2801 |
+
"verror": {
|
2802 |
+
"version": "1.10.0",
|
2803 |
+
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
|
2804 |
+
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
|
2805 |
+
"dev": true,
|
2806 |
+
"requires": {
|
2807 |
+
"assert-plus": "1.0.0",
|
2808 |
+
"core-util-is": "1.0.2",
|
2809 |
+
"extsprintf": "1.3.0"
|
2810 |
+
},
|
2811 |
+
"dependencies": {
|
2812 |
+
"assert-plus": {
|
2813 |
+
"version": "1.0.0",
|
2814 |
+
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
2815 |
+
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
2816 |
+
"dev": true
|
2817 |
+
}
|
2818 |
+
}
|
2819 |
+
},
|
2820 |
+
"websocket-driver": {
|
2821 |
+
"version": "0.7.0",
|
2822 |
+
"resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz",
|
2823 |
+
"integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=",
|
2824 |
+
"dev": true,
|
2825 |
+
"requires": {
|
2826 |
+
"http-parser-js": "0.4.12",
|
2827 |
+
"websocket-extensions": "0.1.3"
|
2828 |
+
}
|
2829 |
+
},
|
2830 |
+
"websocket-extensions": {
|
2831 |
+
"version": "0.1.3",
|
2832 |
+
"resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz",
|
2833 |
+
"integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==",
|
2834 |
+
"dev": true
|
2835 |
+
},
|
2836 |
+
"which": {
|
2837 |
+
"version": "1.2.14",
|
2838 |
+
"resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz",
|
2839 |
+
"integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=",
|
2840 |
+
"dev": true,
|
2841 |
+
"requires": {
|
2842 |
+
"isexe": "2.0.0"
|
2843 |
+
}
|
2844 |
+
},
|
2845 |
+
"which-module": {
|
2846 |
+
"version": "1.0.0",
|
2847 |
+
"resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
|
2848 |
+
"integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
|
2849 |
+
"dev": true
|
2850 |
+
},
|
2851 |
+
"wide-align": {
|
2852 |
+
"version": "1.1.2",
|
2853 |
+
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
|
2854 |
+
"integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
|
2855 |
+
"dev": true,
|
2856 |
+
"requires": {
|
2857 |
+
"string-width": "1.0.2"
|
2858 |
+
}
|
2859 |
+
},
|
2860 |
+
"wrap-ansi": {
|
2861 |
+
"version": "2.1.0",
|
2862 |
+
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
|
2863 |
+
"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
|
2864 |
+
"dev": true,
|
2865 |
+
"requires": {
|
2866 |
+
"string-width": "1.0.2",
|
2867 |
+
"strip-ansi": "3.0.1"
|
2868 |
+
}
|
2869 |
+
},
|
2870 |
+
"wrappy": {
|
2871 |
+
"version": "1.0.2",
|
2872 |
+
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
2873 |
+
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
2874 |
+
"dev": true
|
2875 |
+
},
|
2876 |
+
"xtend": {
|
2877 |
+
"version": "4.0.1",
|
2878 |
+
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
|
2879 |
+
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
|
2880 |
+
"dev": true
|
2881 |
+
},
|
2882 |
+
"y18n": {
|
2883 |
+
"version": "3.2.1",
|
2884 |
+
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
2885 |
+
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
|
2886 |
+
"dev": true
|
2887 |
+
},
|
2888 |
+
"yallist": {
|
2889 |
+
"version": "2.1.2",
|
2890 |
+
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
|
2891 |
+
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
|
2892 |
+
"dev": true
|
2893 |
+
},
|
2894 |
+
"yargs": {
|
2895 |
+
"version": "7.1.0",
|
2896 |
+
"resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
|
2897 |
+
"integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
|
2898 |
+
"dev": true,
|
2899 |
+
"requires": {
|
2900 |
+
"camelcase": "3.0.0",
|
2901 |
+
"cliui": "3.2.0",
|
2902 |
+
"decamelize": "1.2.0",
|
2903 |
+
"get-caller-file": "1.0.2",
|
2904 |
+
"os-locale": "1.4.0",
|
2905 |
+
"read-pkg-up": "1.0.1",
|
2906 |
+
"require-directory": "2.1.1",
|
2907 |
+
"require-main-filename": "1.0.1",
|
2908 |
+
"set-blocking": "2.0.0",
|
2909 |
+
"string-width": "1.0.2",
|
2910 |
+
"which-module": "1.0.0",
|
2911 |
+
"y18n": "3.2.1",
|
2912 |
+
"yargs-parser": "5.0.0"
|
2913 |
+
},
|
2914 |
+
"dependencies": {
|
2915 |
+
"camelcase": {
|
2916 |
+
"version": "3.0.0",
|
2917 |
+
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
|
2918 |
+
"integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
|
2919 |
+
"dev": true
|
2920 |
+
}
|
2921 |
+
}
|
2922 |
+
},
|
2923 |
+
"yargs-parser": {
|
2924 |
+
"version": "5.0.0",
|
2925 |
+
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
|
2926 |
+
"integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
|
2927 |
+
"dev": true,
|
2928 |
+
"requires": {
|
2929 |
+
"camelcase": "3.0.0"
|
2930 |
+
},
|
2931 |
+
"dependencies": {
|
2932 |
+
"camelcase": {
|
2933 |
+
"version": "3.0.0",
|
2934 |
+
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
|
2935 |
+
"integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
|
2936 |
+
"dev": true
|
2937 |
+
}
|
2938 |
+
}
|
2939 |
+
}
|
2940 |
+
}
|
2941 |
+
}
|
package.json
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "simple-lightbox",
|
3 |
+
"version": "2.7.1",
|
4 |
+
"title": "Simple Lightbox",
|
5 |
+
"description": "The highly-customizable lightbox for WordPress",
|
6 |
+
"author": "Archetyped <support@archetyped.com>",
|
7 |
+
"license": "GPLv2",
|
8 |
+
"private": true,
|
9 |
+
"devDependencies": {
|
10 |
+
"grunt": "^1.0.1",
|
11 |
+
"grunt-contrib-jshint": "^1.0.0",
|
12 |
+
"grunt-contrib-uglify": "^3.3.0",
|
13 |
+
"grunt-contrib-watch": "^1.0.0",
|
14 |
+
"grunt-phplint": "0.1.0",
|
15 |
+
"grunt-sass": "^2.1.0",
|
16 |
+
"jshint-stylish": "^2.2.1",
|
17 |
+
"load-grunt-tasks": "^3.5.2",
|
18 |
+
"time-grunt": "^1.4.0"
|
19 |
+
}
|
20 |
+
}
|
readme.txt
CHANGED
@@ -3,8 +3,9 @@ Contributors: Archetyped
|
|
3 |
Donate link: http://gum.co/slb-donate
|
4 |
License: GPLv2
|
5 |
Tags: lightbox, gallery, photography, images, theme, template, style
|
6 |
-
Requires at least:
|
7 |
-
Tested up to: 3
|
|
|
8 |
Stable tag: trunk
|
9 |
|
10 |
The highly customizable lightbox for WordPress
|
@@ -13,6 +14,7 @@ The highly customizable lightbox for WordPress
|
|
13 |
Simple Lightbox is a very simple and customizable lightbox that is easy to add to your WordPress website.
|
14 |
|
15 |
#### Features
|
|
|
16 |
Options for customizing the lightbox behavior are located in the **Appearance > Lightbox** admin menu (or just click the **Settings** link below the plugin's name when viewing the list of installed plugins)
|
17 |
|
18 |
* Automatically activate links (no manual coding required)
|
@@ -30,7 +32,8 @@ Options for customizing the lightbox behavior are located in the **Appearance >
|
|
30 |
* Group image links by Post (separate slideshow for each post on page)
|
31 |
|
32 |
#### Usage
|
33 |
-
|
|
|
34 |
|
35 |
**That's it! The image will be displayed in a lightbox automatically.**
|
36 |
|
@@ -38,12 +41,13 @@ Options for customizing the lightbox behavior are located in the **Appearance >
|
|
38 |
|
39 |
== Installation ==
|
40 |
|
41 |
-
1.
|
42 |
-
1.
|
43 |
|
44 |
== Upgrade Notice ==
|
45 |
|
46 |
-
|
|
|
47 |
|
48 |
== Frequently Asked Questions ==
|
49 |
|
@@ -51,152 +55,26 @@ Get more information on [Simple Lightbox's official page](http://archetyped.com/
|
|
51 |
|
52 |
== Screenshots ==
|
53 |
|
54 |
-
1.
|
55 |
-
2.
|
56 |
-
3.
|
57 |
|
58 |
== Changelog ==
|
59 |
|
60 |
-
= 2.
|
61 |
-
|
62 |
-
*
|
63 |
-
*
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
*
|
68 |
-
*
|
69 |
-
*
|
70 |
-
|
71 |
-
|
72 |
-
*
|
73 |
-
* Add:
|
74 |
-
*
|
75 |
-
|
76 |
-
|
77 |
-
* Optimize: WP 3.3 compatibility
|
78 |
-
* Optimize: Improved compatibility with URI case-sensitivity
|
79 |
-
* Optimize: Activation processing
|
80 |
-
* Optimize: Image grouping
|
81 |
-
* Optimize: Image metadata loading performance
|
82 |
-
* Optimize: File loading
|
83 |
-
* Optimize: Improved safeguards against interference by bugs in other plugins
|
84 |
-
* Optimize: Link processing performance
|
85 |
-
* Optimize: Lightbox styling isolated from site styles
|
86 |
-
* Optimize: Improved link processing performance
|
87 |
-
* Optimize: Improved image metadata support
|
88 |
-
* Optimize: Improved support for HTTP/HTTPS requests
|
89 |
-
* Fix: SLB is not defined in JS (Jezz Hands)
|
90 |
-
* Fix: Boolean case-sensitivity (78 Truths)
|
91 |
-
* Fix: YouTube embed using iFrame overlaps lightbox (Elena in Hiding)
|
92 |
-
* Fix: Issue when scanning links without valid URLs (McCloskey Iteration)
|
93 |
-
* Fix: Image activation is case-sensitive (Sensitive Tanya)
|
94 |
-
* Fix: Visible lightbox overlay edges when image larger than browser window (Chibi Overlay)
|
95 |
-
* Fix: Options availability for some users
|
96 |
-
* Fix: Inconsistent loading of image metadata
|
97 |
-
* Fix: Links not fully processed when group is set manually
|
98 |
-
|
99 |
-
= 1.5.6 =
|
100 |
-
* Add: Display image description in lightbox (with HTML support)
|
101 |
-
* Add: Support for W3 Total Cache plugin
|
102 |
-
* Add: Initial support for NextGEN galleries
|
103 |
-
* Update: **Important:** [System Requirements](http://wordpress.org/about/requirements/) aligned with WP 3.2.1
|
104 |
-
* Optimize: Improved support for small images in default template
|
105 |
-
* Optimize: Support for non-English text in user options
|
106 |
-
* Optimize: Improved IE compatibility
|
107 |
-
* Optimize: Improved data handling
|
108 |
-
* Optimize: Skin loading performance
|
109 |
-
* Optimize: Skin CSS Cleanup
|
110 |
-
* Optimize: Caption support for galleries
|
111 |
-
* Optimize: Options code cleanup (Juga Sweep)
|
112 |
-
* Fix: User-defined UI text not used (Ivan gets Even (cooler))
|
113 |
-
* Fix: Options reset after update (KRazy Donna)
|
114 |
-
|
115 |
-
= 1.5.5.1 =
|
116 |
-
* Fix: Disabled links not being disabled (Disabling Sascha)
|
117 |
-
|
118 |
-
= 1.5.5 =
|
119 |
-
* Add: Distinct link activation (will not affect other lightboxes)
|
120 |
-
* Add: Backwards compatibility with legacy lightbox links (optional)
|
121 |
-
* Add: Support for WordPress 3.2
|
122 |
-
* Add: Support for links added after page load (e.g. via AJAX, etc.)
|
123 |
-
* Add: Admin option to enable/disable attachment links
|
124 |
-
* Add: Support for image attachment links
|
125 |
-
* Update: Options management overhaul
|
126 |
-
* Update: Additional WordPress 3.2 support (Gallery)
|
127 |
-
* Update: Cache-management for enqueued files
|
128 |
-
* Update: Improved UI consistency
|
129 |
-
* Update: Improved compatibility for older versions of PHP
|
130 |
-
* Update: Internal optimizations
|
131 |
-
* Update: Improved URL handling
|
132 |
-
* Fix: Improved options migration from old versions (Hutchison Migration)
|
133 |
-
* Fix: XHTML Validation (Hajo Validation)
|
134 |
-
|
135 |
-
= 1.5.4 =
|
136 |
-
* Add: Optional Link validation
|
137 |
-
* Add: Keyboard Navigation
|
138 |
-
* Add: Option to enable/disable image caption
|
139 |
-
* Add: `rel` attribute supported again
|
140 |
-
* Add: Use `slb_off` in link's `rel` attribute to disable automatic activation for link
|
141 |
-
* Fix: HTTPS compatibility (Jürgen Protocol)
|
142 |
-
* Fix: Enabling SLB on Pages issue
|
143 |
-
* Fix: Zmanu is_single
|
144 |
-
* Fix: Image order is sometimes incorrect
|
145 |
-
* Optimize: Filter double clicks
|
146 |
-
* Optimize: Separate options to enable/disable SLB on Posts and Pages
|
147 |
-
* Optimize: Better grouping support
|
148 |
-
|
149 |
-
= 1.5.3 =
|
150 |
-
* Fix: Caption may not display under certain circumstances (Caption Erin)
|
151 |
-
* Fix: Images not grouped when "separate by post" option is activated (Logical Ross)
|
152 |
-
* Update: Lightbox will not be activated for links that already have `rel` attribute set
|
153 |
-
|
154 |
-
= 1.5.2 =
|
155 |
-
* Fix: Slideshow loops out of control (Mirage of Wallentin)
|
156 |
-
* Fix: Lightbox fails when group by posts disabled (Lange Find)
|
157 |
-
* Add: Option to use the image's URI as caption when link title not set (Under UI options)
|
158 |
-
|
159 |
-
= 1.5.1 =
|
160 |
-
* Add: WP Gallery support
|
161 |
-
* Fix: Navigation hidden when only one image
|
162 |
-
* Fix: Use user-defined UI text
|
163 |
-
|
164 |
-
= 1.5 =
|
165 |
-
* Add: Theme support
|
166 |
-
* Optimize: Javascript cleanup and file size reductions
|
167 |
-
* Optimize: CSS cleanup
|
168 |
-
|
169 |
-
= 1.4 =
|
170 |
-
* Update: Integrated with jQuery
|
171 |
-
* Optimize: Javascript filesize 9x smaller
|
172 |
-
* Add: Close lightbox by clicking to left/right outside of image (an oft-requested feature)
|
173 |
-
|
174 |
-
= 1.3.2 =
|
175 |
-
* Add: Option to enable/disable lightbox resizing animation (thanks Maria!)
|
176 |
-
|
177 |
-
= 1.3.1 =
|
178 |
-
* Update: Utilities code (internal)
|
179 |
-
|
180 |
-
= 1.3 =
|
181 |
-
* Add: Customizable UI label text (close, next, and prev button images can be replaced in `images` directory)
|
182 |
-
* Add: Group image links by Post (separate slideshow for each post)
|
183 |
-
* Add: Reset settings link on plugin listings page
|
184 |
-
* Optimize: Organized settings page
|
185 |
-
|
186 |
-
= 1.2.1 =
|
187 |
-
* Fixed: Image title given higher precedence than Image alt (more compatible w/WP workflow)
|
188 |
-
|
189 |
-
= 1.2 =
|
190 |
-
* Added: Option to group automatically activated links
|
191 |
-
* Optimized: Lightbox caption retrieval
|
192 |
-
|
193 |
-
= 1.1 =
|
194 |
-
* Added: Enable/disable lightbox functionality by page type (Home, Pages/Posts, Archive, etc.)
|
195 |
-
* Added: Automatically activate lightbox functionality for image links
|
196 |
-
* Added: Link to settings menu on plugin listing page
|
197 |
-
* Optimized: Options menu field building
|
198 |
-
* Optimized: Loading of default values for plugin options
|
199 |
-
* Optimized: General code optimizations
|
200 |
-
|
201 |
-
= 1.0 =
|
202 |
-
* Initial release
|
3 |
Donate link: http://gum.co/slb-donate
|
4 |
License: GPLv2
|
5 |
Tags: lightbox, gallery, photography, images, theme, template, style
|
6 |
+
Requires at least: 5.2
|
7 |
+
Tested up to: 5.3
|
8 |
+
Requires PHP: 5.6.20
|
9 |
Stable tag: trunk
|
10 |
|
11 |
The highly customizable lightbox for WordPress
|
14 |
Simple Lightbox is a very simple and customizable lightbox that is easy to add to your WordPress website.
|
15 |
|
16 |
#### Features
|
17 |
+
|
18 |
Options for customizing the lightbox behavior are located in the **Appearance > Lightbox** admin menu (or just click the **Settings** link below the plugin's name when viewing the list of installed plugins)
|
19 |
|
20 |
* Automatically activate links (no manual coding required)
|
32 |
* Group image links by Post (separate slideshow for each post on page)
|
33 |
|
34 |
#### Usage
|
35 |
+
|
36 |
+
1. Insert links to images/image attachments into your posts/pages
|
37 |
|
38 |
**That's it! The image will be displayed in a lightbox automatically.**
|
39 |
|
41 |
|
42 |
== Installation ==
|
43 |
|
44 |
+
1. Install and activate SLB
|
45 |
+
1. Verify that your site's theme uses the `wp_head()`, `wp_footer()`, & `the_content()` template tags (standard in any professional theme)
|
46 |
|
47 |
== Upgrade Notice ==
|
48 |
|
49 |
+
= 2.7.0 =
|
50 |
+
Fixes & improvements. PHP 5.4+ Required.
|
51 |
|
52 |
== Frequently Asked Questions ==
|
53 |
|
55 |
|
56 |
== Screenshots ==
|
57 |
|
58 |
+
1. Lightbox Customization Options
|
59 |
+
2. Light Theme
|
60 |
+
3. Dark Theme
|
61 |
|
62 |
== Changelog ==
|
63 |
|
64 |
+
= 2.7.1 =
|
65 |
+
|
66 |
+
* Update: Confirm compatibility with WordPress 5.0+
|
67 |
+
* Optimize: Improved support for captions generated by Block Editor.
|
68 |
+
|
69 |
+
= 2.7.0 =
|
70 |
+
|
71 |
+
* Fix: Remove reference to deprecated `screen_icon()` function (The Icon of Finnegan Island)
|
72 |
+
* Fix: Reset settings link initializes plugin delete confirmation
|
73 |
+
* Add: Validate requirements before initialization.
|
74 |
+
* Optimize: PHP 7.2+ Compatibility
|
75 |
+
* Optimize: Internal code optimizations
|
76 |
+
* Themes
|
77 |
+
* Add: RTL Support
|
78 |
+
* Update: Load font locally
|
79 |
+
|
80 |
+
[See full changelog](https://github.com/archetyped/simple-lightbox/releases)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template-tags/item/js/dev/tag.item.js
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
if ( !!window.SLB && SLB.has_child('View.extend_template_tag_handler') ) {(function() {
|
2 |
+
SLB.View.extend_template_tag_handler('item', {
|
3 |
+
/**
|
4 |
+
* Render Item tag
|
5 |
+
* @param obj item Content Item
|
6 |
+
* @param obj tag Tag instance
|
7 |
+
* @param obj dfr Promise to be resolved when tag is rendered
|
8 |
+
*/
|
9 |
+
render: function(item, tag, dfr) {
|
10 |
+
// Build method name
|
11 |
+
var m = 'get_' + tag.get_prop();
|
12 |
+
// Get data
|
13 |
+
var ret = ( this.util.is_method(item, m) ) ? item[m]() : item.get_attribute(tag.get_prop(), '');
|
14 |
+
// Handle response
|
15 |
+
if ( this.util.is_promise(ret) ) {
|
16 |
+
ret.done(function(output) {
|
17 |
+
dfr.resolve(output);
|
18 |
+
});
|
19 |
+
} else {
|
20 |
+
dfr.resolve(ret);
|
21 |
+
}
|
22 |
+
return dfr.promise();
|
23 |
+
}
|
24 |
+
});
|
25 |
+
})();
|
26 |
+
}
|
template-tags/item/js/prod/tag.item.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
window.SLB&&SLB.has_child("View.extend_template_tag_handler")&&!function(){SLB.View.extend_template_tag_handler("item",{render:function(item,tag,dfr){var m="get_"+tag.get_prop(),ret=this.util.is_method(item,m)?item[m]():item.get_attribute(tag.get_prop(),"");return this.util.is_promise(ret)?ret.done(function(output){dfr.resolve(output)}):dfr.resolve(ret),dfr.promise()}})}();
|
template-tags/item/tag.item.js
DELETED
@@ -1,17 +0,0 @@
|
|
1 |
-
(function($) {
|
2 |
-
return {
|
3 |
-
render: function(item, tag) {
|
4 |
-
var dfr = $.Deferred();
|
5 |
-
var m = 'get_' + tag.get_prop();
|
6 |
-
var ret = ( this.util.is_method(item, m) ) ? item[m]() : item.get_attribute(tag.get_prop(), '');
|
7 |
-
if ( this.util.is_promise(ret) ) {
|
8 |
-
ret.done(function(output) {
|
9 |
-
dfr.resolve(output);
|
10 |
-
});
|
11 |
-
} else {
|
12 |
-
dfr.resolve(ret);
|
13 |
-
}
|
14 |
-
return dfr.promise();
|
15 |
-
}
|
16 |
-
}
|
17 |
-
})(jQuery);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template-tags/ui/js/dev/tag.ui.js
ADDED
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
if ( !!window.SLB && SLB.has_child('View.extend_template_tag_handler') ) {(function() {
|
2 |
+
SLB.View.extend_template_tag_handler('ui', {
|
3 |
+
_hooks : function() {
|
4 |
+
this.on('dom_init', function(ev) {
|
5 |
+
this.call_attribute('events_init', ev);
|
6 |
+
});
|
7 |
+
},
|
8 |
+
events_init: function(ev) {
|
9 |
+
var v = ev.data.template.get_theme().get_viewer();
|
10 |
+
var thm = v.get_theme();
|
11 |
+
// Add event handlers
|
12 |
+
v.on('events-complete', function(ev, v) {
|
13 |
+
// Register event handlers
|
14 |
+
|
15 |
+
/* Close */
|
16 |
+
|
17 |
+
// Close button
|
18 |
+
thm.dom_get_tag('ui', 'close').click(function() {
|
19 |
+
return v.close();
|
20 |
+
});
|
21 |
+
|
22 |
+
/* Navigation */
|
23 |
+
|
24 |
+
thm.dom_get_tag('ui', 'nav_next').click(function() {
|
25 |
+
v.item_next();
|
26 |
+
});
|
27 |
+
thm.dom_get_tag('ui', 'nav_prev').click(function() {
|
28 |
+
v.item_prev();
|
29 |
+
});
|
30 |
+
|
31 |
+
/* Slideshow */
|
32 |
+
|
33 |
+
thm.dom_get_tag('ui', 'slideshow_control').click(function() {
|
34 |
+
v.slideshow_toggle();
|
35 |
+
});
|
36 |
+
});
|
37 |
+
|
38 |
+
v.on('slideshow-toggle', function(ev, v) {
|
39 |
+
// Update slideshow control tag
|
40 |
+
var tags = thm.get_tags('ui', 'slideshow_control');
|
41 |
+
if ( tags.length ) {
|
42 |
+
// Renderer
|
43 |
+
var render_tag = function(tag) {
|
44 |
+
tag.render(v.get_item()).done(function(r) {
|
45 |
+
r.tag.dom_get().html(r.output);
|
46 |
+
});
|
47 |
+
};
|
48 |
+
// Process tags
|
49 |
+
for ( var x = 0; x < tags.length; x++ ) {
|
50 |
+
render_tag(tags[x]);
|
51 |
+
}
|
52 |
+
}
|
53 |
+
});
|
54 |
+
},
|
55 |
+
render: function(item, tag, dfr) {
|
56 |
+
// Process content
|
57 |
+
var ret = this.handle_prop(tag.get_prop(), item, tag);
|
58 |
+
if ( this.util.is_promise(ret) ) {
|
59 |
+
ret.done(function(output) {
|
60 |
+
dfr.resolve(output);
|
61 |
+
});
|
62 |
+
} else {
|
63 |
+
dfr.resolve(ret);
|
64 |
+
}
|
65 |
+
return dfr.promise();
|
66 |
+
},
|
67 |
+
props: {
|
68 |
+
'slideshow_control': function(item) {
|
69 |
+
// Get slideshow status
|
70 |
+
var v = item.get_viewer();
|
71 |
+
var prop = ( v.slideshow_active() ) ? 'slideshow_stop' : 'slideshow_start';
|
72 |
+
return v.get_label(prop);
|
73 |
+
},
|
74 |
+
'group_status': function(item) {
|
75 |
+
// Handle single items
|
76 |
+
if ( item.get_group().is_single() ) {
|
77 |
+
return '';
|
78 |
+
}
|
79 |
+
// Handle groups with multiple items
|
80 |
+
var out = item.get_viewer().get_label('group_status');
|
81 |
+
var key,
|
82 |
+
ph,
|
83 |
+
delim = '%',
|
84 |
+
handlers = {
|
85 |
+
current: function() {
|
86 |
+
return item.get_group(true).get_pos() + 1;
|
87 |
+
},
|
88 |
+
total: function() {
|
89 |
+
return item.get_group().get_size();
|
90 |
+
}
|
91 |
+
};
|
92 |
+
// Parse placeholders
|
93 |
+
for ( key in handlers ) {
|
94 |
+
// Build placeholder
|
95 |
+
ph = delim + key + delim;
|
96 |
+
// Replace placeholder
|
97 |
+
if ( -1 !== out.indexOf(ph) ) {
|
98 |
+
out = out.replace(new RegExp(ph, 'ig'), handlers[key]());
|
99 |
+
}
|
100 |
+
}
|
101 |
+
return out;
|
102 |
+
}
|
103 |
+
}
|
104 |
+
});
|
105 |
+
})();}
|
template-tags/ui/js/prod/tag.ui.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
window.SLB&&SLB.has_child("View.extend_template_tag_handler")&&!function(){SLB.View.extend_template_tag_handler("ui",{_hooks:function(){this.on("dom_init",function(ev){this.call_attribute("events_init",ev)})},events_init:function(ev){var v=ev.data.template.get_theme().get_viewer(),thm=v.get_theme();v.on("events-complete",function(ev,v){thm.dom_get_tag("ui","close").click(function(){return v.close()}),thm.dom_get_tag("ui","nav_next").click(function(){v.item_next()}),thm.dom_get_tag("ui","nav_prev").click(function(){v.item_prev()}),thm.dom_get_tag("ui","slideshow_control").click(function(){v.slideshow_toggle()})}),v.on("slideshow-toggle",function(ev,v){var tags=thm.get_tags("ui","slideshow_control");if(tags.length)for(var render_tag=function(tag){tag.render(v.get_item()).done(function(r){r.tag.dom_get().html(r.output)})},x=0;x<tags.length;x++)render_tag(tags[x])})},render:function(item,tag,dfr){var ret=this.handle_prop(tag.get_prop(),item,tag);return this.util.is_promise(ret)?ret.done(function(output){dfr.resolve(output)}):dfr.resolve(ret),dfr.promise()},props:{slideshow_control:function(item){var v=item.get_viewer(),prop=v.slideshow_active()?"slideshow_stop":"slideshow_start";return v.get_label(prop)},group_status:function(item){if(item.get_group().is_single())return"";var key,ph,out=item.get_viewer().get_label("group_status"),delim="%",handlers={current:function(){return item.get_group(!0).get_pos()+1},total:function(){return item.get_group().get_size()}};for(key in handlers)ph=delim+key+delim,-1!==out.indexOf(ph)&&(out=out.replace(new RegExp(ph,"ig"),handlers[key]()));return out}}})}();
|
template-tags/ui/tag.ui.js
DELETED
@@ -1,108 +0,0 @@
|
|
1 |
-
(function($) {
|
2 |
-
return {
|
3 |
-
init: function(item, tag, v) {
|
4 |
-
//Add event handlers
|
5 |
-
v.on('events-complete', function(ev, v) {
|
6 |
-
//Register event handlers
|
7 |
-
|
8 |
-
/* Close */
|
9 |
-
|
10 |
-
var close = function() {
|
11 |
-
return v.close();
|
12 |
-
};
|
13 |
-
//Close button
|
14 |
-
v.get_theme().dom_get_tag('ui', 'close').click(close);
|
15 |
-
|
16 |
-
/* Navigation */
|
17 |
-
|
18 |
-
var nav_next = function() {
|
19 |
-
v.item_next();
|
20 |
-
};
|
21 |
-
|
22 |
-
var nav_prev = function() {
|
23 |
-
v.item_prev();
|
24 |
-
};
|
25 |
-
|
26 |
-
v.get_theme().dom_get_tag('ui', 'nav_next').click(nav_next);
|
27 |
-
v.get_theme().dom_get_tag('ui', 'nav_prev').click(nav_prev);
|
28 |
-
|
29 |
-
/* Slideshow */
|
30 |
-
|
31 |
-
var slideshow_control = function() {
|
32 |
-
v.slideshow_toggle();
|
33 |
-
};
|
34 |
-
|
35 |
-
v.get_theme().dom_get_tag('ui', 'slideshow_control').click(slideshow_control);
|
36 |
-
});
|
37 |
-
|
38 |
-
v.on('slideshow-toggle', function(ev, v) {
|
39 |
-
//Update slideshow control tag
|
40 |
-
var tags = v.get_theme().get_tags('ui', 'slideshow_control');
|
41 |
-
if ( tags.length ) {
|
42 |
-
for ( var x = 0; x < tags.length; x++ ) {
|
43 |
-
tags[x].render(v.get_item()).done(function(r) {
|
44 |
-
r.tag.dom_get().html(r.output);
|
45 |
-
});
|
46 |
-
}
|
47 |
-
}
|
48 |
-
});
|
49 |
-
},
|
50 |
-
render: function(item, tag) {
|
51 |
-
//Initialize event handlers (once per viewer)
|
52 |
-
var v = item.get_viewer();
|
53 |
-
var st = ['events-init', tag.get_ns(), tag.get_name()].join('_');
|
54 |
-
var fmt = function(output) {
|
55 |
-
return output;
|
56 |
-
};
|
57 |
-
if ( !v.get_status(st) ) {
|
58 |
-
v.set_status(st);
|
59 |
-
this.call_attribute('init', item, tag, v);
|
60 |
-
}
|
61 |
-
//Process content
|
62 |
-
var dfr = $.Deferred();
|
63 |
-
var ret = this.handle_prop(tag.get_prop(), item, tag);
|
64 |
-
if ( this.util.is_promise(ret) ) {
|
65 |
-
ret.done(function(output) {
|
66 |
-
dfr.resolve(fmt(output));
|
67 |
-
});
|
68 |
-
} else {
|
69 |
-
dfr.resolve(fmt(ret));
|
70 |
-
}
|
71 |
-
return dfr.promise();
|
72 |
-
},
|
73 |
-
props: {
|
74 |
-
'slideshow_control': function(item, tag) {
|
75 |
-
//Get slideshow status
|
76 |
-
var prop = ( item.get_viewer().slideshow_active() ) ? 'slideshow_stop' : 'slideshow_start';
|
77 |
-
return item.get_viewer().get_label(prop);
|
78 |
-
},
|
79 |
-
'group_status': function(item, tag) {
|
80 |
-
//Handle single items
|
81 |
-
if ( item.get_group().is_single() ) {
|
82 |
-
return '';
|
83 |
-
}
|
84 |
-
//Handle groups with multiple items
|
85 |
-
var out = item.get_viewer().get_label('group_status');
|
86 |
-
var key,
|
87 |
-
ph,
|
88 |
-
delim = '%',
|
89 |
-
handlers = {
|
90 |
-
current: function() {
|
91 |
-
return item.get_group(true).get_pos() + 1;
|
92 |
-
},
|
93 |
-
total: function() {
|
94 |
-
return item.get_group().get_size();
|
95 |
-
}
|
96 |
-
};
|
97 |
-
//Parse placeholders
|
98 |
-
for ( key in handlers ) {
|
99 |
-
ph = delim + key + delim;
|
100 |
-
if ( out.indexOf(ph) != -1 ) {
|
101 |
-
out = out.replace(ph, handlers[key]());
|
102 |
-
}
|
103 |
-
}
|
104 |
-
return out;
|
105 |
-
}
|
106 |
-
}
|
107 |
-
}
|
108 |
-
})(jQuery);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
themes/baseline/css/style.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
#slb_viewer_wrap .slb_theme_slb_baseline .slb_viewer_layout,#slb_viewer_wrap .slb_theme_slb_baseline .slb_container{box-sizing:border-box}#slb_viewer_wrap .slb_theme_slb_baseline{position:absolute;top:0;left:0;width:100%;z-index:99999;text-align:center;line-height:0;color:#000;font-family:arial, verdana, sans-serif;font-size:12px}#slb_viewer_wrap .slb_theme_slb_baseline *{margin:0;padding:0;line-height:1.4em;text-align:left;vertical-align:baseline;white-space:normal;outline:none;border:0px;background:none;opacity:1;width:auto;height:auto;position:static;float:none;clear:none}[dir="rtl"] #slb_viewer_wrap .slb_theme_slb_baseline *{text-align:right}#slb_viewer_wrap .slb_theme_slb_baseline a img{border:none}#slb_viewer_wrap .slb_theme_slb_baseline .slb_viewer_layout{z-index:2;position:absolute;width:100%;text-align:center}#slb_viewer_wrap .slb_theme_slb_baseline .slb_viewer_overlay{position:fixed;top:0;left:0;z-index:1;min-height:105%;min-width:100%;background-color:#000}#slb_viewer_wrap .slb_theme_slb_baseline .slb_container{position:relative;display:inline-block;background-color:#fff;margin:0 auto;padding:16px}#slb_viewer_wrap .slb_theme_slb_baseline .slb_loading{background:url("../images/loading.gif") center center no-repeat;position:absolute;left:0%;top:0;width:100%;height:100%;min-width:31px;min-height:31px;text-align:center;line-height:0;display:none}#slb_viewer_wrap .slb_theme_slb_baseline .slb_template_tag_ui{cursor:pointer}#slb_viewer_wrap .slb_theme_slb_baseline .slb_content{position:relative}#slb_viewer_wrap .slb_theme_slb_baseline .slb_details{margin:0 auto;text-align:left}#slb_viewer_wrap .slb_theme_slb_baseline .slb_details .inner{display:table;width:100%}#slb_viewer_wrap .slb_theme_slb_baseline .slb_details .slb_data{display:table-caption}#slb_viewer_wrap .slb_theme_slb_baseline .slb_template_tag_item_content>*{width:100%;height:100%}#slb_viewer_wrap .slb_theme_slb_baseline.item_single .slb_group_status,#slb_viewer_wrap .slb_theme_slb_baseline.item_single .slb_nav,#slb_viewer_wrap .slb_theme_slb_baseline.item_single .slb_slideshow{display:none}#slb_viewer_wrap .slb_theme_slb_baseline.loading .slb_loading{display:block}#slb_viewer_wrap .slb_theme_slb_baseline.loading .slb_template_tag_ui{opacity:0}@media screen and (max-width: 480px){#slb_viewer_wrap .slb_theme_slb_baseline .slb_theme_slb_baseline,#slb_viewer_wrap .slb_theme_slb_baseline .slb_viewer_layout,#slb_viewer_wrap .slb_theme_slb_baseline .slb_container{min-height:100%;min-width:320px;width:100%}#slb_viewer_wrap .slb_theme_slb_baseline .slb_viewer_layout{display:block}#slb_viewer_wrap .slb_theme_slb_baseline .slb_container{max-width:100%;margin:0;padding:5px;position:absolute;top:0;left:0}#slb_viewer_wrap .slb_theme_slb_baseline .slb_container .slb_content img,#slb_viewer_wrap .slb_theme_slb_baseline .slb_container .slb_content iframe,#slb_viewer_wrap .slb_theme_slb_baseline .slb_container .slb_content object,#slb_viewer_wrap .slb_theme_slb_baseline .slb_container .slb_content .slb_inner{max-width:100%}#slb_viewer_wrap .slb_theme_slb_baseline .slb_container .slb_content img{height:auto}}
|
themes/baseline/images/loading.gif
ADDED
Binary file
|
themes/baseline/js/dev/client.js
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
if ( !!window.SLB && SLB.has_child('View.extend_theme') ) {(function() {
|
2 |
+
SLB.View.extend_theme('slb_baseline', {
|
3 |
+
'breakpoints': {
|
4 |
+
'small': 480,
|
5 |
+
'large': 1024
|
6 |
+
},
|
7 |
+
/**
|
8 |
+
* Theme offsets
|
9 |
+
* Reports additional space required for theme UI
|
10 |
+
* @return obj Offset width/height values
|
11 |
+
*/
|
12 |
+
'offset': function() {
|
13 |
+
var o;
|
14 |
+
if ( document.documentElement.clientWidth > this.get_breakpoint('small') ) {
|
15 |
+
o = {'width': 32, 'height': 55};
|
16 |
+
} else {
|
17 |
+
o = {'width': 0, 'height': 0};
|
18 |
+
}
|
19 |
+
return o;
|
20 |
+
},
|
21 |
+
/**
|
22 |
+
* Theme margins
|
23 |
+
* Reports additional margins used for positioning viewer
|
24 |
+
* @return obj Margin width/height values
|
25 |
+
*/
|
26 |
+
'margin': function() {
|
27 |
+
var m;
|
28 |
+
if ( document.documentElement.clientWidth > this.get_breakpoint('small') ) {
|
29 |
+
m = {'height': 50, 'width': 20};
|
30 |
+
} else {
|
31 |
+
m = {'height': 0, 'width': 0};
|
32 |
+
}
|
33 |
+
return m;
|
34 |
+
}
|
35 |
+
});
|
36 |
+
})();
|
37 |
+
}
|
themes/baseline/js/prod/client.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
window.SLB&&SLB.has_child("View.extend_theme")&&!function(){SLB.View.extend_theme("slb_baseline",{breakpoints:{small:480,large:1024},offset:function(){var o;return o=document.documentElement.clientWidth>this.get_breakpoint("small")?{width:32,height:55}:{width:0,height:0}},margin:function(){var m;return m=document.documentElement.clientWidth>this.get_breakpoint("small")?{height:50,width:20}:{height:0,width:0}}})}();
|
themes/{default → baseline}/layout.html
RENAMED
@@ -1,22 +1,22 @@
|
|
1 |
<div class="slb_container">
|
2 |
<div class="slb_content">
|
3 |
{{item.content}}
|
4 |
-
<
|
5 |
-
<
|
6 |
{{ui.nav_prev}}
|
7 |
-
</
|
8 |
-
<
|
9 |
{{ui.nav_next}}
|
10 |
-
</
|
11 |
-
</
|
12 |
-
<
|
13 |
-
<
|
14 |
{{ui.close}}
|
15 |
-
</
|
16 |
-
<
|
17 |
{{ui.slideshow_control}}
|
18 |
-
</
|
19 |
-
</
|
20 |
<div class="slb_loading">
|
21 |
{{ui.loading}}
|
22 |
</div>
|
@@ -31,11 +31,19 @@
|
|
31 |
<span class="slb_group_status">
|
32 |
{{ui.group_status}}
|
33 |
</span>
|
34 |
-
<
|
35 |
{{item.description}}
|
36 |
-
</
|
37 |
</div>
|
38 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
</div>
|
40 |
</div>
|
41 |
</div>
|
1 |
<div class="slb_container">
|
2 |
<div class="slb_content">
|
3 |
{{item.content}}
|
4 |
+
<div class="slb_nav">
|
5 |
+
<span class="slb_prev">
|
6 |
{{ui.nav_prev}}
|
7 |
+
</span>
|
8 |
+
<span class="slb_next">
|
9 |
{{ui.nav_next}}
|
10 |
+
</span>
|
11 |
+
</div>
|
12 |
+
<div class="slb_controls">
|
13 |
+
<span class="slb_close">
|
14 |
{{ui.close}}
|
15 |
+
</span>
|
16 |
+
<span class="slb_slideshow">
|
17 |
{{ui.slideshow_control}}
|
18 |
+
</span>
|
19 |
+
</div>
|
20 |
<div class="slb_loading">
|
21 |
{{ui.loading}}
|
22 |
</div>
|
31 |
<span class="slb_group_status">
|
32 |
{{ui.group_status}}
|
33 |
</span>
|
34 |
+
<div class="slb_data_desc">
|
35 |
{{item.description}}
|
36 |
+
</div>
|
37 |
</div>
|
38 |
</div>
|
39 |
+
<div class="slb_nav">
|
40 |
+
<span class="slb_prev">
|
41 |
+
{{ui.nav_prev}}
|
42 |
+
</span>
|
43 |
+
<span class="slb_next">
|
44 |
+
{{ui.nav_next}}
|
45 |
+
</span>
|
46 |
+
</div>
|
47 |
</div>
|
48 |
</div>
|
49 |
</div>
|
themes/baseline/sass/style.scss
ADDED
@@ -0,0 +1,176 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
//Imports
|
2 |
+
|
3 |
+
//Variables
|
4 |
+
|
5 |
+
//Mixins
|
6 |
+
|
7 |
+
%box-sizing-border-box {
|
8 |
+
box-sizing: border-box;
|
9 |
+
}
|
10 |
+
|
11 |
+
#slb_viewer_wrap {
|
12 |
+
.slb_theme_slb_baseline {
|
13 |
+
position: absolute;
|
14 |
+
top: 0;
|
15 |
+
left: 0;
|
16 |
+
width: 100%;
|
17 |
+
z-index: 99999;
|
18 |
+
text-align: center;
|
19 |
+
line-height: 0;
|
20 |
+
color:#000;
|
21 |
+
font: {
|
22 |
+
family: arial, verdana, sans-serif;
|
23 |
+
size: 12px;
|
24 |
+
}
|
25 |
+
|
26 |
+
//Reset
|
27 |
+
* {
|
28 |
+
margin: 0;
|
29 |
+
padding: 0;
|
30 |
+
line-height: 1.4em;
|
31 |
+
text-align: left;
|
32 |
+
vertical-align: baseline;
|
33 |
+
white-space: normal;
|
34 |
+
outline: none;
|
35 |
+
border: 0px;
|
36 |
+
background: none;
|
37 |
+
opacity: 1;
|
38 |
+
width: auto;
|
39 |
+
height: auto;
|
40 |
+
position: static;
|
41 |
+
float: none;
|
42 |
+
clear: none;
|
43 |
+
[dir="rtl"] & {
|
44 |
+
text-align: right;
|
45 |
+
}
|
46 |
+
}
|
47 |
+
|
48 |
+
//General
|
49 |
+
|
50 |
+
a img {
|
51 |
+
border: none;
|
52 |
+
}
|
53 |
+
|
54 |
+
.slb_viewer_layout {
|
55 |
+
@extend %box-sizing-border-box;
|
56 |
+
z-index: 2;
|
57 |
+
position: absolute;
|
58 |
+
width: 100%;
|
59 |
+
text-align: center;
|
60 |
+
}
|
61 |
+
|
62 |
+
.slb_viewer_overlay {
|
63 |
+
position: fixed;
|
64 |
+
top: 0;
|
65 |
+
left: 0;
|
66 |
+
z-index: 1;
|
67 |
+
min-height: 105%;
|
68 |
+
min-width: 100%;
|
69 |
+
background-color: #000;
|
70 |
+
}
|
71 |
+
|
72 |
+
.slb_container {
|
73 |
+
@extend %box-sizing-border-box;
|
74 |
+
position: relative;
|
75 |
+
display: inline-block;
|
76 |
+
background-color: #fff;
|
77 |
+
margin: 0 auto;
|
78 |
+
padding: 16px;
|
79 |
+
}
|
80 |
+
|
81 |
+
.slb_loading {
|
82 |
+
background: url('../images/loading.gif') center center no-repeat;
|
83 |
+
position: absolute;
|
84 |
+
left: 0%;
|
85 |
+
top: 0;
|
86 |
+
width: 100%;
|
87 |
+
height: 100%;
|
88 |
+
min-width: 31px;
|
89 |
+
min-height: 31px;
|
90 |
+
text-align: center;
|
91 |
+
line-height: 0;
|
92 |
+
display: none;
|
93 |
+
}
|
94 |
+
|
95 |
+
.slb_template_tag_ui {
|
96 |
+
cursor: pointer;
|
97 |
+
}
|
98 |
+
|
99 |
+
//UI
|
100 |
+
|
101 |
+
//Content
|
102 |
+
.slb_content {
|
103 |
+
position: relative;
|
104 |
+
}
|
105 |
+
|
106 |
+
.slb_details {
|
107 |
+
margin: 0 auto;
|
108 |
+
text-align: left;
|
109 |
+
|
110 |
+
.inner {
|
111 |
+
display: table;
|
112 |
+
width: 100%;
|
113 |
+
}
|
114 |
+
.slb_data {
|
115 |
+
display: table-caption;
|
116 |
+
}
|
117 |
+
}
|
118 |
+
|
119 |
+
.slb_template_tag_item_content > * {
|
120 |
+
width: 100%;
|
121 |
+
height: 100%;
|
122 |
+
}
|
123 |
+
|
124 |
+
/* Single */
|
125 |
+
&.item_single {
|
126 |
+
.slb_group_status,
|
127 |
+
.slb_nav,
|
128 |
+
.slb_slideshow {
|
129 |
+
display: none;
|
130 |
+
}
|
131 |
+
}
|
132 |
+
/* Loading */
|
133 |
+
&.loading {
|
134 |
+
.slb_loading {
|
135 |
+
display: block;
|
136 |
+
}
|
137 |
+
|
138 |
+
.slb_template_tag_ui {
|
139 |
+
opacity: 0;
|
140 |
+
}
|
141 |
+
}
|
142 |
+
|
143 |
+
//Media
|
144 |
+
|
145 |
+
//Small screen
|
146 |
+
@media screen and (max-width: 480px) {
|
147 |
+
%vsizing {
|
148 |
+
min-height: 100%;
|
149 |
+
min-width: 320px;
|
150 |
+
width: 100%;
|
151 |
+
}
|
152 |
+
@extend %vsizing;
|
153 |
+
.slb_viewer_layout {
|
154 |
+
@extend %vsizing;
|
155 |
+
display: block;
|
156 |
+
}
|
157 |
+
.slb_container {
|
158 |
+
@extend %vsizing;
|
159 |
+
max-width: 100%;
|
160 |
+
margin: 0;
|
161 |
+
padding: 5px;
|
162 |
+
position: absolute;
|
163 |
+
top: 0;
|
164 |
+
left: 0;
|
165 |
+
.slb_content {
|
166 |
+
img, iframe, object, .slb_inner {
|
167 |
+
max-width: 100%;
|
168 |
+
}
|
169 |
+
img {
|
170 |
+
height: auto;
|
171 |
+
}
|
172 |
+
}
|
173 |
+
}
|
174 |
+
}
|
175 |
+
}
|
176 |
+
}
|
themes/black/config.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1 |
-
# Require any additional compass plugins here.
|
2 |
-
|
3 |
-
# Set this to the root of your project when deployed:
|
4 |
-
http_path = "/"
|
5 |
-
css_dir = "css"
|
6 |
-
sass_dir = "sass"
|
7 |
-
images_dir = "images"
|
8 |
-
|
9 |
-
# You can select your preferred output style here (can be overridden via the command line):
|
10 |
-
output_style = :compressed
|
11 |
-
|
12 |
-
# To enable relative paths to assets via compass helper functions. Uncomment:
|
13 |
-
# relative_assets = true
|
14 |
-
|
15 |
-
# To disable debugging comments that display the original location of your selectors. Uncomment:
|
16 |
-
# line_comments = false
|
17 |
-
|
18 |
-
|
19 |
-
# If you prefer the indented syntax, you might want to regenerate this
|
20 |
-
# project again passing --syntax sass, or you can uncomment this:
|
21 |
-
# preferred_syntax = :sass
|
22 |
-
# and then run:
|
23 |
-
# sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
themes/black/css/style.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
#slb_viewer_wrap .slb_theme_slb_black a,#slb_viewer_wrap .slb_theme_slb_black a:hover{color:#fff}#slb_viewer_wrap .slb_theme_slb_black .slb_loading{background-image:url("../images/loading.gif")}#slb_viewer_wrap .slb_theme_slb_black .slb_container{background-color:#151515}#slb_viewer_wrap .slb_theme_slb_black .slb_prev
|
1 |
+
#slb_viewer_wrap .slb_theme_slb_black a,#slb_viewer_wrap .slb_theme_slb_black a:hover{color:#fff}#slb_viewer_wrap .slb_theme_slb_black .slb_loading{background-image:url("../images/loading.gif")}#slb_viewer_wrap .slb_theme_slb_black .slb_container{background-color:#151515}#slb_viewer_wrap .slb_theme_slb_black .slb_content .slb_prev .slb_template_tag,[dir="rtl"] #slb_viewer_wrap .slb_theme_slb_black .slb_content .slb_next .slb_template_tag{background-image:url("../images/nav_prev.png")}#slb_viewer_wrap .slb_theme_slb_black .slb_content .slb_next .slb_template_tag,[dir="rtl"] #slb_viewer_wrap .slb_theme_slb_black .slb_content .slb_prev .slb_template_tag{background-image:url("../images/nav_next.png")}#slb_viewer_wrap .slb_theme_slb_black .slb_data_title{color:#e3e3e3}#slb_viewer_wrap .slb_theme_slb_black .slb_data_desc{color:#cecece}#slb_viewer_wrap .slb_theme_slb_black .slb_group_status{color:#999}
|
themes/black/sass/style.scss
CHANGED
@@ -13,13 +13,16 @@
|
|
13 |
.slb_container {
|
14 |
background-color: #151515;
|
15 |
}
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
|
|
|
|
|
|
23 |
}
|
24 |
|
25 |
.slb_data_title {
|
13 |
.slb_container {
|
14 |
background-color: #151515;
|
15 |
}
|
16 |
+
.slb_content {
|
17 |
+
.slb_prev .slb_template_tag,
|
18 |
+
[dir="rtl"] & .slb_next .slb_template_tag {
|
19 |
+
background-image: url('../images/nav_prev.png');
|
20 |
+
}
|
21 |
+
|
22 |
+
.slb_next .slb_template_tag,
|
23 |
+
[dir="rtl"] & .slb_prev .slb_template_tag {
|
24 |
+
background-image: url('../images/nav_next.png');
|
25 |
+
}
|
26 |
}
|
27 |
|
28 |
.slb_data_title {
|
themes/default/client.js
DELETED
@@ -1,202 +0,0 @@
|
|
1 |
-
(function($) {
|
2 |
-
return {
|
3 |
-
/**
|
4 |
-
* State transition handlers
|
5 |
-
*/
|
6 |
-
'transition': {
|
7 |
-
/**
|
8 |
-
* Open event
|
9 |
-
* @param View.Viewer v Viewer instance
|
10 |
-
* @param jQuery.Deferred dfr Deferred instance to be resolved when animation is complete
|
11 |
-
* @return jQuery.Promise Resolved when transition is complete
|
12 |
-
*/
|
13 |
-
'open': function(v, dfr) {
|
14 |
-
var t = this;
|
15 |
-
var d = v.dom_get(),
|
16 |
-
l = v.get_layout().hide(),
|
17 |
-
o = v.get_overlay().hide();
|
18 |
-
var pos = {'top' : ''};
|
19 |
-
var final = function() {
|
20 |
-
//Show overlay
|
21 |
-
o.fadeIn(function() {
|
22 |
-
l.css(pos);
|
23 |
-
dfr.resolve();
|
24 |
-
});
|
25 |
-
};
|
26 |
-
//Clean UI
|
27 |
-
d.find('.slb_content').css({width: '', height: ''}).find('.slb_template_tag').hide();
|
28 |
-
d.find('.slb_details').height(0);
|
29 |
-
//Show viewer DOM
|
30 |
-
d.show(function() {
|
31 |
-
if ( document.documentElement.clientWidth > 480 ) {
|
32 |
-
/* Standard */
|
33 |
-
//Center vertically
|
34 |
-
var top_scr = $(document).scrollTop();
|
35 |
-
pos.top = ( top_scr + $(window).height() / 2 ) - ( l.height() / 2 );
|
36 |
-
if ( pos.top < top_scr ) {
|
37 |
-
pos.top = top_scr;
|
38 |
-
}
|
39 |
-
} else {
|
40 |
-
//Position at top
|
41 |
-
/* Small screen */
|
42 |
-
pos.top = $(document).scrollTop();
|
43 |
-
}
|
44 |
-
final();
|
45 |
-
});
|
46 |
-
return dfr.promise();
|
47 |
-
},
|
48 |
-
/**
|
49 |
-
* Close event
|
50 |
-
* @param View.Viewer v Viewer instance
|
51 |
-
* @param jQuery.Deferred dfr Deferred instance to be resolved when animation is complete
|
52 |
-
* @return jQuery.Promise Resolved when transition is complete
|
53 |
-
*/
|
54 |
-
'close': function(v, dfr) {
|
55 |
-
var l = v.get_layout(),
|
56 |
-
c = l.find('.slb_content');
|
57 |
-
var t = this;
|
58 |
-
var reset = function() {
|
59 |
-
//Reset state
|
60 |
-
c.width('').height('');
|
61 |
-
l.css('opacity', '');
|
62 |
-
dfr.resolve();
|
63 |
-
}
|
64 |
-
if ( v.animation_enabled() && document.documentElement.clientWidth > 480 ) { /* Standard */
|
65 |
-
var lanim = {opacity: 0, top: $(document).scrollTop() + ( $(window).height() / 2 )},
|
66 |
-
canim = {width: 0, height: 0};
|
67 |
-
//Shrink & fade out viewer
|
68 |
-
var pos = l.animate(lanim).promise();
|
69 |
-
var size = ( $.isEmptyObject(canim) ) ? true : c.animate(canim).promise();
|
70 |
-
$.when(pos, size).done(function() {
|
71 |
-
//Fade out overlay
|
72 |
-
v.get_overlay().fadeOut(function() {
|
73 |
-
reset();
|
74 |
-
});
|
75 |
-
});
|
76 |
-
} else {
|
77 |
-
l.css('opacity', 0);
|
78 |
-
reset();
|
79 |
-
}
|
80 |
-
return dfr.promise();
|
81 |
-
},
|
82 |
-
/**
|
83 |
-
* Item loading event
|
84 |
-
* @param View.Viewer v Viewer instance
|
85 |
-
* @param jQuery.Deferred dfr Deferred instance to be resolved when animation is complete
|
86 |
-
* @return jQuery.Promise Resolved when transition is complete
|
87 |
-
*/
|
88 |
-
'load': function(v, dfr) {
|
89 |
-
v.get_layout().find('.slb_loading').show();
|
90 |
-
if ( document.documentElement.clientWidth > 480 ) {
|
91 |
-
return v.get_layout().fadeIn().promise()
|
92 |
-
} else {
|
93 |
-
v.get_layout().show();
|
94 |
-
dfr.resolve();
|
95 |
-
return dfr;
|
96 |
-
}
|
97 |
-
},
|
98 |
-
/**
|
99 |
-
* Item unloaded event
|
100 |
-
* @param View.Viewer v Viewer instance
|
101 |
-
* @param jQuery.Deferred dfr Deferred instance to be resolved when animation is complete
|
102 |
-
* @return jQuery.Promise Resolved when transition is complete
|
103 |
-
*/
|
104 |
-
'unload': function(v, dfr) {
|
105 |
-
var l = v.get_layout(),
|
106 |
-
det = l.find('.slb_details'),
|
107 |
-
cont = l.find('.slb_content .slb_template_tag');
|
108 |
-
var props = {height: 0};
|
109 |
-
if ( document.documentElement.clientWidth > 480 ) {
|
110 |
-
//Hide details
|
111 |
-
det.animate(props, 'slow');
|
112 |
-
//Hide content
|
113 |
-
cont.fadeOut();
|
114 |
-
} else {
|
115 |
-
det.css(props);
|
116 |
-
cont.hide();
|
117 |
-
}
|
118 |
-
$.when(det.promise(), cont.promise()).done(function() {
|
119 |
-
dfr.resolve();
|
120 |
-
});
|
121 |
-
return dfr.promise();
|
122 |
-
},
|
123 |
-
/**
|
124 |
-
* Item loading completed event
|
125 |
-
* @param View.Viewer v Viewer instance
|
126 |
-
* @param jQuery.Deferred dfr Deferred instance to be resolved when animation is complete
|
127 |
-
* @return jQuery.Promise Resolved when transition is complete
|
128 |
-
*/
|
129 |
-
'complete': function(v, dfr) {
|
130 |
-
//Elements
|
131 |
-
var l = v.get_layout(),
|
132 |
-
loader = l.find('.slb_loading'),
|
133 |
-
det = l.find('.slb_details'),
|
134 |
-
det_data = det.find('.slb_data'),
|
135 |
-
c = l.find('.slb_content'),
|
136 |
-
c_tag = c.find('.slb_template_tag'),
|
137 |
-
c_tag_cont = c.find('.slb_template_tag_item_content');
|
138 |
-
//Transition
|
139 |
-
if ( document.documentElement.clientWidth > 480 ) {
|
140 |
-
//Resize viewer to fit item
|
141 |
-
var dims = this.get_item_dimensions();
|
142 |
-
//Show detail tags (container still hidden)
|
143 |
-
det.find('.slb_template_tag').show();
|
144 |
-
var top_scr = $(document).scrollTop();
|
145 |
-
var pos = { 'top': top_scr + ( $(window).height() / 2 ) - ( this.get_dimensions().height / 2 ) };
|
146 |
-
if ( pos.top < top_scr ) {
|
147 |
-
pos.top = top_scr;
|
148 |
-
}
|
149 |
-
pos.top = pos.top || 0;
|
150 |
-
//Resize container
|
151 |
-
pos = l.animate(pos).promise();
|
152 |
-
dims = c.animate(dims).promise();
|
153 |
-
$.when(pos, dims).done(function() {
|
154 |
-
//Hide loading indicator
|
155 |
-
loader.fadeOut('fast', function() {
|
156 |
-
//Display content
|
157 |
-
c_tag_cont.fadeIn(function() {
|
158 |
-
//Show UI
|
159 |
-
c_tag.show();
|
160 |
-
//Show details
|
161 |
-
det.animate({height: det_data.outerHeight()}, 'slow').promise().done(function() {
|
162 |
-
det.height('');
|
163 |
-
dfr.resolve();
|
164 |
-
});
|
165 |
-
});
|
166 |
-
});
|
167 |
-
});
|
168 |
-
} else {
|
169 |
-
loader.hide();
|
170 |
-
c_tag.show();
|
171 |
-
det.height('');
|
172 |
-
dfr.resolve();
|
173 |
-
}
|
174 |
-
return dfr.promise();
|
175 |
-
}
|
176 |
-
},
|
177 |
-
/**
|
178 |
-
* Theme offsets
|
179 |
-
* Reports additional space required for theme UI
|
180 |
-
*/
|
181 |
-
'offset': function() {
|
182 |
-
var dims = {'width': 0, 'height': 0};
|
183 |
-
if ( document.documentElement.clientWidth > 480 ) {
|
184 |
-
var d = this.get_viewer().get_layout().find('.slb_details');
|
185 |
-
d.find('.slb_template_tag').show();
|
186 |
-
$.extend(dims, {'width': 32, 'height': d.find('.slb_data').outerHeight()})
|
187 |
-
}
|
188 |
-
return dims;
|
189 |
-
},
|
190 |
-
/**
|
191 |
-
* Theme margins
|
192 |
-
* Reports additional margins used for positioning viewer
|
193 |
-
*/
|
194 |
-
'margin': function() {
|
195 |
-
var m = {'height': 0, 'width': 0};
|
196 |
-
if ( document.documentElement.clientWidth > 480 ) {
|
197 |
-
$.extend(m, {'height': 50, 'width': 20});
|
198 |
-
}
|
199 |
-
return m;
|
200 |
-
}
|
201 |
-
};
|
202 |
-
})(jQuery);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
themes/default/config.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1 |
-
# Require any additional compass plugins here.
|
2 |
-
|
3 |
-
# Set this to the root of your project when deployed:
|
4 |
-
http_path = "/"
|
5 |
-
css_dir = "css"
|
6 |
-
sass_dir = "sass"
|
7 |
-
images_dir = "images"
|
8 |
-
|
9 |
-
# You can select your preferred output style here (can be overridden via the command line):
|
10 |
-
output_style = :compressed
|
11 |
-
|
12 |
-
# To enable relative paths to assets via compass helper functions. Uncomment:
|
13 |
-
# relative_assets = true
|
14 |
-
|
15 |
-
# To disable debugging comments that display the original location of your selectors. Uncomment:
|
16 |
-
# line_comments = false
|
17 |
-
|
18 |
-
|
19 |
-
# If you prefer the indented syntax, you might want to regenerate this
|
20 |
-
# project again passing --syntax sass, or you can uncomment this:
|
21 |
-
# preferred_syntax = :sass
|
22 |
-
# and then run:
|
23 |
-
# sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
themes/default/css/style.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
@
|
1 |
+
@font-face{font-family:'Yanone Kaffeesatz';font-style:normal;font-weight:400;src:url("../fonts/yanone-kaffeesatz-v9-latin-regular.eot");src:local("Yanone Kaffeesatz Regular"),local("YanoneKaffeesatz-Regular"),url("../fonts/yanone-kaffeesatz-v9-latin-regular.eot?#iefix") format("embedded-opentype"),url("../fonts/yanone-kaffeesatz-v9-latin-regular.woff2") format("woff2"),url("../fonts/yanone-kaffeesatz-v9-latin-regular.woff") format("woff"),url("../fonts/yanone-kaffeesatz-v9-latin-regular.ttf") format("truetype"),url("../fonts/yanone-kaffeesatz-v9-latin-regular.svg#YanoneKaffeesatz") format("svg")}#slb_viewer_wrap .slb_theme_slb_default .slb_loading,#slb_viewer_wrap .slb_theme_slb_default .slb_controls .slb_template_tag_ui,#slb_viewer_wrap .slb_theme_slb_default .slb_content .slb_prev .slb_template_tag,#slb_viewer_wrap .slb_theme_slb_default .slb_content .slb_next .slb_template_tag{text-indent:100%;white-space:nowrap;overflow:hidden}#slb_viewer_wrap .slb_theme_slb_default a,#slb_viewer_wrap .slb_theme_slb_default a:hover{border-bottom:none;color:#000;text-decoration:underline}#slb_viewer_wrap .slb_theme_slb_default .slb_viewer_layout{top:20px}#slb_viewer_wrap .slb_theme_slb_default .slb_container{box-shadow:0 0 64px -40px #fcfcfc;border-radius:5px}#slb_viewer_wrap .slb_theme_slb_default .slb_template_tag_ui{transition:opacity .5s}#slb_viewer_wrap .slb_theme_slb_default .slb_controls{position:absolute;top:8px;right:8px;width:75%;text-align:right}[dir="rtl"] #slb_viewer_wrap .slb_theme_slb_default .slb_controls{right:inherit;left:0px}#slb_viewer_wrap .slb_theme_slb_default .slb_controls .slb_template_tag_ui{width:25px;height:25px;float:right;margin-left:2px;opacity:0.5}[dir="rtl"] #slb_viewer_wrap .slb_theme_slb_default .slb_controls .slb_template_tag_ui{float:left}#slb_viewer_wrap .slb_theme_slb_default .slb_controls .slb_template_tag_ui:hover{opacity:0.8}#slb_viewer_wrap .slb_theme_slb_default .slb_controls .slb_slideshow .slb_template_tag{background:url("../images/ui_slideshow_play.png") 0 0 no-repeat}#slb_viewer_wrap .slb_theme_slb_default .slb_controls .slb_close .slb_template_tag{background:url("../images/ui_close.png") 0 0 no-repeat}#slb_viewer_wrap .slb_theme_slb_default.slideshow_active .slb_controls .slb_slideshow .slb_template_tag{background:url("../images/ui_slideshow_pause.png") 0 0 no-repeat}#slb_viewer_wrap .slb_theme_slb_default .slb_content .slb_prev .slb_template_tag,#slb_viewer_wrap .slb_theme_slb_default .slb_content .slb_next .slb_template_tag{position:absolute;top:20%;height:71%;width:45%;min-width:25px;min-height:33px;background-repeat:no-repeat;opacity:0.5}#slb_viewer_wrap .slb_theme_slb_default .slb_content{min-height:58px;min-width:50px}#slb_viewer_wrap .slb_theme_slb_default .slb_content .slb_prev .slb_template_tag,[dir="rtl"] #slb_viewer_wrap .slb_theme_slb_default .slb_content .slb_next .slb_template_tag{left:4px;right:inherit;background-image:url("../images/nav_prev.png");background-position:left 45%}#slb_viewer_wrap .slb_theme_slb_default .slb_content .slb_next .slb_template_tag,[dir="rtl"] #slb_viewer_wrap .slb_theme_slb_default .slb_content .slb_prev .slb_template_tag{right:4px;left:inherit;background-image:url("../images/nav_next.png");background-position:right 45%}#slb_viewer_wrap .slb_theme_slb_default .slb_content .slb_prev .slb_template_tag:hover,#slb_viewer_wrap .slb_theme_slb_default .slb_content .slb_next .slb_template_tag:hover{opacity:1}#slb_viewer_wrap .slb_theme_slb_default .slb_details{line-height:1.4em;overflow:hidden;position:relative}#slb_viewer_wrap .slb_theme_slb_default .slb_details .slb_data{caption-side:bottom}#slb_viewer_wrap .slb_theme_slb_default .slb_details .slb_nav{display:none}#slb_viewer_wrap .slb_theme_slb_default .slb_data_title,#slb_viewer_wrap .slb_theme_slb_default .slb_group_status{font-family:'Yanone Kaffeesatz', arial, sans-serif;font-size:23px;margin-right:.2em;display:inline-block}[dir="rtl"] #slb_viewer_wrap .slb_theme_slb_default .slb_data_title,[dir="rtl"] #slb_viewer_wrap .slb_theme_slb_default .slb_group_status{margin-left:.2em;margin-right:0px}#slb_viewer_wrap .slb_theme_slb_default .slb_group_status{color:#777;font-style:italic;font-size:18.4px}#slb_viewer_wrap .slb_theme_slb_default .slb_data_desc{display:block;margin-top:0.5em}@media screen and (max-width: 480px){#slb_viewer_wrap .slb_theme_slb_default .slb_container{box-shadow:none;border-radius:0}#slb_viewer_wrap .slb_theme_slb_default .slb_controls{top:3px;right:3px}#slb_viewer_wrap .slb_theme_slb_default .slb_content .slb_prev .slb_template_tag,#slb_viewer_wrap .slb_theme_slb_default .slb_content .slb_next .slb_template_tag{top:17%;height:79%}}
|
themes/default/fonts/OFL.txt
ADDED
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Copyright (c) <dates>, <Copyright Holder> (<URL|email>),
|
2 |
+
with Reserved Font Name <Reserved Font Name>.
|
3 |
+
Copyright (c) <dates>, <additional Copyright Holder> (<URL|email>),
|
4 |
+
with Reserved Font Name <additional Reserved Font Name>.
|
5 |
+
Copyright (c) <dates>, <additional Copyright Holder> (<URL|email>).
|
6 |
+
|
7 |
+
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
8 |
+
This license is copied below, and is also available with a FAQ at:
|
9 |
+
http://scripts.sil.org/OFL
|
10 |
+
|
11 |
+
|
12 |
+
-----------------------------------------------------------
|
13 |
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
14 |
+
-----------------------------------------------------------
|
15 |
+
|
16 |
+
PREAMBLE
|
17 |
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
18 |
+
development of collaborative font projects, to support the font creation
|
19 |
+
efforts of academic and linguistic communities, and to provide a free and
|
20 |
+
open framework in which fonts may be shared and improved in partnership
|
21 |
+
with others.
|
22 |
+
|
23 |
+
The OFL allows the licensed fonts to be used, studied, modified and
|
24 |
+
redistributed freely as long as they are not sold by themselves. The
|
25 |
+
fonts, including any derivative works, can be bundled, embedded,
|
26 |
+
redistributed and/or sold with any software provided that any reserved
|
27 |
+
names are not used by derivative works. The fonts and derivatives,
|
28 |
+
however, cannot be released under any other type of license. The
|
29 |
+
requirement for fonts to remain under this license does not apply
|
30 |
+
to any document created using the fonts or their derivatives.
|
31 |
+
|
32 |
+
DEFINITIONS
|
33 |
+
"Font Software" refers to the set of files released by the Copyright
|
34 |
+
Holder(s) under this license and clearly marked as such. This may
|
35 |
+
include source files, build scripts and documentation.
|
36 |
+
|
37 |
+
"Reserved Font Name" refers to any names specified as such after the
|
38 |
+
copyright statement(s).
|
39 |
+
|
40 |
+
"Original Version" refers to the collection of Font Software components as
|
41 |
+
distributed by the Copyright Holder(s).
|
42 |
+
|
43 |
+
"Modified Version" refers to any derivative made by adding to, deleting,
|
44 |
+
or substituting -- in part or in whole -- any of the components of the
|
45 |
+
Original Version, by changing formats or by porting the Font Software to a
|
46 |
+
new environment.
|
47 |
+
|
48 |
+
"Author" refers to any designer, engineer, programmer, technical
|
49 |
+
writer or other person who contributed to the Font Software.
|
50 |
+
|
51 |
+
PERMISSION & CONDITIONS
|
52 |
+
Permission is hereby granted, free of charge, to any person obtaining
|
53 |
+
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
54 |
+
redistribute, and sell modified and unmodified copies of the Font
|
55 |
+
Software, subject to the following conditions:
|
56 |
+
|
57 |
+
1) Neither the Font Software nor any of its individual components,
|
58 |
+
in Original or Modified Versions, may be sold by itself.
|
59 |
+
|
60 |
+
2) Original or Modified Versions of the Font Software may be bundled,
|
61 |
+
redistributed and/or sold with any software, provided that each copy
|
62 |
+
contains the above copyright notice and this license. These can be
|
63 |
+
included either as stand-alone text files, human-readable headers or
|
64 |
+
in the appropriate machine-readable metadata fields within text or
|
65 |
+
binary files as long as those fields can be easily viewed by the user.
|
66 |
+
|
67 |
+
3) No Modified Version of the Font Software may use the Reserved Font
|
68 |
+
Name(s) unless explicit written permission is granted by the corresponding
|
69 |
+
Copyright Holder. This restriction only applies to the primary font name as
|
70 |
+
presented to the users.
|
71 |
+
|
72 |
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
73 |
+
Software shall not be used to promote, endorse or advertise any
|
74 |
+
Modified Version, except to acknowledge the contribution(s) of the
|
75 |
+
Copyright Holder(s) and the Author(s) or with their explicit written
|
76 |
+
permission.
|
77 |
+
|
78 |
+
5) The Font Software, modified or unmodified, in part or in whole,
|
79 |
+
must be distributed entirely under this license, and must not be
|
80 |
+
distributed under any other license. The requirement for fonts to
|
81 |
+
remain under this license does not apply to any document created
|
82 |
+
using the Font Software.
|
83 |
+
|
84 |
+
TERMINATION
|
85 |
+
This license becomes null and void if any of the above conditions are
|
86 |
+
not met.
|
87 |
+
|
88 |
+
DISCLAIMER
|
89 |
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
90 |
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
91 |
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
92 |
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
93 |
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
94 |
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
95 |
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
96 |
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
97 |
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|
themes/default/fonts/yanone-kaffeesatz-v9-latin-regular.eot
ADDED
Binary file
|
themes/default/fonts/yanone-kaffeesatz-v9-latin-regular.svg
ADDED
@@ -0,0 +1,407 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" standalone="no"?>
|
2 |
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
3 |
+
<svg xmlns="http://www.w3.org/2000/svg">
|
4 |
+
<defs >
|
5 |
+
<font id="YanoneKaffeesatz" horiz-adv-x="384" ><font-face
|
6 |
+
font-family="Yanone Kaffeesatz"
|
7 |
+
units-per-em="1000"
|
8 |
+
panose-1="0 0 5 0 0 0 0 0 0 0"
|
9 |
+
ascent="957"
|
10 |
+
descent="-200"
|
11 |
+
alphabetic="0" />
|
12 |
+
<glyph unicode=" " glyph-name="space" horiz-adv-x="158" />
|
13 |
+
<glyph unicode="!" glyph-name="exclam" horiz-adv-x="195" d="M45 683Q45 694 53 699T83 705T155 706L139 251Q138 233 131 226T109 216T59 213L45 683ZM68 -7T55 7T42 50Q42 74 57 91T97 108Q153 108 153 50Q153 26 138 10T97 -7Q68 -7 55 7Z" />
|
14 |
+
<glyph unicode=""" glyph-name="quotedbl" horiz-adv-x="263" d="M42 607T37 667T31 760Q31 781 34 782Q41 786 65 786Q95 786 110 783Q110 740 103 665T89 586Q82 585 67 584T45 583Q42 607 37 667ZM166 590T160 659T153 761Q153 781 156 782Q163 786 187
|
15 |
+
786Q218 786 233 783Q233 742 225 666T212 586Q205 585 190 584T168 583Q166 590 160 659Z" />
|
16 |
+
<glyph unicode="#" glyph-name="numbersign" horiz-adv-x="418" d="M323 254H390Q390 213 388 202T374 190H320L316 123Q315 112 302 110T245 107L249 190H154L150 123Q149 112 136 110T79 107L83 190H28Q28 232 30 243T44 254H87L92 360H28Q28 402 30 413T44
|
17 |
+
424H96L99 487Q100 498 114 500T170 503L166 424H262L265 487Q266 498 280 500T336 503L332 424H390Q390 383 388 372T374 360H328L323 254ZM157 254H253L258 360H162L157 254Z" />
|
18 |
+
<glyph unicode="$" glyph-name="dollar" horiz-adv-x="418" d="M363 20T237 -4V-91Q237 -110 221 -116T164 -122V-7Q128 -5 103 2T66 19T53 37Q53 46 59 68T74 102Q111 72 181 72Q228 72 251 94T274 158Q274 186 262 208T219 264L107 377Q53 434 53 488Q53 542
|
19 |
+
86 574T181 615V704Q181 724 198 730T254 737V616Q304 613 330 602T357 581Q357 569 352 553T337 525Q326 533 299 539T239 546Q142 546 142 489Q142 469 152 452T185 409L306 288Q336 258 349 227T363 157Q363 20 237 -4Z" />
|
20 |
+
<glyph unicode="%" glyph-name="percent" horiz-adv-x="692" d="M162 -7T150 -3T127 8T116 23L520 709Q523 708 534 703T555 691T565 674Q565 667 397 382T166 -8Q162 -7 150 -3ZM132 339T104 353T60 408T45 525Q45 618 81 663T186 708Q233 708 261 692T304 636T319
|
21 |
+
526Q319 339 180 339Q132 339 104 353ZM212 402T228 430T245 525Q245 574 239 600T220 636T186 646Q154 646 138 619T122 523Q122 473 128 447T148 412T182 402Q212 402 228 430ZM460 -9T431 5T387 60T372 177Q372 270 408 315T514 360Q561 360 589 344T632 288T647
|
22 |
+
178Q647 -9 508 -9Q460 -9 431 5ZM539 52T555 80T572 175Q572 224 566 250T548 286T513 296Q481 296 465 269T448 173Q448 123 454 97T474 62T509 52Q539 52 555 80Z" />
|
23 |
+
<glyph unicode="&" glyph-name="ampersand" horiz-adv-x="502" d="M458 70T488 55Q485 31 468 11T435 -10Q420 -10 362 54Q306 -10 212 -10Q27 -10 27 170Q27 229 59 278T139 358Q61 494 61 568Q61 636 104 671T228 706Q293 706 335 692T377 659Q377 644 372
|
24 |
+
627T357 600Q330 619 301 627T237 635Q193 635 170 620T146 558Q146 508 205 405T343 201Q351 241 351 291Q351 423 291 496Q332 504 405 504Q447 504 483 501Q483 499 484 490T485 472Q485 453 477 444T443 435L394 436Q411 405 420 374T429 281Q429 194 404 129Q458
|
25 |
+
70 488 55ZM272 66T309 115Q242 196 174 300Q110 254 110 168Q110 124 133 95T207 66Q272 66 309 115Z" />
|
26 |
+
<glyph unicode="'" glyph-name="quotesingle" horiz-adv-x="141" d="M42 607T37 667T31 760Q31 781 34 782Q41 786 65 786Q95 786 110 783Q110 740 103 665T89 586Q82 585 67 584T45 583Q42 607 37 667Z" />
|
27 |
+
<glyph unicode="(" glyph-name="parenleft" horiz-adv-x="292" d="M212 -196T172 -135T99 43T65 320Q65 470 98 578T172 744T226 803Q246 803 255 792T271 752Q218 680 183 573T147 318Q147 211 166 119T213 -38T271 -136Q265 -166 256 -181T227 -196Q212 -196 172 -135Z" />
|
28 |
+
<glyph unicode=")" glyph-name="parenright" horiz-adv-x="292" d="M47 -196T37 -181T21 -136Q71 -70 108 44T145 318Q145 460 110 573T21 752Q28 781 37 792T66 803Q79 803 119 746T193 581T227 320Q227 168 194 52T120 -130T65 -196Q47 -196 37 -181Z" />
|
29 |
+
<glyph unicode="*" glyph-name="asterisk" horiz-adv-x="470" d="M199 667Q198 678 206 683T229 688Q256 688 278 677L258 519Q256 510 252 506T239 501Q231 501 221 504L199 667ZM269 469T269 478Q269 489 282 495L431 575Q441 566 447 551T454 521Q454 498 439
|
30 |
+
494L280 455Q269 469 269 478ZM16 503Q15 532 29 551T60 570Q63 570 69 568L199 487Q200 470 194 463T175 459L16 503ZM249 404Q246 410 246 414Q246 424 271 434L386 299Q390 294 390 288Q390 274 370 261T327 245L249 404ZM130 250T120 250Q107 250 92 266T66
|
31 |
+
300L187 423Q195 431 202 431Q212 431 224 415L136 259Q130 250 120 250Z" />
|
32 |
+
<glyph unicode="+" glyph-name="plus" horiz-adv-x="418" d="M384 317Q384 275 382 261T368 247H245V123Q245 112 231 110T174 107V247H34Q34 290 36 303T51 317H174V441Q174 452 188 454T245 457V317H384Z" />
|
33 |
+
<glyph unicode="," glyph-name="comma" horiz-adv-x="183" d="M43 -103T38 -80Q54 -53 59 -36T67 5Q43 21 43 54Q43 77 57 91T94 106Q148 106 148 47Q148 13 133 -21T99 -79T70 -103Q43 -103 38 -80Z" />
|
34 |
+
<glyph unicode="-" glyph-name="hyphen" horiz-adv-x="278" d="M37 290T39 303T54 317H241Q241 275 239 261T225 247H37Q37 290 39 303Z" />
|
35 |
+
<glyph unicode="." glyph-name="period" horiz-adv-x="183" d="M63 -6T50 8T37 51Q37 75 52 91T93 108Q148 108 148 51Q148 26 133 10T93 -6Q63 -6 50 8Z" />
|
36 |
+
<glyph unicode="/" glyph-name="slash" horiz-adv-x="334" d="M235 743Q238 754 243 758T265 763T324 765L99 0Q96 -10 91 -14T69 -19T10 -20L235 743Z" />
|
37 |
+
<glyph unicode="0" glyph-name="zero" horiz-adv-x="418" d="M107 -9T68 65T29 296Q29 448 72 524T211 600Q306 600 347 532T389 320Q389 151 348 71T206 -9Q107 -9 68 65ZM260 64T282 124T305 321Q305 428 285 478T215 529Q160 529 138 469T116 290Q116 206 124
|
38 |
+
157T153 86T208 64Q260 64 282 124Z" />
|
39 |
+
<glyph unicode="1" glyph-name="one" horiz-adv-x="418" d="M28 32T28 56Q28 67 72 71T173 76L184 517Q163 516 123 509T70 499Q58 519 58 552Q58 558 97 569T183 590T247 600Q263 600 270 595L257 76H331Q353 76 368 77T389 79Q389 32 387 16T373 0H30Q28 32 28 56Z" />
|
40 |
+
<glyph unicode="2" glyph-name="two" horiz-adv-x="418" d="M29 11T29 25Q29 45 33 56T54 96Q76 133 102 167T167 247Q227 317 255 362T283 454Q283 523 206 523Q166 523 125 513T59 488Q49 511 49 547Q49 559 73 571T139 592T226 600Q309 600 341 567T374 464Q374
|
41 |
+
403 342 349T243 217Q171 131 136 76H271Q304 76 341 79T389 83Q389 34 386 17T372 0H33Q29 11 29 25Z" />
|
42 |
+
<glyph unicode="3" glyph-name="three" horiz-adv-x="418" d="M99 -100T72 -86T44 -51Q44 -27 49 -11T55 9Q90 -23 153 -23Q218 -23 254 25T291 150Q291 209 248 231T132 254L130 305Q194 336 228 376T263 458Q263 486 248 504T191 523Q111 523 53 487Q43 507
|
43 |
+
43 546Q43 559 64 571T125 592T216 600Q290 600 322 568T355 482Q355 380 245 301Q305 295 341 259T378 152Q378 71 349 15T269 -71T152 -100Q99 -100 72 -86Z" />
|
44 |
+
<glyph unicode="4" glyph-name="four" horiz-adv-x="418" d="M235 131H54Q28 157 28 202Q28 227 65 311T152 478T237 592Q254 606 273 606Q297 606 319 595L316 206Q344 206 364 207T390 209Q391 208 392 202T394 186Q394 162 388 147T367 131H316V26Q316 12 313
|
45 |
+
7T295 1T235 0V131ZM235 206L247 495Q208 450 161 361T98 206H235Z" />
|
46 |
+
<glyph unicode="5" glyph-name="five" horiz-adv-x="418" d="M111 -100T85 -93T47 -77T34 -59Q34 -19 43 7Q78 -25 141 -25Q218 -25 256 33T294 178Q294 259 255 289T139 319Q100 319 42 306L71 600H377Q377 568 375 554T363 534T335 528Q291 528 229 529T140
|
47 |
+
532L124 381Q159 386 187 386Q380 386 380 194Q380 56 322 -22T148 -100Q111 -100 85 -93Z" />
|
48 |
+
<glyph unicode="6" glyph-name="six" horiz-adv-x="418" d="M313 439T352 392T391 245Q391 -8 202 -8Q128 -8 91 29T43 132T31 308Q31 702 259 702Q306 702 336 694T367 668Q367 636 359 611Q317 626 265 626Q119 626 108 367Q132 403 165 421T246 439Q313 439
|
49 |
+
352 392ZM255 64T283 110T312 228Q312 295 289 330T223 365Q157 365 108 290V284Q106 169 129 117T205 64Q255 64 283 110Z" />
|
50 |
+
<glyph unicode="7" glyph-name="seven" horiz-adv-x="418" d="M115 -88T98 -84T80 -66Q93 35 128 149T208 365T294 531Q220 527 67 527Q45 527 45 600H405Q303 403 242 238T163 -88Q115 -88 98 -84Z" />
|
51 |
+
<glyph unicode="8" glyph-name="eight" horiz-adv-x="418" d="M362 293T377 259T392 182Q392 99 347 46T218 -8Q123 -8 78 45T32 183Q32 245 63 295T146 376Q101 407 81 429Q60 448 50 475T39 534Q39 617 87 661T210 706Q387 706 387 544Q387 485 358 444T279
|
52 |
+
369Q317 339 333 323Q362 293 377 259ZM176 630T148 608T119 539Q119 489 159 457Q180 438 219 411Q313 469 313 541Q313 585 286 607T220 630Q176 630 148 608ZM259 69T286 100T313 183Q313 220 302 243T268 286Q248 307 210 333Q163 309 135 272T107 188Q107
|
53 |
+
133 135 101T213 69Q259 69 286 100Z" />
|
54 |
+
<glyph unicode="9" glyph-name="nine" horiz-adv-x="418" d="M288 609T324 580T373 486T389 297Q387 92 327 -6T138 -104Q98 -104 74 -96T49 -71Q49 -58 51 -43T56 -17Q89 -27 129 -27Q220 -27 261 39T310 229Q286 193 254 175T174 157Q109 157 69 209T28 358Q28
|
55 |
+
485 75 547T217 609Q288 609 324 580ZM263 231T312 306V310Q312 392 305 439T278 512T218 537Q165 537 136 495T107 368Q107 302 131 267T198 231Q263 231 312 306Z" />
|
56 |
+
<glyph unicode=":" glyph-name="colon" horiz-adv-x="183" d="M63 329T51 343T38 386Q38 410 53 426T93 443Q149 443 149 386Q149 361 134 345T93 329Q63 329 51 343ZM63 -6T51 8T38 51Q38 75 53 91T93 108Q149 108 149 51Q149 26 134 10T93 -6Q63 -6 51 8Z" />
|
57 |
+
<glyph unicode=";" glyph-name="semicolon" horiz-adv-x="183" d="M61 329T49 343T36 386Q36 410 51 426T91 443Q147 443 147 386Q147 361 132 345T91 329Q61 329 49 343ZM39 -103T34 -80Q50 -54 55 -37T63 5Q39 21 39 54Q39 77 53 91T90 106Q144 106 144 47Q144
|
58 |
+
13 129 -21T95 -79T66 -103Q39 -103 34 -80Z" />
|
59 |
+
<glyph unicode="<" glyph-name="less" horiz-adv-x="400" d="M318 96T297 103L52 211Q39 234 39 258Q39 289 65 302L329 430Q342 418 349 404T357 377Q357 359 343 353L144 255L360 159Q359 134 348 115T324 96Q318 96 297 103Z" />
|
60 |
+
<glyph unicode="=" glyph-name="equal" horiz-adv-x="418" d="M34 382T36 396T51 410H384Q384 367 382 353T368 339H34Q34 382 36 396ZM34 197T36 210T51 224H384Q384 182 382 168T368 154H34Q34 197 36 210Z" />
|
61 |
+
<glyph unicode=">" glyph-name="greater" horiz-adv-x="400" d="M62 97T55 112T46 139Q46 157 60 164L260 261L43 358Q44 383 56 401T80 420Q90 420 107 413L351 305Q364 285 364 258Q364 227 338 214L74 85Q62 97 55 112Z" />
|
62 |
+
<glyph unicode="?" glyph-name="question" horiz-adv-x="295" d="M92 210T89 219T82 244T79 278Q79 319 97 351Q109 374 124 396T143 424Q171 465 184 491T197 552Q197 629 115 629Q66 629 31 603Q19 639 19 667Q19 684 58 697T144 710Q209 710 246 675T283 570Q283
|
63 |
+
512 264 473T209 384Q182 350 172 330Q160 309 160 283Q160 271 165 243Q167 234 168 227T166 217Q156 206 120 206Q109 206 93 208Q92 210 89 219ZM100 -6T88 8T75 51Q75 75 90 91T130 108Q186 108 186 51Q186 26 171 10T130 -6Q100 -6 88 8Z" />
|
64 |
+
<glyph unicode="@" glyph-name="at" horiz-adv-x="738" d="M442 -112T496 -101T602 -68Q623 -100 623 -126Q623 -141 592 -156T505 -180T375 -190Q268 -190 199 -159T89 -29T47 264Q47 479 139 581T394 683Q545 683 619 608T693 359Q693 145 644 74T533 2Q498
|
65 |
+
2 471 25Q459 15 429 8T358 1Q319 1 293 12T252 57T237 151Q237 318 365 318Q403 318 423 307Q423 313 424 330T425 368Q426 401 411 413T364 426Q333 426 310 421T264 402Q256 419 256 448Q256 459 265 468Q281 479 312 486T391 494Q448 494 475 468T501 378L496
|
66 |
+
177Q494 104 491 78Q508 72 524 72Q545 72 564 98T597 184T610 338Q610 441 590 500T523 585T393 611Q303 611 246 578T159 466T129 253Q129 106 155 27T233 -82T369 -112Q442 -112 496 -101ZM423 258Q402 261 388 261Q352 261 333 236T314 147Q314 98 327 80T368
|
67 |
+
62Q390 62 404 74T419 114L423 258Z" />
|
68 |
+
<glyph unicode="A" glyph-name="A" horiz-adv-x="437" d="M433 6T426 2T396 -2Q369 -2 348 0L306 178H132L93 14Q90 5 84 2T55 -2Q34 -2 5 1L184 689Q187 703 214 703Q237 703 252 700L431 15Q433 6 426 2ZM288 251L254 395Q225 517 219 588Q208 499 183 395L149
|
69 |
+
251H288Z" />
|
70 |
+
<glyph unicode="B" glyph-name="B" horiz-adv-x="377" d="M44 681Q44 691 49 695T70 700H169Q337 700 337 546Q337 470 308 430T242 384Q289 381 324 350T360 238Q360 118 307 59T170 0H44V681ZM175 414Q209 414 229 443T249 530Q249 629 175 629H125V414H175ZM171
|
71 |
+
71Q212 71 238 110T265 231Q265 280 254 305T223 337T172 345H125V71H171Z" />
|
72 |
+
<glyph unicode="C" glyph-name="C" horiz-adv-x="341" d="M142 -10T107 13T51 109T30 321Q30 480 59 566T130 681T227 710Q277 710 299 694T321 655Q321 628 308 606Q277 631 243 631Q206 631 178 608T133 517T115 325Q115 227 127 173T161 99T215 79Q243 79 268
|
73 |
+
88T308 111Q320 85 320 62Q320 32 285 11T196 -10Q142 -10 107 13Z" />
|
74 |
+
<glyph unicode="D" glyph-name="D" horiz-adv-x="388" d="M44 681Q44 691 50 695T71 700H169Q237 700 279 672T342 575T364 386Q364 242 342 158T276 37T169 0H44V681ZM171 77Q201 77 223 100T259 193T273 394Q273 485 262 535T229 606T171 626H125V77H171Z" />
|
75 |
+
<glyph unicode="E" glyph-name="E" horiz-adv-x="320" d="M125 73H297Q297 44 297 26T293 4T281 0H45V684Q45 688 48 694T61 700H301Q301 672 301 654T297 632T286 627H125V418H276Q276 391 276 373T272 350T261 344H125V73Z" />
|
76 |
+
<glyph unicode="F" glyph-name="F" horiz-adv-x="313" d="M301 700Q301 672 301 656T297 635T286 631H125V418H276Q276 391 276 373T272 350T261 344H125V16Q125 11 123 6T110 0H45V684Q45 688 48 694T61 700H301Z" />
|
77 |
+
<glyph unicode="G" glyph-name="G" horiz-adv-x="386" d="M148 -10T108 18T49 121T30 334Q30 485 55 567T127 679T245 710Q293 710 322 695T352 659Q352 635 341 607Q327 618 306 624T261 631Q208 631 177 605T131 515T116 340Q116 225 128 167T162 89T220 69Q244
|
78 |
+
69 259 77T280 94V343H205V394Q205 410 224 410H355V35Q301 -10 218 -10Q148 -10 108 18Z" />
|
79 |
+
<glyph unicode="H" glyph-name="H" horiz-adv-x="410" d="M365 7T362 4T339 1T285 0V339H125V16Q125 7 122 4T98 1T44 0V684Q44 693 47 696T71 699T125 700V415H285V684Q285 693 288 696T311 699T365 700V16Q365 7 362 4Z" />
|
80 |
+
<glyph unicode="I" glyph-name="I" horiz-adv-x="169" d="M44 663Q44 683 48 690T66 698T126 700V16Q126 7 122 4T98 1T44 0V663Z" />
|
81 |
+
<glyph unicode="J" glyph-name="J" horiz-adv-x="300" d="M63 -9T39 8T14 50Q14 64 17 73T26 96Q41 82 63 73T109 63Q138 63 151 76T169 114T174 183V663Q174 684 177 690T195 698T256 700V165Q256 82 226 37T119 -9Q63 -9 39 8Z" />
|
82 |
+
<glyph unicode="K" glyph-name="K" horiz-adv-x="389" d="M371 701T371 686Q371 682 368 677L206 398Q326 307 367 18Q368 6 362 2T334 -2Q308 -2 278 1Q254 128 229 201T164 318Q151 333 124 345V16Q124 7 121 4T97 1T42 0V684Q42 693 45 696T69 699T124 700V398L284
|
83 |
+
695Q313 701 335 701Q371 701 371 686Z" />
|
84 |
+
<glyph unicode="L" glyph-name="L" horiz-adv-x="314" d="M44 677Q44 690 48 694T66 699T125 700V76H297V16Q297 7 293 4T281 0H44V677Z" />
|
85 |
+
<glyph unicode="M" glyph-name="M" horiz-adv-x="489" d="M445 700V16Q445 7 442 4T418 1T363 0L366 245Q368 310 375 410T385 546L368 486Q329 342 319 315L266 161Q263 153 255 153H220L168 315Q155 354 104 541L103 540Q106 509 113 412T121 249L123 16Q123
|
86 |
+
7 119 4T95 1T44 0V684Q44 694 48 697T60 700H118L214 396Q225 362 234 330T246 285Q249 297 257 329T275 393L364 684Q367 693 370 696T380 700H445Z" />
|
87 |
+
<glyph unicode="N" glyph-name="N" horiz-adv-x="444" d="M320 693T324 696T348 699T401 700V16Q401 0 384 0H324L209 275Q185 339 114 560Q118 517 121 416T124 259V16Q124 7 121 4T97 1T44 0V684Q44 700 60 700H121L234 430Q247 395 308 211Q312 199 330 146V149Q325
|
88 |
+
188 323 290T320 448V684Q320 693 324 696Z" />
|
89 |
+
<glyph unicode="O" glyph-name="O" horiz-adv-x="429" d="M143 -10T105 21T48 131T30 354Q30 486 50 564T113 676T222 710Q288 710 326 678T381 569T399 357Q399 220 380 140T319 25T211 -10Q143 -10 105 21ZM251 73T272 101T302 190T312 355Q312 459 304 517T276
|
90 |
+
601T220 627Q184 627 163 599T131 507T121 334Q121 238 129 182T158 99T214 73Q251 73 272 101Z" />
|
91 |
+
<glyph unicode="P" glyph-name="P" horiz-adv-x="361" d="M254 700T298 653T343 503Q343 387 293 336T160 284H124V16Q124 7 121 4T97 1T44 0V684Q44 693 47 696T60 700H159Q254 700 298 653ZM212 359T233 394T254 512Q254 569 236 599T174 629H124V359H168Q212
|
92 |
+
359 233 394Z" />
|
93 |
+
<glyph unicode="Q" glyph-name="Q" horiz-adv-x="429" d="M404 -61T407 -74T410 -97Q410 -118 382 -127T320 -137Q269 -137 239 -107T190 -9Q131 -5 97 29T46 141T30 354Q30 486 50 564T113 676T222 710Q288 710 326 678T381 569T399 357Q399 194 371 111T282
|
94 |
+
2Q288 -37 300 -53T335 -70Q372 -70 398 -53Q404 -61 407 -74ZM121 238T129 182T158 99T214 73Q251 73 272 101T302 190T312 355Q312 459 304 517T276 601T220 627Q184 627 163 599T131 507T121 334Q121 238 129 182Z" />
|
95 |
+
<glyph unicode="R" glyph-name="R" horiz-adv-x="372" d="M288 264T315 192T350 18Q350 6 343 2T309 -2Q298 -2 262 0Q255 110 231 179T180 285Q173 284 160 284H124V16Q124 7 121 4T97 1T44 0V684Q44 688 47 694T60 700H159Q254 700 298 653T343 503Q343 356
|
96 |
+
256 306Q288 264 315 192ZM168 359Q212 359 233 393T254 506Q254 567 236 598T174 629H124V359H168Z" />
|
97 |
+
<glyph unicode="S" glyph-name="S" horiz-adv-x="358" d="M94 -10T60 8T25 49Q25 62 30 78T46 107Q85 72 149 72Q248 72 248 174Q248 210 235 238T189 306L89 423Q55 464 41 497T26 567Q26 632 71 671T198 710Q265 710 297 697T329 660Q329 635 309 614Q298 623
|
98 |
+
271 630T211 638Q166 638 140 620T113 569Q113 543 124 522T159 470L268 347Q306 302 320 264T335 178Q335 93 294 42T157 -10Q94 -10 60 8Z" />
|
99 |
+
<glyph unicode="T" glyph-name="T" horiz-adv-x="373" d="M365 700V641Q365 631 361 628T348 624H225V16Q225 7 221 4T197 1T144 0V624H8V684Q8 700 25 700H365Z" />
|
100 |
+
<glyph unicode="U" glyph-name="U" horiz-adv-x="437" d="M148 -10T109 18T57 91T44 205V683Q44 692 47 695T71 699T127 700V202Q127 133 146 99T224 65Q249 65 274 70T312 82V683Q312 692 316 695T340 699T394 700V26Q373 12 326 1T224 -10Q148 -10 109 18Z" />
|
101 |
+
<glyph unicode="V" glyph-name="V" horiz-adv-x="420" d="M176 -7T165 8T146 51Q122 153 73 377T7 676Q5 686 5 689Q5 695 9 697T24 700H90L174 312Q187 246 207 117L214 69Q232 215 250 312L325 676Q328 689 332 694T346 700H416L262 -3Q233 -7 194 -7Q176 -7 165 8Z" />
|
102 |
+
<glyph unicode="W" glyph-name="W" horiz-adv-x="654" d="M650 700L518 -3Q509 -4 492 -6T451 -8Q419 -8 408 49L356 276Q345 334 325 503Q306 341 296 277L241 -3Q208 -7 167 -7Q140 -7 126 54Q105 158 63 380T7 676Q6 680 6 687Q6 694 10 697T24 700H90L163
|
103 |
+
311Q178 220 193 88H198Q203 187 224 311L286 642Q289 656 292 661T307 666H364L435 311Q450 232 462 118L465 88H471Q482 220 496 311L561 676Q563 689 566 694T581 700H650Z" />
|
104 |
+
<glyph unicode="X" glyph-name="X" horiz-adv-x="424" d="M414 9T414 7Q414 0 403 0H315L261 135Q233 206 207 283Q178 198 151 135L97 10Q93 4 90 2T79 0H9L162 361L36 686Q33 694 37 696T66 699T131 700L172 586Q205 491 222 436Q248 520 271 586L310 687Q312
|
105 |
+
694 316 696T341 699T397 700L268 368L412 13Q414 9 414 7Z" />
|
106 |
+
<glyph unicode="Y" glyph-name="Y" horiz-adv-x="364" d="M225 16Q225 7 222 4T198 1T144 0V285L6 687Q4 694 8 696T35 699T97 700L137 563Q152 516 168 446T187 353Q189 375 206 445T238 563L273 685Q275 693 279 696T304 699T360 700L225 290V16Z" />
|
107 |
+
<glyph unicode="Z" glyph-name="Z" horiz-adv-x="385" d="M19 11T19 31Q19 50 27 67L267 628H80Q49 628 37 625V683Q37 691 41 695T54 700H352Q360 689 360 674Q360 656 352 637L108 72H302Q343 72 361 80V16Q361 0 345 0H32Q19 11 19 31Z" />
|
108 |
+
<glyph unicode="[" glyph-name="bracketleft" horiz-adv-x="386" d="M122 796Q122 808 125 812T140 819T184 821H377Q377 785 376 771T369 752T350 747H203V-123H376Q376 -161 374 -176T367 -195T349 -199H122V796Z" />
|
109 |
+
<glyph unicode="\" glyph-name="backslash" horiz-adv-x="329" d="M12 743L10 752Q10 761 25 763T91 765L317 -10L319 -18Q319 -26 304 -28T237 -30L12 743Z" />
|
110 |
+
<glyph unicode="]" glyph-name="bracketright" horiz-adv-x="386" d="M9 -164T10 -150T17 -131T36 -126H183V746H10Q10 784 12 799T19 818T37 822H264V-175Q264 -187 261 -191T246 -198T202 -200H9Q9 -164 10 -150Z" />
|
111 |
+
<glyph unicode="^" glyph-name="asciicircum" horiz-adv-x="430" d="M69 208T59 220T48 249L220 398L366 270Q380 259 380 244Q380 230 369 219T341 206L212 294L110 218Q94 208 85 208Q69 208 59 220Z" />
|
112 |
+
<glyph unicode="_" glyph-name="underscore" horiz-adv-x="377" d="M14 -66T16 -52T30 -38H364Q364 -81 362 -95T347 -109H14Q14 -66 16 -52Z" />
|
113 |
+
<glyph unicode="`" glyph-name="grave" horiz-adv-x="269" d="M162 568T111 604T49 655Q53 677 63 696T86 716Q93 716 141 675T220 598Q219 595 215 584T204 563T189 553Q162 568 111 604Z" />
|
114 |
+
<glyph unicode="a" glyph-name="a" horiz-adv-x="354" d="M102 -10T66 20T29 142Q29 237 65 271T163 306Q210 306 236 293V372Q236 406 221 419T174 432Q138 432 101 426T41 409Q30 430 30 456Q30 476 41 483Q56 493 99 501T194 510Q259 510 288 482T317 388V335Q317
|
115 |
+
115 311 24Q287 9 250 0T166 -10Q102 -10 66 20ZM196 58T211 63T233 74Q236 108 236 236Q217 246 189 246Q153 246 133 225T113 144Q113 93 129 76T180 58Q196 58 211 63Z" />
|
116 |
+
<glyph unicode="b" glyph-name="b" horiz-adv-x="385" d="M84 -10T48 20V698Q48 717 54 724T75 733T128 735V475Q173 510 235 510Q297 510 327 465T358 313Q358 120 303 55T164 -10Q84 -10 48 20ZM212 61T240 110T268 296Q268 374 251 405T198 437Q156 437 128
|
117 |
+
409V75Q144 61 175 61Q212 61 240 110Z" />
|
118 |
+
<glyph unicode="c" glyph-name="c" horiz-adv-x="313" d="M128 -10T96 9T48 83T31 239Q31 400 81 455T210 510Q246 510 270 497T294 465Q294 442 285 420Q251 439 214 439Q170 439 142 399T114 238Q114 169 123 131T152 77T204 62Q227 62 248 68T284 85Q292 56
|
119 |
+
292 41Q292 20 260 5T180 -10Q128 -10 96 9Z" />
|
120 |
+
<glyph unicode="d" glyph-name="d" horiz-adv-x="381" d="M142 -10T108 7T52 77T31 232Q31 373 73 441T184 510Q230 510 256 490V698Q256 717 262 724T284 733T337 735V20Q273 -10 193 -10Q142 -10 108 7ZM234 62T256 77V427Q239 440 210 440Q120 440 120 241Q120
|
121 |
+
168 129 129T154 76T196 62Q234 62 256 77Z" />
|
122 |
+
<glyph unicode="e" glyph-name="e" horiz-adv-x="361" d="M267 68T321 100Q328 78 328 45Q328 22 288 6T190 -10Q139 -10 105 9T50 79T30 224Q30 341 54 404T117 488T207 510Q334 510 334 350Q334 270 323 220Q279 211 221 208T113 204Q115 150 125 121T155 80T207
|
123 |
+
68Q267 68 321 100ZM162 439T140 402T114 268Q213 268 251 280Q256 303 256 340Q255 396 243 417T198 439Q162 439 140 402Z" />
|
124 |
+
<glyph unicode="f" glyph-name="f" horiz-adv-x="254" d="M82 432H13Q13 459 14 475T18 496T33 500H82V561Q82 665 129 702T249 739Q294 739 318 728T342 698Q342 675 333 654Q304 666 262 666Q215 666 189 646T162 567V500H252Q252 473 251 457T247 436T235 432H162V16Q162
|
125 |
+
11 159 6T145 0H82V432Z" />
|
126 |
+
<glyph unicode="g" glyph-name="g" horiz-adv-x="394" d="M308 72T341 47T375 -34Q375 -104 326 -150T183 -197Q91 -197 57 -167T23 -88Q23 -54 44 -23T100 33Q37 50 38 87Q38 127 101 177Q39 217 39 327Q39 422 83 466T206 510Q229 510 256 502H375Q383 488 383
|
127 |
+
464Q383 433 355 433Q342 433 319 438Q357 400 357 329Q357 246 318 200T195 154Q169 154 150 158Q123 131 123 114Q123 102 148 97T242 82Q308 72 341 47ZM167 451T146 422T124 329Q124 271 139 244T200 216Q239 216 257 249T276 348Q276 402 258 426T203 451Q167
|
128 |
+
451 146 422ZM240 -123T266 -99T293 -45Q293 -22 283 -10T249 9T180 19L160 21Q137 3 122 -21T106 -69Q106 -96 124 -109T190 -123Q240 -123 266 -99Z" />
|
129 |
+
<glyph unicode="h" glyph-name="h" horiz-adv-x="380" d="M45 698Q45 717 51 724T72 733T125 735V471Q147 490 177 500T238 510Q299 510 320 479T342 378V16Q342 7 338 4T313 1T260 0V356Q260 394 248 414T201 435Q182 435 162 429T125 408V16Q125 7 122 4T99
|
130 |
+
1T45 0V698Z" />
|
131 |
+
<glyph unicode="i" glyph-name="i" horiz-adv-x="175" d="M47 463Q47 482 53 489T75 498T128 500V16Q128 7 125 4T101 1T47 0V463ZM300 570T300 628Q300 692 346 692Q368 692 377 679T386 634Q386 604 374 587T340 570Q300 570 300 628Z" />
|
132 |
+
<glyph unicode="j" glyph-name="j" horiz-adv-x="184" d="M-50 -196T-76 -182T-103 -143Q-103 -117 -91 -102Q-53 -122 -6 -122Q31 -122 42 -101T54 -24V463Q54 482 60 489T81 498T134 500V-36Q134 -111 106 -153T4 -196Q-50 -196 -76 -182ZM306 570T306 628Q306
|
133 |
+
692 352 692Q374 692 383 679T392 634Q392 604 380 587T346 570Q306 570 306 628Z" />
|
134 |
+
<glyph unicode="k" glyph-name="k" horiz-adv-x="376" d="M46 698Q46 717 52 724T74 733T127 735V464Q153 485 187 497T253 510Q338 510 338 424Q338 369 312 331T254 269Q293 252 320 209T354 100Q355 90 355 67Q355 43 352 16Q351 7 347 4T321 1T261 0Q265 29
|
135 |
+
265 62Q265 93 260 123Q251 175 231 201T183 227Q176 227 172 226Q161 224 146 217T127 207V16Q127 7 124 4T101 1T46 0V698ZM249 314T249 397Q249 437 212 437Q166 437 127 389V265Q249 314 249 397Z" />
|
136 |
+
<glyph unicode="l" glyph-name="l" horiz-adv-x="173" d="M46 698Q46 717 52 724T74 733T127 735V16Q127 7 123 4T100 1T46 0V698Z" />
|
137 |
+
<glyph unicode="m" glyph-name="m" horiz-adv-x="564" d="M458 510T482 494T515 449T523 369V16Q523 7 519 4T495 1T442 0V370Q442 409 433 424T393 439Q356 439 325 420V16Q325 7 322 4T299 1T246 0H245V372Q245 400 242 413T229 433T195 440Q159 440 127 422V16Q127
|
138 |
+
7 123 4T99 1T46 0V477Q119 510 197 510Q259 510 288 479Q313 493 346 501T410 510Q458 510 482 494Z" />
|
139 |
+
<glyph unicode="n" glyph-name="n" horiz-adv-x="383" d="M45 476Q76 490 121 500T204 510Q282 510 313 480T344 376V16Q344 7 340 4T316 1T261 0V352Q261 402 249 421T201 440Q183 440 162 436T126 422V16Q126 7 122 4T98 1T45 0V476Z" />
|
140 |
+
<glyph unicode="o" glyph-name="o" horiz-adv-x="376" d="M128 -10T95 9T45 84T27 250Q27 510 194 510Q249 510 282 488T332 409T349 252Q349 116 308 53T184 -10Q128 -10 95 9ZM222 58T241 100T261 252Q261 330 254 371T231 427T191 442Q154 442 135 400T115
|
141 |
+
248Q115 168 123 127T146 72T186 58Q222 58 241 100Z" />
|
142 |
+
<glyph unicode="p" glyph-name="p" horiz-adv-x="382" d="M63 -197T55 -190T46 -162V470Q109 510 192 510Q272 510 313 464T355 302Q355 121 313 56T206 -10Q180 -10 160 -2T127 18V-191Q108 -197 85 -197Q63 -197 55 -190ZM266 62T266 293Q266 352 258 384T233
|
143 |
+
428T188 440Q154 440 127 421V95Q147 62 181 62Q266 62 266 293Z" />
|
144 |
+
<glyph unicode="q" glyph-name="q" horiz-adv-x="387" d="M276 -198T261 -195V34Q231 -10 165 -10Q107 -10 69 38T30 218Q30 373 86 441T235 510Q269 510 294 503T342 479V-163Q342 -186 334 -191T294 -198Q276 -198 261 -195ZM215 60T233 73T261 112V426Q243
|
145 |
+
440 215 440Q169 440 145 389T121 220Q121 127 141 94T195 61Q215 60 233 73Z" />
|
146 |
+
<glyph unicode="r" glyph-name="r" horiz-adv-x="263" d="M45 465Q109 510 181 510Q218 510 234 500T251 468Q251 443 242 421Q221 433 194 433Q155 433 128 410L127 16Q127 7 123 4T99 1T45 0V465Z" />
|
147 |
+
<glyph unicode="s" glyph-name="s" horiz-adv-x="346" d="M97 -10T64 3T30 40Q30 64 45 87Q86 63 144 63Q183 63 204 78T226 124Q226 146 217 165T186 203L89 286Q31 333 31 392Q31 447 72 478T195 510Q263 510 291 492T320 454Q320 445 315 434T303 413Q259 440
|
148 |
+
204 440Q168 440 147 427T125 391Q125 376 133 363T165 329L258 254Q291 222 304 194T318 129Q318 63 274 27T152 -10Q97 -10 64 3Z" />
|
149 |
+
<glyph unicode="t" glyph-name="t" horiz-adv-x="292" d="M141 -10T121 7T94 56T87 139V431H19Q19 458 20 474T24 495T36 500H87V652Q87 666 93 671T114 678T167 680V500H271Q271 473 270 456T266 435T254 431H167V139Q167 98 173 79T204 59Q220 59 232 62T262
|
150 |
+
74Q268 54 268 34Q268 10 243 0T182 -10Q141 -10 121 7Z" />
|
151 |
+
<glyph unicode="u" glyph-name="u" horiz-adv-x="389" d="M135 -10T103 8T58 61T45 156V484Q45 493 48 496T72 499T128 500V149Q128 98 141 79T196 60Q236 60 263 79V484Q263 493 267 496T290 499T344 500V26Q314 10 274 0T194 -10Q135 -10 103 8Z" />
|
152 |
+
<glyph unicode="v" glyph-name="v" horiz-adv-x="344" d="M143 -6T135 6T121 43L19 475Q17 485 17 487Q17 494 23 496T51 499T104 500L136 339Q150 274 161 193T176 86H178Q181 111 192 192T216 340L243 482Q245 492 249 495T273 499T328 500L213 -3Q198 -6 156
|
153 |
+
-6Q143 -6 135 6Z" />
|
154 |
+
<glyph unicode="w" glyph-name="w" horiz-adv-x="541" d="M448 492T452 495T476 499T526 500Q510 421 466 209T418 -3Q415 -4 401 -5T366 -6Q354 -6 342 7T324 46L311 114Q288 220 274 363Q256 205 237 113L214 -3Q207 -4 188 -5T147 -6Q123 -6 113 43Q95 120
|
155 |
+
61 276T16 483Q14 492 19 495T46 499T103 500L134 337Q146 267 156 191T169 93H175Q194 229 203 278L235 469Q237 480 241 483T261 486H314L353 276Q364 228 373 170T384 93H389Q393 140 402 210T421 337L446 482Q448 492 452 495Z" />
|
156 |
+
<glyph unicode="x" glyph-name="x" horiz-adv-x="411" d="M395 9T395 8Q395 3 384 2T337 0H302L265 66Q243 107 199 201Q164 121 136 65L107 16Q103 8 96 5T68 1T15 0L157 260L35 487Q32 494 35 496T60 499T120 500L157 431Q185 379 211 317Q244 390 266 432L297
|
157 |
+
486Q300 494 305 496T330 499T386 500L258 267L391 19Q395 9 395 8Z" />
|
158 |
+
<glyph unicode="y" glyph-name="y" horiz-adv-x="357" d="M-4 -193T-4 -154Q-4 -142 -1 -130T8 -109Q18 -116 35 -120T71 -124Q97 -124 115 -100T144 -16L24 478Q22 486 22 489Q22 497 35 498T102 500L157 260Q167 211 174 156T184 83Q186 99 192 154T208 261L253
|
159 |
+
477Q255 490 259 494T279 499T340 500L217 -27Q202 -91 184 -127T140 -178T77 -193Q-4 -193 -4 -154Z" />
|
160 |
+
<glyph unicode="z" glyph-name="z" horiz-adv-x="335" d="M33 1T30 5T24 19T21 40Q21 58 28 70L223 432H120Q63 432 28 427Q25 444 25 465Q25 483 31 491T51 500H306Q307 499 310 493T314 475Q314 456 305 436L115 75H204Q270 75 310 85Q312 77 312 50Q312 23
|
161 |
+
306 12T280 0H34Q33 1 30 5Z" />
|
162 |
+
<glyph unicode="{" glyph-name="braceleft" horiz-adv-x="277" d="M154 -150T122 -117T89 -15Q89 26 96 80Q97 89 100 120T103 182Q103 220 90 237T48 260Q41 275 41 293Q41 321 58 333Q74 343 83 352T97 378T103 427Q103 458 100 492T96 536Q89 590 89 626Q89
|
163 |
+
686 130 714T244 744Q260 722 260 694Q260 683 256 676T245 666Q208 663 190 644T171 585Q171 556 176 511Q182 445 182 403Q182 357 169 335T128 300Q155 289 168 268T182 205Q182 164 176 100Q171 53 171 22Q171 -15 180 -35T206 -63T253 -76Q255 -102 255 -106Q255
|
164 |
+
-126 248 -138T227 -150Q154 -150 122 -117Z" />
|
165 |
+
<glyph unicode="|" glyph-name="bar" horiz-adv-x="324" d="M122 793Q122 805 126 809T145 814T203 815V-180Q203 -191 199 -194T175 -199T122 -200V793Z" />
|
166 |
+
<glyph unicode="}" glyph-name="braceright" horiz-adv-x="277" d="M18 -128T18 -100Q18 -75 33 -72Q106 -66 106 8Q106 28 102 84Q96 148 96 191Q96 237 109 259T149 294Q122 305 109 326T96 389Q96 430 102 494Q106 550 106 573Q106 610 97 629T71 657T25 670Q21
|
167 |
+
686 21 701Q21 720 29 732T50 744Q123 744 155 711T188 609Q188 568 181 514Q180 505 177 474T174 412Q174 374 187 357T229 334Q236 317 236 301Q236 272 218 261Q201 250 193 242T180 216T174 167Q174 128 182 58Q188 -6 188 -32Q188 -92 146 -121T33 -150Q18
|
168 |
+
-128 18 -100Z" />
|
169 |
+
<glyph unicode="~" glyph-name="asciitilde" horiz-adv-x="400" d="M237 212T221 218T185 237Q169 247 158 251T132 256Q115 256 102 250T72 232Q58 221 46 218Q32 217 22 230T11 266Q26 289 61 309T140 329Q164 329 178 324T212 306Q228 296 240 291T270 286Q309
|
170 |
+
286 341 320Q347 325 357 325Q370 325 380 311T391 277Q373 252 340 232T263 212Q237 212 221 218Z" />
|
171 |
+
<glyph unicode=" " glyph-name="uni00A0" horiz-adv-x="158" />
|
172 |
+
<glyph unicode="¡" glyph-name="exclamdown" horiz-adv-x="195" d="M46 394T46 451Q46 476 61 492T102 508Q132 508 144 494T157 451Q157 427 142 411T102 394Q46 394 46 451ZM61 256Q62 274 69 281T91 291T141 293L155 -174Q155 -185 147 -190T117 -196T45
|
173 |
+
-197L61 256Z" />
|
174 |
+
<glyph unicode="¢" glyph-name="cent" horiz-adv-x="418" d="M277 64T299 71T335 88Q343 68 343 37Q343 23 319 9T263 -9V-102Q263 -121 247 -127T190 -133V-7Q154 -1 131 20T96 91T83 228Q83 471 213 504V592Q213 611 230 618T286 626V508Q310 503 327 494T345
|
175 |
+
475Q345 437 337 417Q305 435 269 435Q239 435 217 421T179 362T164 231Q164 156 174 121T202 75T257 64Q277 64 299 71Z" />
|
176 |
+
<glyph unicode="£" glyph-name="sterling" horiz-adv-x="366" d="M322 74Q329 54 329 37Q329 0 277 0H89Q80 121 78 277H15Q15 320 17 333T31 347H78Q82 480 122 537T238 595Q280 595 309 582T338 542Q338 530 335 518T327 493Q294 514 256 514Q210 514 185
|
177 |
+
479T158 347H288Q288 305 286 291T272 277H158Q160 146 165 80L322 74Z" />
|
178 |
+
<glyph unicode="¤" glyph-name="currency" horiz-adv-x="571" d="M560 49Q535 24 525 15T507 6Q504 6 498 10L417 91Q371 52 286 52Q201 52 154 90L62 -2Q39 21 30 32T20 51Q20 56 24 60L110 146Q87 198 87 276Q87 350 107 401L12 496Q37 521 47 530T65 539Q69
|
179 |
+
539 73 535L147 461Q198 506 291 506Q380 506 427 463L510 546Q534 522 543 512T552 493Q552 489 548 485L466 403Q484 357 484 286Q484 202 460 148L560 49ZM348 121T377 162T407 288Q407 365 380 402T295 439Q230 439 199 398T167 271Q167 195 196 158T288 121Q348
|
180 |
+
121 377 162Z" />
|
181 |
+
<glyph unicode="¥" glyph-name="yen" horiz-adv-x="418" d="M249 243H379Q379 205 373 191T347 176H249V16Q249 7 246 4T223 1T169 0V176H38Q38 215 44 229T70 243H169V284L149 341H38Q38 380 44 394T70 408H126L30 687Q28 694 32 696T59 699T122 700L161
|
182 |
+
563Q179 505 193 449T209 372Q211 392 226 451T259 563L297 685Q300 693 304 696T329 699T384 700L288 408H378Q378 370 372 356T347 341H266L249 290V243Z" />
|
183 |
+
<glyph unicode="¦" glyph-name="brokenbar" horiz-adv-x="227" d="M90 326T73 330V711Q73 729 82 736T115 743Q135 743 153 737V354Q153 337 146 332T112 326Q90 326 73 330ZM89 -198T73 -193V192Q73 210 82 217T115 225Q135 225 153 219V-169Q153 -187 146
|
184 |
+
-192T112 -198Q89 -198 73 -193Z" />
|
185 |
+
<glyph unicode="§" glyph-name="section" horiz-adv-x="348" d="M264 201Q284 174 292 155T301 112Q301 58 259 27T150 -4Q106 -4 78 9T43 39Q40 44 40 55Q40 83 56 105Q90 81 137 81Q171 81 190 94T209 128Q209 142 202 154T179 185Q179 185 141 223Q94
|
186 |
+
268 72 296Q53 320 45 340T36 388Q36 415 49 442T91 489L83 499Q63 524 55 543T46 587Q46 641 88 672T198 703Q242 703 269 690T304 661Q307 652 307 644Q307 617 291 595Q259 618 209 618Q175 618 157 605T138 571Q138 557 144 546T167 515Q181 500 202 480Q221
|
187 |
+
462 242 441T275 404Q295 380 303 360T311 312Q311 286 297 259T255 212L264 201ZM151 300T171 284T196 264Q214 271 225 287T236 318Q236 335 229 350T207 384Q196 399 176 415T151 435Q133 429 122 413T111 382Q111 363 118 348T140 315Q151 300 171 284Z" />
|
188 |
+
<glyph unicode="¨" glyph-name="dieresis" horiz-adv-x="269" d="M53 573T44 586T34 632Q34 659 45 674T78 689Q100 689 108 677T117 634Q117 604 106 588T73 572Q53 573 44 586ZM173 573T163 585T153 628Q153 689 197 689Q219 689 227 677T236 634Q234 572
|
189 |
+
192 572Q173 573 163 585Z" />
|
190 |
+
<glyph unicode="©" glyph-name="copyright" horiz-adv-x="471" d="M133 320T85 371T36 541Q36 652 89 706T242 760Q343 760 389 711T436 543Q436 435 384 378T234 320Q133 320 85 371ZM296 378T335 418T375 544Q375 628 342 666T241 705Q96 705 96 541Q96
|
191 |
+
452 129 415T232 378Q296 378 335 418ZM211 416T193 424T166 456T157 531Q157 613 183 640T249 668Q264 668 279 663T294 652Q294 644 288 620Q268 628 254 628Q231 628 218 609T204 529Q204 497 208 482T222 462T247 457Q266 457 286 467Q289 461 291 452T293
|
192 |
+
437Q293 430 277 423T243 416Q211 416 193 424Z" />
|
193 |
+
<glyph unicode="ª" glyph-name="ordfeminine" horiz-adv-x="323" d="M100 288T71 312T41 411Q41 478 69 506T150 534Q182 534 214 524V582Q214 615 198 627T152 639Q105 639 57 617Q47 630 47 652Q47 668 53 675Q85 710 176 710Q225 710 253 685T282 608V317Q259
|
194 |
+
306 224 297T154 288Q100 288 71 312ZM179 346T193 349T214 358V468Q206 472 194 474T172 476Q138 476 122 464T105 409Q105 373 120 360T165 346Q179 346 193 349Z" />
|
195 |
+
<glyph unicode="«" glyph-name="guillemotleft" horiz-adv-x="416" d="M156 16T120 70T51 181T18 253Q18 268 50 322T118 430T164 500Q178 500 188 491T205 472T212 459Q212 442 186 397T132 309T94 253Q103 240 132 198T187 109T214 47Q213 43 207 32T191
|
196 |
+
11T167 0Q156 16 120 70ZM326 38T291 86T223 185T190 251Q190 265 222 315T288 414T334 477Q347 477 357 469T374 451T381 439Q381 423 356 381T303 301T267 251Q276 240 303 203T357 125T383 69Q382 66 376 55T360 34T337 24Q326 38 291 86Z" />
|
197 |
+
<glyph unicode="¬" glyph-name="logicalnot" horiz-adv-x="400" d="M358 111Q342 105 321 105Q304 105 293 111T282 131V232H40Q34 252 34 270Q34 287 40 297T60 308H358V111Z" />
|
198 |
+
<glyph unicode="­" glyph-name="uni00AD" horiz-adv-x="278" d="M37 290T39 303T54 317H241Q241 275 239 261T225 247H37Q37 290 39 303Z" />
|
199 |
+
<glyph unicode="®" glyph-name="registered" horiz-adv-x="471" d="M343 760T389 711T436 543Q436 435 384 378T234 320Q133 320 85 371T36 541Q36 652 89 706T242 760Q343 760 389 711ZM296 378T335 418T375 544Q375 628 342 666T241 705Q96 705 96 541Q96
|
200 |
+
452 129 415T232 378Q296 378 335 418ZM288 517T300 492T315 426Q315 420 312 418T299 416Q281 416 274 417Q268 491 239 518Q235 517 227 517H214V425Q214 419 208 418T176 417V665Q176 666 177 668T183 670H227Q308 670 308 598Q308 550 274 529Q288 517 300
|
201 |
+
492ZM219 551T230 551Q249 551 258 562T268 600Q268 618 260 627T232 637H214V552Q219 551 230 551Z" />
|
202 |
+
<glyph unicode="¯" glyph-name="overscore" horiz-adv-x="269" d="M1 601T1 624Q1 642 10 652T34 663H261Q268 646 268 629Q268 611 260 599T238 587H6Q1 601 1 624Z" />
|
203 |
+
<glyph unicode="°" glyph-name="degree" horiz-adv-x="358" d="M129 553T107 573T84 649Q84 746 184 746Q233 746 254 725T276 650Q276 602 251 578T177 553Q129 553 107 573ZM223 604T223 650Q223 674 214 684T184 694Q161 694 150 684T138 648Q138 604
|
204 |
+
179 604Q223 604 223 650Z" />
|
205 |
+
<glyph unicode="±" glyph-name="plusminus" horiz-adv-x="419" d="M385 359Q385 317 383 303T369 289H246V165Q246 154 232 152T175 149V289H35Q35 332 37 345T52 359H175V483Q175 494 189 496T246 499V359H385ZM34 58T36 71T51 85H384Q384 43 382 29T368
|
206 |
+
15H34Q34 58 36 71Z" />
|
207 |
+
<glyph unicode="²" glyph-name="uni00B2" d="M41 301T41 315Q41 344 53 357Q77 385 138 444Q188 491 210 518T232 576Q232 600 219 614T168 628Q139 628 116 618T66 590Q57 606 54 616T51 639Q51 657 74 673T134 700T205 710Q274 710 302 683T330 604Q330
|
208 |
+
556 300 515T212 416Q170 373 162 365H339Q344 342 344 330Q344 289 318 289H47Q41 301 41 315Z" />
|
209 |
+
<glyph unicode="³" glyph-name="uni00B3" d="M304 503T322 478T340 423Q340 352 292 316T165 279Q126 279 98 286T57 305Q45 314 45 335Q45 347 50 359T64 379Q103 353 161 353Q205 353 231 369T257 416Q257 438 242 452T199 470Q181 473 128 473Q126 476
|
210 |
+
123 489T119 510Q119 535 144 535Q171 535 197 532Q218 548 227 562T236 594Q236 612 221 625T171 638Q113 638 67 605Q51 622 51 645Q51 663 61 671Q79 688 116 699T204 710Q266 710 295 686T325 620Q325 592 312 565T273 516Q304 503 322 478Z" />
|
211 |
+
<glyph unicode="´" glyph-name="acute" horiz-adv-x="271" d="M73 560T66 570T55 591T50 605Q82 641 129 681T184 722Q197 722 207 703T221 661Q209 648 158 611T81 560Q73 560 66 570Z" />
|
212 |
+
<glyph unicode="µ" glyph-name="uni00B5" horiz-adv-x="395" d="M70 -195T45 -190V470Q45 488 54 496T86 505Q110 505 125 500V131Q125 98 143 82T195 66Q237 66 269 81V470Q269 488 277 496T308 505Q334 505 349 500V24Q317 9 277 0T194 -10Q146 -10 125
|
213 |
+
15V-163Q125 -195 80 -195Q70 -195 45 -190Z" />
|
214 |
+
<glyph unicode="¶" glyph-name="paragraph" horiz-adv-x="541" d="M289 -3T271 3V205Q257 198 235 194T191 190Q121 190 78 242T34 420Q34 569 86 639T231 710Q298 710 352 682V26Q352 -3 312 -3Q289 -3 271 3ZM430 -3T414 2V658Q414 676 423 683T456 690Q477
|
215 |
+
690 495 684V26Q495 8 487 3T453 -3Q430 -3 414 2ZM226 255T243 258T271 269V630Q253 641 220 641Q169 641 143 588T116 428Q116 331 143 294T212 255Q226 255 243 258Z" />
|
216 |
+
<glyph unicode="·" glyph-name="middot" horiz-adv-x="220" d="M79 212T66 226T53 269Q53 293 68 309T109 326Q165 326 165 269Q165 244 150 228T109 212Q79 212 66 226Z" />
|
217 |
+
<glyph unicode="¸" glyph-name="cedilla" horiz-adv-x="269" d="M177 -58T191 -74T206 -122Q206 -160 184 -183T126 -206Q107 -206 89 -200T70 -193Q71 -188 75 -172T83 -152Q86 -149 101 -156T128 -163Q159 -163 159 -129Q159 -95 129 -95Q113 -95 102 -97T88
|
218 |
+
-101L107 2H152L140 -59Q141 -58 157 -58Q177 -58 191 -74Z" />
|
219 |
+
<glyph unicode="¹" glyph-name="uni00B9" horiz-adv-x="382" d="M45 308T45 323Q45 345 50 355T72 365H166V622L58 600Q48 616 48 638Q48 666 74 676Q109 688 157 699T223 710Q241 710 247 707V365H334Q338 339 338 329Q338 307 333 298T313 289H49Q45 308 45 323Z" />
|
220 |
+
<glyph unicode="º" glyph-name="ordmasculine" horiz-adv-x="338" d="M121 289T93 307T50 372T35 499Q35 607 71 658T174 710Q220 710 247 692T289 628T303 501Q303 394 268 342T165 289Q121 289 93 307ZM200 356T217 389T235 499Q235 580 221 609T175 639Q139
|
221 |
+
639 121 606T103 494Q103 414 118 385T166 356Q200 356 217 389Z" />
|
222 |
+
<glyph unicode="»" glyph-name="guillemotright" horiz-adv-x="414" d="M244 1T233 6T211 21T200 46Q200 62 227 108T283 197T321 253Q312 266 284 308T229 396T203 459Q203 471 213 480T235 494T251 500Q262 484 297 431T364 323T396 253Q396 237 363 181T295
|
223 |
+
71T248 0Q244 1 233 6ZM73 23T63 28T43 43T33 68Q33 84 59 124T112 202T149 250Q152 250 126 284Q84 343 60 382T35 439Q35 451 45 460T65 474T79 480Q90 465 125 416T192 316T224 250Q224 234 191 184T123 85T76 22Q73 23 63 28Z" />
|
224 |
+
<glyph unicode="¼" glyph-name="onequarter" horiz-adv-x="959" d="M41 307T41 323Q41 345 46 355T68 365H162V622L54 600Q44 616 44 638Q44 665 71 676Q105 688 153 699T219 710Q237 710 244 707V365H330Q334 348 334 329Q334 307 329 298T310 289H46Q41
|
225 |
+
307 41 323ZM324 -10T309 -2T281 19L617 691Q625 710 645 710Q658 710 673 703T700 682L361 5Q355 -10 337 -10Q324 -10 309 -2ZM808 -6T792 -2V70H621Q607 85 607 110Q607 125 614 143Q632 202 677 275T764 390Q780 409 796 415T834 421Q853 421 868 416V147H927Q934
|
226 |
+
130 934 109Q934 91 927 81T909 70H868V19Q868 -6 825 -6Q808 -6 792 -2ZM795 141L799 329Q766 303 731 247T682 141H795Z" />
|
227 |
+
<glyph unicode="½" glyph-name="onehalf" horiz-adv-x="947" d="M41 307T41 323Q41 345 46 355T68 365H162V622L54 600Q44 616 44 638Q44 665 71 676Q105 688 153 699T219 710Q237 710 244 707V365H330Q334 348 334 329Q334 307 329 298T310 289H46Q41 307
|
228 |
+
41 323ZM324 -10T309 -2T281 19L617 691Q625 710 645 710Q658 710 673 703T700 682L361 5Q355 -10 337 -10Q324 -10 309 -2ZM607 12T607 26Q607 55 619 68Q643 96 704 155Q754 202 776 229T798 287Q798 311 785 325T734 339Q706 339 682 329T632 301Q623 317 621
|
229 |
+
327T618 350Q618 368 641 384T700 411T771 421Q840 421 868 394T896 315Q896 281 879 249T839 190T776 125Q735 84 728 76H905Q910 53 910 41Q910 0 884 0H613Q607 12 607 26Z" />
|
230 |
+
<glyph unicode="¾" glyph-name="threequarters" horiz-adv-x="961" d="M300 503T318 478T336 423Q336 352 288 316T161 279Q122 279 95 286T54 305Q41 314 41 335Q41 347 46 359T61 379Q98 353 158 353Q202 353 227 369T253 416Q253 438 238 452T196 470Q177
|
231 |
+
473 124 473Q122 476 119 489T115 510Q115 535 140 535Q169 535 194 532Q215 547 223 561T232 594Q232 612 217 625T168 638Q109 638 64 605Q48 622 48 646Q48 664 57 671Q75 688 112 699T201 710Q262 710 291 686T321 620Q321 592 308 565T269 516Q300 503 318
|
232 |
+
478ZM326 -10T311 -2T283 19L619 691Q627 710 647 710Q660 710 675 703T702 682L363 5Q357 -10 339 -10Q326 -10 311 -2ZM810 -6T794 -2V70H623Q609 85 609 110Q609 125 616 143Q634 202 679 275T766 390Q782 409 798 415T836 421Q855 421 870 416V147H929Q936
|
233 |
+
130 936 109Q936 91 929 81T911 70H870V19Q870 -6 827 -6Q810 -6 794 -2ZM797 141L801 329Q768 303 733 247T684 141H797Z" />
|
234 |
+
<glyph unicode="¿" glyph-name="questiondown" horiz-adv-x="306" d="M138 392T125 407T111 450Q111 474 126 490T167 506Q197 506 210 492T223 450Q223 426 208 409T167 392Q138 392 125 407ZM89 -195T52 -160T14 -56Q14 3 33 43T89 131Q117 170 125 184Q137
|
235 |
+
205 137 232Q137 242 132 272Q130 281 130 288T131 298Q141 308 176 308Q188 308 204 306Q205 304 208 295T215 270T219 236Q219 198 201 163Q186 135 156 93Q127 49 114 23T101 -37Q101 -114 182 -114Q228 -114 266 -89Q278 -119 278 -153Q278 -170 239 -182T153
|
236 |
+
-195Q89 -195 52 -160Z" />
|
237 |
+
<glyph unicode="À" glyph-name="Agrave" horiz-adv-x="437" d="M433 6T426 2T396 -2Q369 -2 348 0L306 178H132L93 14Q90 5 84 2T55 -2Q34 -2 5 1L184 689Q187 703 214 703Q237 703 252 700L431 15Q433 6 426 2ZM288 251L254 395Q225 517 219 588Q208 499
|
238 |
+
183 395L149 251H288ZM253 768T202 804T140 855Q144 877 154 896T177 916Q184 916 232 875T311 798Q310 795 306 784T295 763T280 753Q253 768 202 804Z" />
|
239 |
+
<glyph unicode="Á" glyph-name="Aacute" horiz-adv-x="437" d="M433 6T426 2T396 -2Q369 -2 348 0L306 178H132L93 14Q90 5 84 2T55 -2Q34 -2 5 1L184 689Q187 703 214 703Q237 703 252 700L431 15Q433 6 426 2ZM288 251L254 395Q225 517 219 588Q208 499
|
240 |
+
183 395L149 251H288ZM163 760T156 770T145 791T140 805Q172 841 219 881T274 922Q287 922 297 903T311 861Q299 848 248 811T171 760Q163 760 156 770Z" />
|
241 |
+
<glyph unicode="Â" glyph-name="Acircumflex" horiz-adv-x="437" d="M433 6T426 2T396 -2Q369 -2 348 0L306 178H132L93 14Q90 5 84 2T55 -2Q34 -2 5 1L184 689Q187 703 214 703Q237 703 252 700L431 15Q433 6 426 2ZM288 251L254 395Q225 517 219 588Q208
|
242 |
+
499 183 395L149 251H288ZM279 770T255 796T222 838Q218 832 203 814T172 779T147 762Q111 762 92 785L206 908Q214 911 223 911Q237 911 248 899Q255 892 278 867T323 817T345 784Q345 774 328 768T288 761Q279 770 255 796Z" />
|
243 |
+
<glyph unicode="Ã" glyph-name="Atilde" horiz-adv-x="437" d="M433 6T426 2T396 -2Q369 -2 348 0L306 178H132L93 14Q90 5 84 2T55 -2Q34 -2 5 1L184 689Q187 703 214 703Q237 703 252 700L431 15Q433 6 426 2ZM288 251L254 395Q225 517 219 588Q208 499
|
244 |
+
183 395L149 251H288ZM238 763T227 770T205 790Q195 801 188 806T170 811Q156 811 147 804T127 785T111 772Q101 772 93 781T79 799T72 812Q96 851 125 869T185 887Q200 887 209 881T230 863Q241 851 250 845T272 839Q292 839 302 846T322 866T337 878Q345 878
|
245 |
+
351 868T361 847T366 833Q362 824 347 808T309 777T258 763Q238 763 227 770Z" />
|
246 |
+
<glyph unicode="Ä" glyph-name="Adieresis" horiz-adv-x="437" d="M433 6T426 2T396 -2Q369 -2 348 0L306 178H132L93 14Q90 5 84 2T55 -2Q34 -2 5 1L184 689Q187 703 214 703Q237 703 252 700L431 15Q433 6 426 2ZM288 251L254 395Q225 517 219 588Q208
|
247 |
+
499 183 395L149 251H288ZM137 773T128 786T118 832Q118 859 129 874T162 889Q184 889 192 877T201 834Q201 804 190 788T157 772Q137 773 128 786ZM257 773T247 785T237 828Q237 889 281 889Q303 889 311 877T320 834Q318 772 276 772Q257 773 247 785Z" />
|
248 |
+
<glyph unicode="Å" glyph-name="Aring" horiz-adv-x="437" d="M433 6T426 2T396 -2Q369 -2 348 0L306 178H132L93 14Q90 5 84 2T55 -2Q34 -2 5 1L184 689Q187 703 214 703Q237 703 252 700L431 15Q433 6 426 2ZM288 251L254 395Q225 517 219 588Q208 499
|
249 |
+
183 395L149 251H288ZM169 743T146 764T123 839Q123 888 149 912T223 937Q271 937 293 916T315 840Q315 792 290 768T216 743Q169 743 146 764ZM259 797T259 840Q259 862 250 871T223 881Q180 881 180 838Q180 818 189 808T218 797Q259 797 259 840Z" />
|
250 |
+
<glyph unicode="Æ" glyph-name="AE" horiz-adv-x="615" d="M420 73H592Q592 44 592 26T588 4T576 0H340V178H174L105 14Q102 5 95 2T68 -2Q45 -2 17 1L311 686Q317 700 337 700H596Q596 672 596 654T592 632T581 627H420V418H571Q571 391 571 373T567 350T556
|
251 |
+
344H420V73ZM340 251V615Q304 490 264 392L205 251H340Z" />
|
252 |
+
<glyph unicode="Ç" glyph-name="Ccedilla" horiz-adv-x="341" d="M243 79T268 88T308 111Q320 85 320 62Q320 35 293 15T220 -9L210 -59Q211 -58 227 -58Q247 -58 261 -74T276 -122Q276 -160 254 -183T196 -206Q177 -206 159 -200T140 -193Q141 -188 145
|
253 |
+
-172T153 -152Q156 -149 171 -156T198 -163Q229 -163 229 -129Q229 -95 199 -95Q183 -95 172 -97T158 -101L175 -9Q128 -6 97 21T48 120T30 321Q30 480 59 566T130 681T227 710Q277 710 299 694T321 655Q321 628 308 606Q277 631 243 631Q206 631 178 608T133 517T115
|
254 |
+
325Q115 227 127 173T161 99T215 79Q243 79 268 88Z" />
|
255 |
+
<glyph unicode="È" glyph-name="Egrave" horiz-adv-x="320" d="M125 73H297Q297 44 297 26T293 4T281 0H45V684Q45 688 48 694T61 700H301Q301 672 301 654T297 632T286 627H125V418H276Q276 391 276 373T272 350T261 344H125V73ZM204 768T153 804T91 855Q95
|
256 |
+
877 105 896T128 916Q135 916 183 875T262 798Q261 795 257 784T246 763T231 753Q204 768 153 804Z" />
|
257 |
+
<glyph unicode="É" glyph-name="Eacute" horiz-adv-x="320" d="M125 73H297Q297 44 297 26T293 4T281 0H45V684Q45 688 48 694T61 700H301Q301 672 301 654T297 632T286 627H125V418H276Q276 391 276 373T272 350T261 344H125V73ZM114 760T107 770T96 791T91
|
258 |
+
805Q123 841 170 881T225 922Q238 922 248 903T262 861Q250 848 199 811T122 760Q114 760 107 770Z" />
|
259 |
+
<glyph unicode="Ê" glyph-name="Ecircumflex" horiz-adv-x="320" d="M125 73H297Q297 44 297 26T293 4T281 0H45V684Q45 688 48 694T61 700H301Q301 672 301 654T297 632T286 627H125V418H276Q276 391 276 373T272 350T261 344H125V73ZM230 770T206 796T173
|
260 |
+
838Q169 832 154 814T123 779T98 762Q62 762 43 785L157 908Q165 911 174 911Q188 911 199 899Q206 892 229 867T274 817T296 784Q296 774 279 768T239 761Q230 770 206 796Z" />
|
261 |
+
<glyph unicode="Ë" glyph-name="Edieresis" horiz-adv-x="320" d="M125 73H297Q297 44 297 26T293 4T281 0H45V684Q45 688 48 694T61 700H301Q301 672 301 654T297 632T286 627H125V418H276Q276 391 276 373T272 350T261 344H125V73ZM88 773T79 786T69 832Q69
|
262 |
+
859 80 874T113 889Q135 889 143 877T152 834Q152 804 141 788T108 772Q88 773 79 786ZM208 773T198 785T188 828Q188 889 232 889Q254 889 262 877T271 834Q269 772 227 772Q208 773 198 785Z" />
|
263 |
+
<glyph unicode="Ì" glyph-name="Igrave" horiz-adv-x="169" d="M44 663Q44 683 48 690T66 698T126 700V16Q126 7 122 4T98 1T44 0V663ZM119 768T68 804T6 855Q10 877 20 896T43 916Q50 916 98 875T177 798Q176 795 172 784T161 763T146 753Q119 768 68 804Z" />
|
264 |
+
<glyph unicode="Í" glyph-name="Iacute" horiz-adv-x="169" d="M44 663Q44 683 48 690T66 698T126 700V16Q126 7 122 4T98 1T44 0V663ZM29 760T22 770T11 791T6 805Q38 841 85 881T140 922Q153 922 163 903T177 861Q165 848 114 811T37 760Q29 760 22 770Z" />
|
265 |
+
<glyph unicode="Î" glyph-name="Icircumflex" horiz-adv-x="169" d="M44 663Q44 683 48 690T66 698T126 700V16Q126 7 122 4T98 1T44 0V663ZM145 770T121 796T88 838Q84 832 69 814T38 779T13 762Q-23 762 -42 785L72 908Q80 911 89 911Q103 911 114 899Q121
|
266 |
+
892 144 867T189 817T211 784Q211 774 194 768T154 761Q145 770 121 796Z" />
|
267 |
+
<glyph unicode="Ï" glyph-name="Idieresis" horiz-adv-x="169" d="M44 663Q44 683 48 690T66 698T126 700V16Q126 7 122 4T98 1T44 0V663ZM3 773T-6 786T-16 832Q-16 859 -5 874T28 889Q50 889 58 877T67 834Q67 804 56 788T23 772Q3 773 -6 786ZM123 773T113
|
268 |
+
785T103 828Q103 889 147 889Q169 889 177 877T186 834Q184 772 142 772Q123 773 113 785Z" />
|
269 |
+
<glyph unicode="Ð" glyph-name="Eth" horiz-adv-x="388" d="M237 700T279 672T342 577T364 394Q364 247 342 160T276 37T169 0H44V331H5Q5 374 7 387T21 401H44V681Q44 691 50 695T71 700H169Q237 700 279 672ZM201 77T223 100T259 193T273 394Q273 485 262
|
270 |
+
535T229 606T171 626H125V401H205Q205 359 203 345T188 331H125V77H171Q201 77 223 100Z" />
|
271 |
+
<glyph unicode="Ñ" glyph-name="Ntilde" horiz-adv-x="444" d="M320 693T324 696T348 699T401 700V16Q401 0 384 0H324L209 275Q185 339 114 560Q118 517 121 416T124 259V16Q124 7 121 4T97 1T44 0V684Q44 700 60 700H121L234 430Q247 395 308 211Q312 199
|
272 |
+
330 146V149Q325 188 323 290T320 448V684Q320 693 324 696ZM241 763T230 770T208 790Q198 801 191 806T173 811Q159 811 150 804T130 785T114 772Q104 772 96 781T82 799T75 812Q99 851 128 869T188 887Q203 887 212 881T233 863Q244 851 253 845T275 839Q295
|
273 |
+
839 305 846T325 866T340 878Q348 878 354 868T364 847T369 833Q365 824 350 808T312 777T261 763Q241 763 230 770Z" />
|
274 |
+
<glyph unicode="Ò" glyph-name="Ograve" horiz-adv-x="429" d="M143 -10T105 21T48 131T30 354Q30 486 50 564T113 676T222 710Q288 710 326 678T381 569T399 357Q399 220 380 140T319 25T211 -10Q143 -10 105 21ZM251 73T272 101T302 190T312 355Q312 459
|
275 |
+
304 517T276 601T220 627Q184 627 163 599T131 507T121 334Q121 238 129 182T158 99T214 73Q251 73 272 101ZM249 768T198 804T136 855Q140 877 150 896T173 916Q180 916 228 875T307 798Q306 795 302 784T291 763T276 753Q249 768 198 804Z" />
|
276 |
+
<glyph unicode="Ó" glyph-name="Oacute" horiz-adv-x="429" d="M143 -10T105 21T48 131T30 354Q30 486 50 564T113 676T222 710Q288 710 326 678T381 569T399 357Q399 220 380 140T319 25T211 -10Q143 -10 105 21ZM251 73T272 101T302 190T312 355Q312 459
|
277 |
+
304 517T276 601T220 627Q184 627 163 599T131 507T121 334Q121 238 129 182T158 99T214 73Q251 73 272 101ZM159 760T152 770T141 791T136 805Q168 841 215 881T270 922Q283 922 293 903T307 861Q295 848 244 811T167 760Q159 760 152 770Z" />
|
278 |
+
<glyph unicode="Ô" glyph-name="Ocircumflex" horiz-adv-x="429" d="M143 -10T105 21T48 131T30 354Q30 486 50 564T113 676T222 710Q288 710 326 678T381 569T399 357Q399 220 380 140T319 25T211 -10Q143 -10 105 21ZM251 73T272 101T302 190T312 355Q312
|
279 |
+
459 304 517T276 601T220 627Q184 627 163 599T131 507T121 334Q121 238 129 182T158 99T214 73Q251 73 272 101ZM275 770T251 796T218 838Q214 832 199 814T168 779T143 762Q107 762 88 785L202 908Q210 911 219 911Q233 911 244 899Q251 892 274 867T319 817T341
|
280 |
+
784Q341 774 324 768T284 761Q275 770 251 796Z" />
|
281 |
+
<glyph unicode="Õ" glyph-name="Otilde" horiz-adv-x="429" d="M143 -10T105 21T48 131T30 354Q30 486 50 564T113 676T222 710Q288 710 326 678T381 569T399 357Q399 220 380 140T319 25T211 -10Q143 -10 105 21ZM251 73T272 101T302 190T312 355Q312 459
|
282 |
+
304 517T276 601T220 627Q184 627 163 599T131 507T121 334Q121 238 129 182T158 99T214 73Q251 73 272 101ZM234 763T223 770T201 790Q191 801 184 806T166 811Q152 811 143 804T123 785T107 772Q97 772 89 781T75 799T68 812Q92 851 121 869T181 887Q196 887
|
283 |
+
205 881T226 863Q237 851 246 845T268 839Q288 839 298 846T318 866T333 878Q341 878 347 868T357 847T362 833Q358 824 343 808T305 777T254 763Q234 763 223 770Z" />
|
284 |
+
<glyph unicode="Ö" glyph-name="Odieresis" horiz-adv-x="429" d="M143 -10T105 21T48 131T30 354Q30 486 50 564T113 676T222 710Q288 710 326 678T381 569T399 357Q399 220 380 140T319 25T211 -10Q143 -10 105 21ZM251 73T272 101T302 190T312 355Q312
|
285 |
+
459 304 517T276 601T220 627Q184 627 163 599T131 507T121 334Q121 238 129 182T158 99T214 73Q251 73 272 101ZM133 773T124 786T114 832Q114 859 125 874T158 889Q180 889 188 877T197 834Q197 804 186 788T153 772Q133 773 124 786ZM253 773T243 785T233 828Q233
|
286 |
+
889 277 889Q299 889 307 877T316 834Q314 772 272 772Q253 773 243 785Z" />
|
287 |
+
<glyph unicode="×" glyph-name="multiply" horiz-adv-x="418" d="M257 281L345 183Q319 157 309 149T292 140Q290 140 284 144L209 228L133 144Q127 140 125 140Q118 140 108 148T72 183L160 281L71 381Q76 386 90 399T111 418T124 423Q129 423 133 419L209
|
288 |
+
335L284 419Q288 423 293 423Q300 423 308 416T329 398T346 381L257 281Z" />
|
289 |
+
<glyph unicode="Ø" glyph-name="Oslash" horiz-adv-x="436" d="M415 685T381 585Q403 506 403 357Q403 220 383 140T322 25T214 -10Q174 -10 145 0T94 35Q81 -1 73 -16Q59 -16 43 -9T24 9Q23 12 35 44T59 102Q33 183 33 354Q33 486 53 564T114 676T222 710Q262
|
290 |
+
710 291 699T341 664Q359 712 363 719Q367 719 378 717T401 709T414 694Q415 685 381 585ZM186 628T165 600T134 507T124 334Q124 228 132 176L281 599Q261 628 222 628Q186 628 165 600ZM247 73T269 95T303 178T315 355Q315 463 307 516Q249 349 157 98Q176 73
|
291 |
+
211 73Q247 73 269 95Z" />
|
292 |
+
<glyph unicode="Ù" glyph-name="Ugrave" horiz-adv-x="437" d="M148 -10T109 18T57 91T44 205V683Q44 692 47 695T71 699T127 700V202Q127 133 146 99T224 65Q249 65 274 70T312 82V683Q312 692 316 695T340 699T394 700V26Q373 12 326 1T224 -10Q148 -10
|
293 |
+
109 18ZM253 768T202 804T140 855Q144 877 154 896T177 916Q184 916 232 875T311 798Q310 795 306 784T295 763T280 753Q253 768 202 804Z" />
|
294 |
+
<glyph unicode="Ú" glyph-name="Uacute" horiz-adv-x="437" d="M148 -10T109 18T57 91T44 205V683Q44 692 47 695T71 699T127 700V202Q127 133 146 99T224 65Q249 65 274 70T312 82V683Q312 692 316 695T340 699T394 700V26Q373 12 326 1T224 -10Q148 -10
|
295 |
+
109 18ZM163 760T156 770T145 791T140 805Q172 841 219 881T274 922Q287 922 297 903T311 861Q299 848 248 811T171 760Q163 760 156 770Z" />
|
296 |
+
<glyph unicode="Û" glyph-name="Ucircumflex" horiz-adv-x="437" d="M148 -10T109 18T57 91T44 205V683Q44 692 47 695T71 699T127 700V202Q127 133 146 99T224 65Q249 65 274 70T312 82V683Q312 692 316 695T340 699T394 700V26Q373 12 326 1T224 -10Q148
|
297 |
+
-10 109 18ZM279 770T255 796T222 838Q218 832 203 814T172 779T147 762Q111 762 92 785L206 908Q214 911 223 911Q237 911 248 899Q255 892 278 867T323 817T345 784Q345 774 328 768T288 761Q279 770 255 796Z" />
|
298 |
+
<glyph unicode="Ü" glyph-name="Udieresis" horiz-adv-x="437" d="M148 -10T109 18T57 91T44 205V683Q44 692 47 695T71 699T127 700V202Q127 133 146 99T224 65Q249 65 274 70T312 82V683Q312 692 316 695T340 699T394 700V26Q373 12 326 1T224 -10Q148
|
299 |
+
-10 109 18ZM137 773T128 786T118 832Q118 859 129 874T162 889Q184 889 192 877T201 834Q201 804 190 788T157 772Q137 773 128 786ZM257 773T247 785T237 828Q237 889 281 889Q303 889 311 877T320 834Q318 772 276 772Q257 773 247 785Z" />
|
300 |
+
<glyph unicode="Ý" glyph-name="Yacute" horiz-adv-x="364" d="M225 16Q225 7 222 4T198 1T144 0V285L6 687Q4 694 8 696T35 699T97 700L137 563Q152 516 168 446T187 353Q189 375 206 445T238 563L273 685Q275 693 279 696T304 699T360 700L225 290V16ZM126
|
301 |
+
760T119 770T108 791T103 805Q135 841 182 881T237 922Q250 922 260 903T274 861Q262 848 211 811T134 760Q126 760 119 770Z" />
|
302 |
+
<glyph unicode="Þ" glyph-name="Thorn" horiz-adv-x="361" d="M44 680Q44 693 54 696T98 700H124V566H159Q254 566 298 519T343 369Q343 253 293 202T160 150H124V16Q124 7 120 4T96 1T44 0V680ZM212 225T233 260T254 378Q254 435 236 465T174 495Q139 495
|
303 |
+
124 493V228Q131 228 144 227T168 225Q212 225 233 260Z" />
|
304 |
+
<glyph unicode="ß" glyph-name="germandbls" horiz-adv-x="465" d="M65 -9T52 -4T39 2Q40 4 42 13T47 38T50 74L48 550Q48 629 90 667T208 705Q277 705 322 685T388 631T409 561Q409 529 394 510T348 467Q323 449 312 436T300 403Q300 385 313 368T355 325Q387
|
305 |
+
294 407 270T441 213T456 138Q456 70 416 31T306 -9Q269 -9 242 -2T201 15T187 36Q187 69 208 90Q217 81 238 72T288 63Q324 63 345 82T366 137Q366 172 347 201T288 270Q250 309 231 337T212 399Q212 432 228 452T276 497Q300 515 311 528T323 560Q323 589 295
|
306 |
+
609T214 630Q166 630 148 601T129 504L131 44Q131 14 122 3T84 -9Q65 -9 52 -4Z" />
|
307 |
+
<glyph unicode="à" glyph-name="agrave" horiz-adv-x="354" d="M102 -10T66 20T29 142Q29 237 65 271T163 306Q210 306 236 293V372Q236 406 221 419T174 432Q138 432 101 426T41 409Q30 430 30 456Q30 476 41 483Q56 493 99 501T194 510Q259 510 288 482T317
|
308 |
+
388V335Q317 115 311 24Q287 9 250 0T166 -10Q102 -10 66 20ZM196 58T211 63T233 74Q236 108 236 236Q217 246 189 246Q153 246 133 225T113 144Q113 93 129 76T180 58Q196 58 211 63ZM209 568T158 604T96 655Q100 677 110 696T133 716Q140 716 188 675T267 598Q266
|
309 |
+
595 262 584T251 563T236 553Q209 568 158 604Z" />
|
310 |
+
<glyph unicode="á" glyph-name="aacute" horiz-adv-x="354" d="M102 -10T66 20T29 142Q29 237 65 271T163 306Q210 306 236 293V372Q236 406 221 419T174 432Q138 432 101 426T41 409Q30 430 30 456Q30 476 41 483Q56 493 99 501T194 510Q259 510 288 482T317
|
311 |
+
388V335Q317 115 311 24Q287 9 250 0T166 -10Q102 -10 66 20ZM196 58T211 63T233 74Q236 108 236 236Q217 246 189 246Q153 246 133 225T113 144Q113 93 129 76T180 58Q196 58 211 63ZM119 560T112 570T101 591T96 605Q128 641 175 681T230 722Q243 722 253 703T267
|
312 |
+
661Q255 648 204 611T127 560Q119 560 112 570Z" />
|
313 |
+
<glyph unicode="â" glyph-name="acircumflex" horiz-adv-x="354" d="M102 -10T66 20T29 142Q29 237 65 271T163 306Q210 306 236 293V372Q236 406 221 419T174 432Q138 432 101 426T41 409Q30 430 30 456Q30 476 41 483Q56 493 99 501T194 510Q259 510 288
|
314 |
+
482T317 388V335Q317 115 311 24Q287 9 250 0T166 -10Q102 -10 66 20ZM196 58T211 63T233 74Q236 108 236 236Q217 246 189 246Q153 246 133 225T113 144Q113 93 129 76T180 58Q196 58 211 63ZM235 570T211 596T178 638Q174 632 159 614T128 579T103 562Q67 562
|
315 |
+
48 585L162 708Q170 711 179 711Q193 711 204 699Q211 692 234 667T279 617T301 584Q301 574 284 568T244 561Q235 570 211 596Z" />
|
316 |
+
<glyph unicode="ã" glyph-name="atilde" horiz-adv-x="354" d="M102 -10T66 20T29 142Q29 237 65 271T163 306Q210 306 236 293V372Q236 406 221 419T174 432Q138 432 101 426T41 409Q30 430 30 456Q30 476 41 483Q56 493 99 501T194 510Q259 510 288 482T317
|
317 |
+
388V335Q317 115 311 24Q287 9 250 0T166 -10Q102 -10 66 20ZM196 58T211 63T233 74Q236 108 236 236Q217 246 189 246Q153 246 133 225T113 144Q113 93 129 76T180 58Q196 58 211 63ZM194 563T183 570T161 590Q151 601 144 606T126 611Q112 611 103 604T83 585T67
|
318 |
+
572Q57 572 49 581T35 599T28 612Q52 651 81 669T141 687Q156 687 165 681T186 663Q197 651 206 645T228 639Q248 639 258 646T278 666T293 678Q301 678 307 668T317 647T322 633Q318 624 303 608T265 577T214 563Q194 563 183 570Z" />
|
319 |
+
<glyph unicode="ä" glyph-name="adieresis" horiz-adv-x="354" d="M102 -10T66 20T29 142Q29 237 65 271T163 306Q210 306 236 293V372Q236 406 221 419T174 432Q138 432 101 426T41 409Q30 430 30 456Q30 476 41 483Q56 493 99 501T194 510Q259 510 288
|
320 |
+
482T317 388V335Q317 115 311 24Q287 9 250 0T166 -10Q102 -10 66 20ZM196 58T211 63T233 74Q236 108 236 236Q217 246 189 246Q153 246 133 225T113 144Q113 93 129 76T180 58Q196 58 211 63ZM93 573T84 586T74 632Q74 659 85 674T118 689Q140 689 148 677T157
|
321 |
+
634Q157 604 146 588T113 572Q93 573 84 586ZM213 573T203 585T193 628Q193 689 237 689Q259 689 267 677T276 634Q274 572 232 572Q213 573 203 585Z" />
|
322 |
+
<glyph unicode="å" glyph-name="aring" horiz-adv-x="354" d="M102 -10T66 20T29 142Q29 237 65 271T163 306Q210 306 236 293V372Q236 406 221 419T174 432Q138 432 101 426T41 409Q30 430 30 456Q30 476 41 483Q56 493 99 501T194 510Q259 510 288 482T317
|
323 |
+
388V335Q317 115 311 24Q287 9 250 0T166 -10Q102 -10 66 20ZM196 58T211 63T233 74Q236 108 236 236Q217 246 189 246Q153 246 133 225T113 144Q113 93 129 76T180 58Q196 58 211 63ZM125 543T102 564T79 639Q79 688 105 712T179 737Q227 737 249 716T271 640Q271
|
324 |
+
592 246 568T172 543Q125 543 102 564ZM215 597T215 640Q215 662 206 671T179 681Q136 681 136 638Q136 618 145 608T174 597Q215 597 215 640Z" />
|
325 |
+
<glyph unicode="æ" glyph-name="ae" horiz-adv-x="583" d="M478 69T532 100Q539 79 539 28Q539 21 520 13T468 -2T401 -9Q367 -9 344 -3T302 20Q255 -9 164 -9Q122 -9 94 1T47 46T29 148Q29 319 160 319Q210 319 236 306V378Q236 412 218 425T168 438Q93
|
326 |
+
438 42 411Q32 429 32 459Q32 466 35 472T42 483Q58 494 98 502T197 510Q238 510 262 497T296 453Q317 487 346 498T418 510Q545 510 545 351Q545 270 534 220Q497 214 445 214Q383 214 324 225Q324 157 333 124T360 80T410 69Q478 69 532 100ZM376 439T354 406T326
|
327 |
+
289Q388 277 426 277Q446 277 462 280Q467 303 467 342Q466 397 454 418T409 439Q376 439 354 406ZM236 250Q217 258 189 258Q154 258 134 235T113 149Q113 110 121 90T142 64T178 58Q195 58 212 62T236 74V250Z" />
|
328 |
+
<glyph unicode="ç" glyph-name="ccedilla" horiz-adv-x="313" d="M227 62T248 68T284 85Q292 56 292 41Q292 20 262 6T184 -10L174 -59Q175 -58 191 -58Q211 -58 225 -74T240 -122Q240 -160 218 -183T160 -206Q141 -206 123 -200T104 -193Q105 -188 109 -172T117
|
329 |
+
-152Q120 -149 135 -156T162 -163Q193 -163 193 -129Q193 -95 163 -95Q147 -95 136 -97T122 -101L139 -7Q102 -1 79 23T43 99T31 239Q31 400 81 455T210 510Q246 510 270 497T294 465Q294 442 285 420Q251 439 214 439Q170 439 142 399T114 238Q114 169 123 131T152
|
330 |
+
77T204 62Q227 62 248 68Z" />
|
331 |
+
<glyph unicode="è" glyph-name="egrave" horiz-adv-x="361" d="M267 68T321 100Q328 78 328 45Q328 22 288 6T190 -10Q139 -10 105 9T50 79T30 224Q30 341 54 404T117 488T207 510Q334 510 334 350Q334 270 323 220Q279 211 221 208T113 204Q115 150 125
|
332 |
+
121T155 80T207 68Q267 68 321 100ZM162 439T140 402T114 268Q213 268 251 280Q256 303 256 340Q255 396 243 417T198 439Q162 439 140 402ZM223 568T172 604T110 655Q114 677 124 696T147 716Q154 716 202 675T281 598Q280 595 276 584T265 563T250 553Q223 568
|
333 |
+
172 604Z" />
|
334 |
+
<glyph unicode="é" glyph-name="eacute" horiz-adv-x="361" d="M267 68T321 100Q328 78 328 45Q328 22 288 6T190 -10Q139 -10 105 9T50 79T30 224Q30 341 54 404T117 488T207 510Q334 510 334 350Q334 270 323 220Q279 211 221 208T113 204Q115 150 125
|
335 |
+
121T155 80T207 68Q267 68 321 100ZM162 439T140 402T114 268Q213 268 251 280Q256 303 256 340Q255 396 243 417T198 439Q162 439 140 402ZM133 560T126 570T115 591T110 605Q142 641 189 681T244 722Q257 722 267 703T281 661Q269 648 218 611T141 560Q133 560
|
336 |
+
126 570Z" />
|
337 |
+
<glyph unicode="ê" glyph-name="ecircumflex" horiz-adv-x="361" d="M267 68T321 100Q328 78 328 45Q328 22 288 6T190 -10Q139 -10 105 9T50 79T30 224Q30 341 54 404T117 488T207 510Q334 510 334 350Q334 270 323 220Q279 211 221 208T113 204Q115 150
|
338 |
+
125 121T155 80T207 68Q267 68 321 100ZM162 439T140 402T114 268Q213 268 251 280Q256 303 256 340Q255 396 243 417T198 439Q162 439 140 402ZM249 570T225 596T192 638Q188 632 173 614T142 579T117 562Q81 562 62 585L176 708Q184 711 193 711Q207 711 218
|
339 |
+
699Q225 692 248 667T293 617T315 584Q315 574 298 568T258 561Q249 570 225 596Z" />
|
340 |
+
<glyph unicode="ë" glyph-name="edieresis" horiz-adv-x="361" d="M267 68T321 100Q328 78 328 45Q328 22 288 6T190 -10Q139 -10 105 9T50 79T30 224Q30 341 54 404T117 488T207 510Q334 510 334 350Q334 270 323 220Q279 211 221 208T113 204Q115 150 125
|
341 |
+
121T155 80T207 68Q267 68 321 100ZM162 439T140 402T114 268Q213 268 251 280Q256 303 256 340Q255 396 243 417T198 439Q162 439 140 402ZM107 573T98 586T88 632Q88 659 99 674T132 689Q154 689 162 677T171 634Q171 604 160 588T127 572Q107 573 98 586ZM227
|
342 |
+
573T217 585T207 628Q207 689 251 689Q273 689 281 677T290 634Q288 572 246 572Q227 573 217 585Z" />
|
343 |
+
<glyph unicode="ì" glyph-name="igrave" horiz-adv-x="175" d="M47 463Q47 482 53 489T75 498T128 500V16Q128 7 125 4T101 1T47 0V463ZM377 568T326 604T264 655Q268 677 278 696T301 716Q308 716 356 675T435 598Q434 595 430 584T419 563T404 553Q377
|
344 |
+
568 326 604Z" />
|
345 |
+
<glyph unicode="í" glyph-name="iacute" horiz-adv-x="175" d="M47 463Q47 482 53 489T75 498T128 500V16Q128 7 125 4T101 1T47 0V463ZM31 560T24 570T13 591T8 605Q40 641 87 681T142 722Q155 722 165 703T179 661Q167 648 116 611T39 560Q31 560 24 570Z" />
|
346 |
+
<glyph unicode="î" glyph-name="icircumflex" horiz-adv-x="175" d="M47 463Q47 482 53 489T75 498T128 500V16Q128 7 125 4T101 1T47 0V463ZM147 570T123 596T90 638Q86 632 71 614T40 579T15 562Q-21 562 -40 585L74 708Q82 711 91 711Q105 711 116 699Q123
|
347 |
+
692 146 667T191 617T213 584Q213 574 196 568T156 561Q147 570 123 596Z" />
|
348 |
+
<glyph unicode="ï" glyph-name="idieresis" horiz-adv-x="175" d="M47 463Q47 482 53 489T75 498T128 500V16Q128 7 125 4T101 1T47 0V463ZM261 573T252 586T242 632Q242 659 253 674T286 689Q308 689 316 677T325 634Q325 604 314 588T281 572Q261 573 252
|
349 |
+
586ZM381 573T371 585T361 628Q361 689 405 689Q427 689 435 677T444 634Q442 572 400 572Q381 573 371 585Z" />
|
350 |
+
<glyph unicode="ð" glyph-name="eth" horiz-adv-x="408" d="M380 504T380 289Q380 149 344 70T209 -10Q116 -10 73 51T30 257Q30 378 73 443T190 509Q244 509 278 480Q260 547 224 602L129 565Q121 585 116 600T111 623Q111 633 119 637L177 659Q163 675
|
351 |
+
125 707Q134 724 150 734T183 744Q203 744 213 732Q233 716 257 690L326 717Q334 697 339 682T344 659Q344 649 336 646L300 632Q380 504 380 289ZM263 58T280 116T298 286Q298 349 293 388Q264 437 212 437Q163 437 138 383T112 244Q112 58 207 58Q263 58 280
|
352 |
+
116Z" />
|
353 |
+
<glyph unicode="ñ" glyph-name="ntilde" horiz-adv-x="383" d="M45 476Q76 490 121 500T204 510Q282 510 313 480T344 376V16Q344 7 340 4T316 1T261 0V352Q261 402 249 421T201 440Q183 440 162 436T126 422V16Q126 7 122 4T98 1T45 0V476ZM211 563T200
|
354 |
+
570T178 590Q168 601 161 606T143 611Q129 611 120 604T100 585T84 572Q74 572 66 581T52 599T45 612Q69 651 98 669T158 687Q173 687 182 681T203 663Q214 651 223 645T245 639Q265 639 275 646T295 666T310 678Q318 678 324 668T334 647T339 633Q335 624 320
|
355 |
+
608T282 577T231 563Q211 563 200 570Z" />
|
356 |
+
<glyph unicode="ò" glyph-name="ograve" horiz-adv-x="376" d="M128 -10T95 9T45 84T27 250Q27 510 194 510Q249 510 282 488T332 409T349 252Q349 116 308 53T184 -10Q128 -10 95 9ZM222 58T241 100T261 252Q261 330 254 371T231 427T191 442Q154 442 135
|
357 |
+
400T115 248Q115 168 123 127T146 72T186 58Q222 58 241 100ZM224 568T173 604T111 655Q115 677 125 696T148 716Q155 716 203 675T282 598Q281 595 277 584T266 563T251 553Q224 568 173 604Z" />
|
358 |
+
<glyph unicode="ó" glyph-name="oacute" horiz-adv-x="376" d="M128 -10T95 9T45 84T27 250Q27 510 194 510Q249 510 282 488T332 409T349 252Q349 116 308 53T184 -10Q128 -10 95 9ZM222 58T241 100T261 252Q261 330 254 371T231 427T191 442Q154 442 135
|
359 |
+
400T115 248Q115 168 123 127T146 72T186 58Q222 58 241 100ZM134 560T127 570T116 591T111 605Q143 641 190 681T245 722Q258 722 268 703T282 661Q270 648 219 611T142 560Q134 560 127 570Z" />
|
360 |
+
<glyph unicode="ô" glyph-name="ocircumflex" horiz-adv-x="376" d="M128 -10T95 9T45 84T27 250Q27 510 194 510Q249 510 282 488T332 409T349 252Q349 116 308 53T184 -10Q128 -10 95 9ZM222 58T241 100T261 252Q261 330 254 371T231 427T191 442Q154 442
|
361 |
+
135 400T115 248Q115 168 123 127T146 72T186 58Q222 58 241 100ZM250 570T226 596T193 638Q189 632 174 614T143 579T118 562Q82 562 63 585L177 708Q185 711 194 711Q208 711 219 699Q226 692 249 667T294 617T316 584Q316 574 299 568T259 561Q250 570 226 596Z"
|
362 |
+
/>
|
363 |
+
<glyph unicode="õ" glyph-name="otilde" horiz-adv-x="376" d="M128 -10T95 9T45 84T27 250Q27 510 194 510Q249 510 282 488T332 409T349 252Q349 116 308 53T184 -10Q128 -10 95 9ZM222 58T241 100T261 252Q261 330 254 371T231 427T191 442Q154 442 135
|
364 |
+
400T115 248Q115 168 123 127T146 72T186 58Q222 58 241 100ZM209 563T198 570T176 590Q166 601 159 606T141 611Q127 611 118 604T98 585T82 572Q72 572 64 581T50 599T43 612Q67 651 96 669T156 687Q171 687 180 681T201 663Q212 651 221 645T243 639Q263 639
|
365 |
+
273 646T293 666T308 678Q316 678 322 668T332 647T337 633Q333 624 318 608T280 577T229 563Q209 563 198 570Z" />
|
366 |
+
<glyph unicode="ö" glyph-name="odieresis" horiz-adv-x="376" d="M128 -10T95 9T45 84T27 250Q27 510 194 510Q249 510 282 488T332 409T349 252Q349 116 308 53T184 -10Q128 -10 95 9ZM222 58T241 100T261 252Q261 330 254 371T231 427T191 442Q154 442
|
367 |
+
135 400T115 248Q115 168 123 127T146 72T186 58Q222 58 241 100ZM108 573T99 586T89 632Q89 659 100 674T133 689Q155 689 163 677T172 634Q172 604 161 588T128 572Q108 573 99 586ZM228 573T218 585T208 628Q208 689 252 689Q274 689 282 677T291 634Q289 572
|
368 |
+
247 572Q228 573 218 585Z" />
|
369 |
+
<glyph unicode="÷" glyph-name="divide" horiz-adv-x="418" d="M181 376T170 389T159 427Q159 448 172 463T208 478Q258 478 258 427Q258 405 245 391T208 376Q181 376 170 389ZM34 290T36 303T51 317H384Q384 275 382 261T368 247H34Q34 290 36 303ZM181
|
370 |
+
81T170 94T159 132Q159 153 172 168T208 183Q258 183 258 132Q258 110 245 96T208 81Q181 81 170 94Z" />
|
371 |
+
<glyph unicode="ø" glyph-name="oslash" horiz-adv-x="412" d="M403 484T388 454T356 395Q369 343 369 252Q369 116 329 53T207 -10Q167 -10 140 -2T93 29L62 -26Q46 -23 32 -14T17 8Q17 14 63 92Q48 149 48 250Q48 510 213 510Q250 510 277 501T323 468Q351
|
372 |
+
515 357 522Q360 521 371 517T393 506T403 489Q403 484 388 454ZM174 440T155 399T135 248Q135 216 137 176L266 404Q257 425 244 432T211 440Q174 440 155 399ZM243 58T262 100T282 252Q282 298 279 331Q275 323 194 179L150 101Q158 76 172 67T207 58Q243 58
|
373 |
+
262 100Z" />
|
374 |
+
<glyph unicode="ù" glyph-name="ugrave" horiz-adv-x="389" d="M135 -10T103 8T58 61T45 156V484Q45 493 48 496T72 499T128 500V149Q128 98 141 79T196 60Q236 60 263 79V484Q263 493 267 496T290 499T344 500V26Q314 10 274 0T194 -10Q135 -10 103 8ZM229
|
375 |
+
568T178 604T116 655Q120 677 130 696T153 716Q160 716 208 675T287 598Q286 595 282 584T271 563T256 553Q229 568 178 604Z" />
|
376 |
+
<glyph unicode="ú" glyph-name="uacute" horiz-adv-x="389" d="M135 -10T103 8T58 61T45 156V484Q45 493 48 496T72 499T128 500V149Q128 98 141 79T196 60Q236 60 263 79V484Q263 493 267 496T290 499T344 500V26Q314 10 274 0T194 -10Q135 -10 103 8ZM139
|
377 |
+
560T132 570T121 591T116 605Q148 641 195 681T250 722Q263 722 273 703T287 661Q275 648 224 611T147 560Q139 560 132 570Z" />
|
378 |
+
<glyph unicode="û" glyph-name="ucircumflex" horiz-adv-x="389" d="M135 -10T103 8T58 61T45 156V484Q45 493 48 496T72 499T128 500V149Q128 98 141 79T196 60Q236 60 263 79V484Q263 493 267 496T290 499T344 500V26Q314 10 274 0T194 -10Q135 -10 103
|
379 |
+
8ZM255 570T231 596T198 638Q194 632 179 614T148 579T123 562Q87 562 68 585L182 708Q190 711 199 711Q213 711 224 699Q231 692 254 667T299 617T321 584Q321 574 304 568T264 561Q255 570 231 596Z" />
|
380 |
+
<glyph unicode="ü" glyph-name="udieresis" horiz-adv-x="389" d="M135 -10T103 8T58 61T45 156V484Q45 493 48 496T72 499T128 500V149Q128 98 141 79T196 60Q236 60 263 79V484Q263 493 267 496T290 499T344 500V26Q314 10 274 0T194 -10Q135 -10 103 8ZM113
|
381 |
+
573T104 586T94 632Q94 659 105 674T138 689Q160 689 168 677T177 634Q177 604 166 588T133 572Q113 573 104 586ZM233 573T223 585T213 628Q213 689 257 689Q279 689 287 677T296 634Q294 572 252 572Q233 573 223 585Z" />
|
382 |
+
<glyph unicode="ý" glyph-name="yacute" horiz-adv-x="357" d="M-4 -193T-4 -154Q-4 -142 -1 -130T8 -109Q18 -116 35 -120T71 -124Q97 -124 115 -100T144 -16L24 478Q22 486 22 489Q22 497 35 498T102 500L157 260Q167 211 174 156T184 83Q186 99 192 154T208
|
383 |
+
261L253 477Q255 490 259 494T279 499T340 500L217 -27Q202 -91 184 -127T140 -178T77 -193Q-4 -193 -4 -154ZM122 560T115 570T104 591T99 605Q131 641 178 681T233 722Q246 722 256 703T270 661Q258 648 207 611T130 560Q122 560 115 570Z" />
|
384 |
+
<glyph unicode="þ" glyph-name="thorn" d="M273 509T314 463T355 300Q355 123 309 57T203 -10Q153 -10 127 16V-194Q108 -200 79 -200Q58 -200 52 -194T46 -166V698Q46 717 52 724T74 733T127 735V502Q156 509 192 509Q273 509 314 463ZM212 60T239 109T266
|
385 |
+
293Q266 354 257 385T232 428T188 439Q154 439 127 418V88Q143 59 178 59Q212 60 239 109Z" />
|
386 |
+
<glyph unicode="ÿ" glyph-name="ydieresis" horiz-adv-x="357" d="M-4 -193T-4 -154Q-4 -142 -1 -130T8 -109Q18 -116 35 -120T71 -124Q97 -124 115 -100T144 -16L24 478Q22 486 22 489Q22 497 35 498T102 500L157 260Q167 211 174 156T184 83Q186 99 192
|
387 |
+
154T208 261L253 477Q255 490 259 494T279 499T340 500L217 -27Q202 -91 184 -127T140 -178T77 -193Q-4 -193 -4 -154ZM96 573T87 586T77 632Q77 659 88 674T121 689Q143 689 151 677T160 634Q160 604 149 588T116 572Q96 573 87 586ZM216 573T206 585T196 628Q196
|
388 |
+
689 240 689Q262 689 270 677T279 634Q277 572 235 572Q216 573 206 585Z" />
|
389 |
+
<glyph unicode="–" glyph-name="endash" horiz-adv-x="424" d="M37 290T39 303T54 317H387Q387 275 385 261T371 247H37Q37 290 39 303Z" />
|
390 |
+
<glyph unicode="—" glyph-name="emdash" horiz-adv-x="700" d="M6 290T8 303T22 317H694Q694 275 692 261T678 247H6Q6 290 8 303Z" />
|
391 |
+
<glyph unicode="‘" glyph-name="quoteleft" horiz-adv-x="174" d="M34 575T34 634Q34 668 48 705T80 769T108 795Q135 795 140 772Q127 747 122 725T115 676Q138 661 138 627Q138 605 124 590T88 575Q34 575 34 634Z" />
|
392 |
+
<glyph unicode="’" glyph-name="quoteright" horiz-adv-x="174" d="M41 572T34 595Q48 621 52 642T59 692Q36 706 36 740Q36 763 50 777T86 792Q141 792 141 733Q141 699 127 662T94 598T66 572Q41 572 34 595Z" />
|
393 |
+
<glyph unicode="‚" glyph-name="quotesinglbase" horiz-adv-x="170" d="M41 -114T34 -91Q48 -66 52 -45T59 5Q36 19 36 54Q36 76 50 91T86 106Q141 106 141 47Q141 13 127 -24T94 -88T66 -114Q41 -114 34 -91Z" />
|
394 |
+
<glyph unicode="“" glyph-name="quotedblleft" horiz-adv-x="324" d="M34 575T34 634Q34 668 48 705T80 769T108 795Q135 795 140 772Q127 747 122 725T115 676Q138 661 138 627Q138 605 124 590T88 575Q34 575 34 634ZM184 575T184 634Q184 668 198 705T230
|
395 |
+
769T258 795Q285 795 290 772Q276 747 272 726T265 676Q288 661 288 627Q288 605 274 590T238 575Q184 575 184 634Z" />
|
396 |
+
<glyph unicode="”" glyph-name="quotedblright" horiz-adv-x="324" d="M41 572T34 595Q48 621 52 642T59 692Q36 706 36 740Q36 763 50 777T86 792Q141 792 141 733Q141 699 127 662T94 598T66 572Q41 572 34 595ZM189 572T184 595Q198 621 202 642T209
|
397 |
+
692Q186 706 186 740Q186 763 200 777T236 792Q291 792 291 733Q291 699 277 662T244 598T216 572Q189 572 184 595Z" />
|
398 |
+
<glyph unicode="„" glyph-name="quotedblbase" horiz-adv-x="321" d="M41 -114T34 -91Q48 -66 52 -45T59 5Q36 19 36 54Q36 76 50 91T86 106Q141 106 141 47Q141 13 127 -24T94 -88T66 -114Q41 -114 34 -91ZM189 -114T184 -91Q198 -66 202 -45T209 5Q186
|
399 |
+
19 186 54Q186 76 200 91T236 106Q291 106 291 47Q291 13 277 -24T244 -88T216 -114Q189 -114 184 -91Z" />
|
400 |
+
<glyph unicode="•" glyph-name="bullet" horiz-adv-x="223" d="M75 208T58 227T41 284Q41 316 61 338T114 361Q153 361 171 341T189 284Q189 251 169 230T114 208Q75 208 58 227Z" />
|
401 |
+
<glyph unicode="‹" glyph-name="guilsinglleft" horiz-adv-x="247" d="M156 16T120 69T51 178T18 250Q18 265 50 320T118 430T164 500Q178 500 188 491T205 472T212 459Q212 442 186 396T132 306T94 250Q103 238 132 196T187 109T214 47Q213 43 207 32T191
|
402 |
+
11T167 0Q156 16 120 69Z" />
|
403 |
+
<glyph unicode="›" glyph-name="guilsinglright" horiz-adv-x="247" d="M77 1T66 6T44 21T33 46Q33 62 59 107T115 195T153 250Q144 263 116 306T61 395T35 459Q35 471 45 480T67 494T83 500Q94 484 129 430T196 321T229 250Q229 234 196 179T128 70T81
|
404 |
+
0Q77 1 66 6Z" />
|
405 |
+
</font>
|
406 |
+
</defs>
|
407 |
+
</svg>
|
themes/default/fonts/yanone-kaffeesatz-v9-latin-regular.ttf
ADDED
Binary file
|
themes/default/fonts/yanone-kaffeesatz-v9-latin-regular.woff
ADDED
Binary file
|
themes/default/fonts/yanone-kaffeesatz-v9-latin-regular.woff2
ADDED
Binary file
|
themes/default/js/dev/client.js
ADDED
@@ -0,0 +1,184 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
if ( !!window.SLB && SLB.has_child('View.extend_theme') ) {(function($) {
|
2 |
+
SLB.View.extend_theme('slb_default', {
|
3 |
+
/**
|
4 |
+
* Transition event handlers
|
5 |
+
*/
|
6 |
+
'transition': {
|
7 |
+
/**
|
8 |
+
* Open event
|
9 |
+
* @param View.Viewer v Viewer instance
|
10 |
+
* @param deferred dfr Resolved when transition is complete
|
11 |
+
* @return promise Resolved when transition is complete
|
12 |
+
*/
|
13 |
+
'open': function(v, dfr) {
|
14 |
+
// Reset layout and overlay state on open
|
15 |
+
var l = v.get_layout().hide(),
|
16 |
+
o = v.get_overlay().hide();
|
17 |
+
|
18 |
+
// Clean UI
|
19 |
+
var thm = this;
|
20 |
+
var d = v.dom_get();
|
21 |
+
d.find('.slb_content').css({width: '', height: ''}).find(this.get_tag_selector()).hide();
|
22 |
+
d.find('.slb_details').height(0);
|
23 |
+
// Show viewer DOM
|
24 |
+
d.show({'always': function() {
|
25 |
+
var pos = {'top_base': $(document).scrollTop()};
|
26 |
+
if ( document.documentElement.clientWidth > thm.get_breakpoint('small') ) {
|
27 |
+
/* Standard screen */
|
28 |
+
// Center vertically
|
29 |
+
pos.top = ( pos.top_base + $(window).height() / 2 ) - ( l.height() / 2 );
|
30 |
+
if ( pos.top < pos.top_base ) {
|
31 |
+
pos.top = pos.top_base;
|
32 |
+
}
|
33 |
+
} else {
|
34 |
+
/* Small screen */
|
35 |
+
// Position at top
|
36 |
+
pos.top = pos.top_base;
|
37 |
+
}
|
38 |
+
// Show overlay
|
39 |
+
o.fadeIn({'always': function() {
|
40 |
+
// Position lightbox
|
41 |
+
l.css(pos);
|
42 |
+
dfr.resolve();
|
43 |
+
}});
|
44 |
+
}});
|
45 |
+
return dfr.promise();
|
46 |
+
},
|
47 |
+
/**
|
48 |
+
* Close event
|
49 |
+
* @param View.Viewer v Viewer instance
|
50 |
+
* @param jQuery.Deferred dfr Deferred instance to be resolved when animation is complete
|
51 |
+
* @return jQuery.Promise Resolved when transition is complete
|
52 |
+
*/
|
53 |
+
'close': function(v, dfr) {
|
54 |
+
// Viewer elements
|
55 |
+
var l = v.get_layout(),
|
56 |
+
c = l.find('.slb_content');
|
57 |
+
// Reset procedure
|
58 |
+
var reset = function() {
|
59 |
+
// Reset state
|
60 |
+
c.width('').height('');
|
61 |
+
l.css('opacity', '');
|
62 |
+
dfr.resolve();
|
63 |
+
};
|
64 |
+
if ( v.animation_enabled() && document.documentElement.clientWidth > this.get_breakpoint('small') ) {
|
65 |
+
/* Standard */
|
66 |
+
var anims = {
|
67 |
+
'layout': { opacity: 0, top: $(document).scrollTop() + ( $(window).height() / 2 ) },
|
68 |
+
'content': { width: 0, height: 0 },
|
69 |
+
'speed': 'fast'
|
70 |
+
};
|
71 |
+
// Shrink & fade out viewer
|
72 |
+
var pos = l.animate(anims.layout, anims.speed).promise();
|
73 |
+
var size = c.animate(anims.content, anims.speed).promise();
|
74 |
+
$.when(pos, size).done(function() {
|
75 |
+
// Fade out overlay
|
76 |
+
v.get_overlay().fadeOut({'always': function() {
|
77 |
+
reset();
|
78 |
+
}});
|
79 |
+
});
|
80 |
+
} else {
|
81 |
+
l.css('opacity', 0);
|
82 |
+
reset();
|
83 |
+
}
|
84 |
+
return dfr.promise();
|
85 |
+
},
|
86 |
+
/**
|
87 |
+
* Item loading event
|
88 |
+
* @param View.Viewer v Viewer instance
|
89 |
+
* @param deferred dfr Resolved when animation is complete
|
90 |
+
* @return promise Resolved when transition is complete
|
91 |
+
*/
|
92 |
+
'load': function(v) {
|
93 |
+
v.get_layout().find('.slb_loading').show();
|
94 |
+
if ( document.documentElement.clientWidth > this.get_breakpoint('small') ) {
|
95 |
+
return v.get_layout().fadeIn().promise();
|
96 |
+
} else {
|
97 |
+
return v.get_layout().show().promise();
|
98 |
+
}
|
99 |
+
},
|
100 |
+
/**
|
101 |
+
* Item unloaded event
|
102 |
+
* @param View.Viewer v Viewer instance
|
103 |
+
* @param jQuery.Deferred dfr Deferred instance to be resolved when animation is complete
|
104 |
+
* @return jQuery.Promise Resolved when transition is complete
|
105 |
+
*/
|
106 |
+
'unload': function(v, dfr) {
|
107 |
+
var l = v.get_layout(),
|
108 |
+
det = l.find('.slb_details'),
|
109 |
+
cont = l.find('.slb_content ' + this.get_tag_selector());
|
110 |
+
var props = {height: 0};
|
111 |
+
// Hide details
|
112 |
+
det.css(props);
|
113 |
+
// Hide content
|
114 |
+
cont.hide();
|
115 |
+
// Finish
|
116 |
+
$.when(det.promise(), cont.promise()).done(function() {
|
117 |
+
dfr.resolve();
|
118 |
+
});
|
119 |
+
return dfr.promise();
|
120 |
+
},
|
121 |
+
/**
|
122 |
+
* Item loading completed event
|
123 |
+
* @param View.Viewer v Viewer instance
|
124 |
+
* @param jQuery.Deferred dfr Deferred instance to be resolved when animation is complete
|
125 |
+
* @return jQuery.Promise Resolved when transition is complete
|
126 |
+
*/
|
127 |
+
'complete': function(v, dfr) {
|
128 |
+
// Elements
|
129 |
+
var l = v.get_layout(),
|
130 |
+
loader = l.find('.slb_loading'),
|
131 |
+
det = l.find('.slb_details'),
|
132 |
+
det_data = det.find('.slb_data'),
|
133 |
+
c = l.find('.slb_content'),
|
134 |
+
c_tag = c.find( this.get_tag_selector() );
|
135 |
+
// Transition
|
136 |
+
if ( document.documentElement.clientWidth > this.get_breakpoint('small') ) {
|
137 |
+
var spd = 'fast';
|
138 |
+
// Resize viewer to fit item
|
139 |
+
var dims_item = this.get_item_dimensions();
|
140 |
+
// Determine details height
|
141 |
+
det.width(dims_item.width);
|
142 |
+
var dims_det = {'height': det_data.outerHeight()};
|
143 |
+
// Reset width
|
144 |
+
det.width('');
|
145 |
+
// Determine vertical positioning (centered)
|
146 |
+
var pos = { 'top_base': $(document).scrollTop() };
|
147 |
+
// Center vertically
|
148 |
+
pos.top = pos.top_base + ( $(window).height() / 2 ) - ( ( dims_det.height + dims_item.height ) / 2 );
|
149 |
+
if ( pos.top < pos.top_base ) {
|
150 |
+
pos.top = pos.top_base;
|
151 |
+
}
|
152 |
+
|
153 |
+
// Position/Resize viewer
|
154 |
+
pos = l.animate(pos, spd).promise();
|
155 |
+
dims_item = c.animate(dims_item, spd).promise();
|
156 |
+
// Display elements
|
157 |
+
var thm = this;
|
158 |
+
$.when(pos, dims_item).done(function() {
|
159 |
+
// Hide loading indicator
|
160 |
+
loader.fadeOut(spd, function() {
|
161 |
+
// Display content
|
162 |
+
c.find( thm.get_tag_selector('item', 'content') ).fadeIn(function() {
|
163 |
+
// Show UI
|
164 |
+
c_tag.show();
|
165 |
+
// Show details
|
166 |
+
det.animate({'height': det_data.outerHeight()}, 'slow').promise().done(function() {
|
167 |
+
det.height('');
|
168 |
+
dfr.resolve();
|
169 |
+
});
|
170 |
+
});
|
171 |
+
});
|
172 |
+
});
|
173 |
+
} else {
|
174 |
+
loader.hide();
|
175 |
+
c_tag.show();
|
176 |
+
det.height('');
|
177 |
+
dfr.resolve();
|
178 |
+
}
|
179 |
+
return dfr.promise();
|
180 |
+
}
|
181 |
+
}
|
182 |
+
});
|
183 |
+
})(jQuery);
|
184 |
+
}
|
themes/default/js/prod/client.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
window.SLB&&SLB.has_child("View.extend_theme")&&!function($){SLB.View.extend_theme("slb_default",{transition:{open:function(v,dfr){var l=v.get_layout().hide(),o=v.get_overlay().hide(),thm=this,d=v.dom_get();return d.find(".slb_content").css({width:"",height:""}).find(this.get_tag_selector()).hide(),d.find(".slb_details").height(0),d.show({always:function(){var pos={top_base:$(document).scrollTop()};document.documentElement.clientWidth>thm.get_breakpoint("small")?(pos.top=pos.top_base+$(window).height()/2-l.height()/2,pos.top<pos.top_base&&(pos.top=pos.top_base)):pos.top=pos.top_base,o.fadeIn({always:function(){l.css(pos),dfr.resolve()}})}}),dfr.promise()},close:function(v,dfr){var l=v.get_layout(),c=l.find(".slb_content"),reset=function(){c.width("").height(""),l.css("opacity",""),dfr.resolve()};if(v.animation_enabled()&&document.documentElement.clientWidth>this.get_breakpoint("small")){var anims={layout:{opacity:0,top:$(document).scrollTop()+$(window).height()/2},content:{width:0,height:0},speed:"fast"},pos=l.animate(anims.layout,anims.speed).promise(),size=c.animate(anims.content,anims.speed).promise();$.when(pos,size).done(function(){v.get_overlay().fadeOut({always:function(){reset()}})})}else l.css("opacity",0),reset();return dfr.promise()},load:function(v){return v.get_layout().find(".slb_loading").show(),document.documentElement.clientWidth>this.get_breakpoint("small")?v.get_layout().fadeIn().promise():v.get_layout().show().promise()},unload:function(v,dfr){var l=v.get_layout(),det=l.find(".slb_details"),cont=l.find(".slb_content "+this.get_tag_selector()),props={height:0};return det.css(props),cont.hide(),$.when(det.promise(),cont.promise()).done(function(){dfr.resolve()}),dfr.promise()},complete:function(v,dfr){var l=v.get_layout(),loader=l.find(".slb_loading"),det=l.find(".slb_details"),det_data=det.find(".slb_data"),c=l.find(".slb_content"),c_tag=c.find(this.get_tag_selector());if(document.documentElement.clientWidth>this.get_breakpoint("small")){var spd="fast",dims_item=this.get_item_dimensions();det.width(dims_item.width);var dims_det={height:det_data.outerHeight()};det.width("");var pos={top_base:$(document).scrollTop()};pos.top=pos.top_base+$(window).height()/2-(dims_det.height+dims_item.height)/2,pos.top<pos.top_base&&(pos.top=pos.top_base),pos=l.animate(pos,spd).promise(),dims_item=c.animate(dims_item,spd).promise();var thm=this;$.when(pos,dims_item).done(function(){loader.fadeOut(spd,function(){c.find(thm.get_tag_selector("item","content")).fadeIn(function(){c_tag.show(),det.animate({height:det_data.outerHeight()},"slow").promise().done(function(){det.height(""),dfr.resolve()})})})})}else loader.hide(),c_tag.show(),det.height(""),dfr.resolve();return dfr.promise()}}})}(jQuery);
|
themes/default/sass/_fonts.scss
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* yanone-kaffeesatz-regular - latin */
|
2 |
+
@font-face {
|
3 |
+
font-family: 'Yanone Kaffeesatz';
|
4 |
+
font-style: normal;
|
5 |
+
font-weight: 400;
|
6 |
+
src: url('../fonts/yanone-kaffeesatz-v9-latin-regular.eot'); /* IE9 Compat Modes */
|
7 |
+
src: local('Yanone Kaffeesatz Regular'), local('YanoneKaffeesatz-Regular'),
|
8 |
+
url('../fonts/yanone-kaffeesatz-v9-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
9 |
+
url('../fonts/yanone-kaffeesatz-v9-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
|
10 |
+
url('../fonts/yanone-kaffeesatz-v9-latin-regular.woff') format('woff'), /* Modern Browsers */
|
11 |
+
url('../fonts/yanone-kaffeesatz-v9-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
|
12 |
+
url('../fonts/yanone-kaffeesatz-v9-latin-regular.svg#YanoneKaffeesatz') format('svg'); /* Legacy iOS */
|
13 |
+
}
|
themes/default/sass/style.scss
CHANGED
@@ -1,54 +1,25 @@
|
|
1 |
-
//
|
2 |
|
3 |
-
|
4 |
-
|
|
|
|
|
5 |
|
6 |
-
//
|
7 |
|
8 |
-
@
|
9 |
-
|
10 |
-
|
11 |
|
12 |
-
|
13 |
-
|
14 |
-
|
|
|
15 |
}
|
16 |
|
17 |
#slb_viewer_wrap {
|
18 |
.slb_theme_slb_default {
|
19 |
-
|
20 |
-
top: 0;
|
21 |
-
left: 0;
|
22 |
-
width: 100%;
|
23 |
-
z-index: 99999;
|
24 |
-
text-align: center;
|
25 |
-
line-height: 0;
|
26 |
-
color:#000;
|
27 |
-
font: {
|
28 |
-
family: arial, verdana, sans-serif;
|
29 |
-
size: 12px;
|
30 |
-
}
|
31 |
-
|
32 |
-
/* Reset */
|
33 |
-
* {
|
34 |
-
margin: 0;
|
35 |
-
padding: 0;
|
36 |
-
line-height: 1.4em;
|
37 |
-
text-align: left;
|
38 |
-
vertical-align: baseline;
|
39 |
-
white-space: normal;
|
40 |
-
outline: none;
|
41 |
-
border: 0px;
|
42 |
-
background: none;
|
43 |
-
opacity: 1;
|
44 |
-
width: auto;
|
45 |
-
height: auto;
|
46 |
-
position: static;
|
47 |
-
float: none;
|
48 |
-
clear: none;
|
49 |
-
}
|
50 |
-
|
51 |
-
/* General */
|
52 |
a,
|
53 |
a:hover {
|
54 |
border-bottom:none;
|
@@ -56,80 +27,49 @@
|
|
56 |
text-decoration:underline;
|
57 |
}
|
58 |
|
59 |
-
a img {
|
60 |
-
border: none;
|
61 |
-
}
|
62 |
-
|
63 |
.slb_viewer_layout {
|
64 |
-
@include box-sizing-border;
|
65 |
-
z-index: 2;
|
66 |
-
position: absolute;
|
67 |
top: 20px;
|
68 |
-
width: 100%;
|
69 |
-
text-align: center;
|
70 |
-
}
|
71 |
-
|
72 |
-
.slb_viewer_overlay {
|
73 |
-
position: fixed;
|
74 |
-
top: 0;
|
75 |
-
left: 0;
|
76 |
-
z-index: 1;
|
77 |
-
min-height: 105%;
|
78 |
-
min-width: 100%;
|
79 |
-
background-color: #151410;
|
80 |
-
@include opacity(0.8);
|
81 |
}
|
82 |
|
83 |
.slb_container {
|
84 |
-
|
85 |
-
@include box-shadow(0 0 64px -40px #fcfcfc);
|
86 |
-
position: relative;
|
87 |
-
display: inline-block;
|
88 |
-
background-color: #fff;
|
89 |
-
margin: 0 auto;
|
90 |
border-radius: 5px;
|
91 |
-
padding: 16px;
|
92 |
}
|
93 |
|
94 |
.slb_loading {
|
95 |
-
|
96 |
-
position: absolute;
|
97 |
-
left: 0%;
|
98 |
-
top: 0;
|
99 |
-
width: 100%;
|
100 |
-
height: 100%;
|
101 |
-
min-width: 31px;
|
102 |
-
min-height: 31px;
|
103 |
-
text-align: center;
|
104 |
-
text-indent: -2000em;
|
105 |
-
line-height: 0;
|
106 |
-
display: none;
|
107 |
}
|
108 |
|
109 |
.slb_template_tag_ui {
|
110 |
-
cursor: pointer;
|
111 |
transition: opacity .5s;
|
112 |
}
|
113 |
|
114 |
-
|
115 |
.slb_controls {
|
116 |
position: absolute;
|
117 |
top: 8px;
|
118 |
right: 8px;
|
119 |
width: 75%;
|
120 |
text-align: right;
|
|
|
|
|
|
|
|
|
121 |
|
122 |
.slb_template_tag_ui {
|
123 |
-
|
124 |
-
|
|
|
125 |
float: right;
|
126 |
margin-left: 2px;
|
127 |
-
|
128 |
-
|
|
|
|
|
129 |
}
|
130 |
|
131 |
.slb_template_tag_ui:hover {
|
132 |
-
|
133 |
}
|
134 |
|
135 |
.slb_slideshow .slb_template_tag {
|
@@ -145,74 +85,80 @@
|
|
145 |
background: url('../images/ui_slideshow_pause.png') 0 0 no-repeat;
|
146 |
}
|
147 |
|
148 |
-
|
149 |
$ui_nav_pos: 45%;
|
150 |
%ui_nav {
|
|
|
151 |
position: absolute;
|
152 |
top: 20%;
|
153 |
height: 71%;
|
154 |
width: 45%;
|
155 |
-
|
|
|
156 |
background-repeat: no-repeat;
|
157 |
-
|
158 |
-
@include opacity(.5);
|
159 |
-
}
|
160 |
-
|
161 |
-
.slb_prev .slb_template_tag {
|
162 |
-
background-image: url('../images/nav_prev.png');
|
163 |
-
background-position: left $ui_nav_pos;
|
164 |
-
}
|
165 |
-
|
166 |
-
.slb_next .slb_template_tag {
|
167 |
-
right: 4px;
|
168 |
-
background-image: url('../images/nav_next.png');
|
169 |
-
background-position: right $ui_nav_pos;
|
170 |
-
}
|
171 |
-
|
172 |
-
.slb_prev, .slb_next {
|
173 |
-
.slb_template_tag {
|
174 |
-
@extend %ui_nav;
|
175 |
-
&:hover { @include opacity(1); }
|
176 |
-
}
|
177 |
}
|
178 |
|
179 |
-
|
180 |
.slb_content {
|
181 |
-
|
182 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
183 |
}
|
184 |
|
185 |
.slb_details {
|
186 |
-
margin: 0 auto;
|
187 |
line-height: 1.4em;
|
188 |
-
text-align: left;
|
189 |
overflow: hidden;
|
190 |
position: relative;
|
191 |
-
|
192 |
-
display: table;
|
193 |
-
width: 100%;
|
194 |
-
}
|
195 |
.slb_data {
|
196 |
-
display: table-caption;
|
197 |
caption-side: bottom;
|
198 |
}
|
|
|
|
|
|
|
|
|
199 |
}
|
200 |
|
201 |
-
|
202 |
-
width: 100%;
|
203 |
-
height: 100%;
|
204 |
-
}
|
205 |
-
|
206 |
-
/* Title */
|
207 |
$title-size: 23px;
|
208 |
|
209 |
-
.slb_data_title {
|
210 |
-
font-family: 'Yanone Kaffeesatz', sans-serif;
|
211 |
font-size: $title-size;
|
|
|
|
|
|
|
|
|
|
|
|
|
212 |
}
|
213 |
|
214 |
.slb_group_status {
|
215 |
-
@extend .slb_data_title;
|
216 |
color: #777;
|
217 |
font-style: italic;
|
218 |
font-size: $title-size * .8;
|
@@ -223,62 +169,13 @@
|
|
223 |
margin-top: 0.5em;
|
224 |
}
|
225 |
|
226 |
-
/* Single */
|
227 |
-
&.item_single {
|
228 |
-
.slb_group_status,
|
229 |
-
.slb_nav,
|
230 |
-
.slb_slideshow {
|
231 |
-
display: none;
|
232 |
-
}
|
233 |
-
}
|
234 |
-
/* Loading */
|
235 |
-
&.loading {
|
236 |
-
.slb_loading {
|
237 |
-
display: block;
|
238 |
-
}
|
239 |
-
.slb_details,
|
240 |
-
.slb_template_tag {
|
241 |
-
//display: none;
|
242 |
-
}
|
243 |
-
|
244 |
-
.slb_template_tag_ui {
|
245 |
-
@include opacity(0);
|
246 |
-
}
|
247 |
-
}
|
248 |
-
|
249 |
//Media
|
250 |
|
251 |
//Small screen
|
252 |
@media screen and (max-width: 480px) {
|
253 |
-
@mixin vsizing {
|
254 |
-
min-height: 100%;
|
255 |
-
min-width: 320px;
|
256 |
-
width: 100%;
|
257 |
-
}
|
258 |
-
@include vsizing;
|
259 |
-
.slb_viewer_layout {
|
260 |
-
@include vsizing;
|
261 |
-
display: block;
|
262 |
-
}
|
263 |
.slb_container {
|
264 |
-
|
265 |
-
@include box-sizing-border;
|
266 |
-
@include box-shadow(none);
|
267 |
-
max-width: 100%;
|
268 |
border-radius: 0;
|
269 |
-
margin: 0;
|
270 |
-
padding: 5px;
|
271 |
-
position: absolute;
|
272 |
-
top: 0;
|
273 |
-
left: 0;
|
274 |
-
.slb_content {
|
275 |
-
img, iframe, object, .slb_inner {
|
276 |
-
max-width: 100%;
|
277 |
-
}
|
278 |
-
img {
|
279 |
-
height: auto;
|
280 |
-
}
|
281 |
-
}
|
282 |
}
|
283 |
.slb_controls {
|
284 |
top: 3px;
|
1 |
+
// Variables
|
2 |
|
3 |
+
$nav_width: 25px;
|
4 |
+
$nav_height: 33px;
|
5 |
+
$ui_controls_width: 25px;
|
6 |
+
$ui_controls_height: 25px;
|
7 |
|
8 |
+
// Fonts
|
9 |
|
10 |
+
@import "fonts";
|
11 |
+
|
12 |
+
// Placeholders
|
13 |
|
14 |
+
%hide-text {
|
15 |
+
text-indent: 100%;
|
16 |
+
white-space: nowrap;
|
17 |
+
overflow: hidden;
|
18 |
}
|
19 |
|
20 |
#slb_viewer_wrap {
|
21 |
.slb_theme_slb_default {
|
22 |
+
//General
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
a,
|
24 |
a:hover {
|
25 |
border-bottom:none;
|
27 |
text-decoration:underline;
|
28 |
}
|
29 |
|
|
|
|
|
|
|
|
|
30 |
.slb_viewer_layout {
|
|
|
|
|
|
|
31 |
top: 20px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
}
|
33 |
|
34 |
.slb_container {
|
35 |
+
box-shadow: 0 0 64px -40px #fcfcfc;
|
|
|
|
|
|
|
|
|
|
|
36 |
border-radius: 5px;
|
|
|
37 |
}
|
38 |
|
39 |
.slb_loading {
|
40 |
+
@extend %hide-text;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
}
|
42 |
|
43 |
.slb_template_tag_ui {
|
|
|
44 |
transition: opacity .5s;
|
45 |
}
|
46 |
|
47 |
+
//UI
|
48 |
.slb_controls {
|
49 |
position: absolute;
|
50 |
top: 8px;
|
51 |
right: 8px;
|
52 |
width: 75%;
|
53 |
text-align: right;
|
54 |
+
[dir="rtl"] & {
|
55 |
+
right: inherit;
|
56 |
+
left: 0px;
|
57 |
+
}
|
58 |
|
59 |
.slb_template_tag_ui {
|
60 |
+
@extend %hide-text;
|
61 |
+
width: $ui_controls_width;
|
62 |
+
height: $ui_controls_height;
|
63 |
float: right;
|
64 |
margin-left: 2px;
|
65 |
+
opacity: 0.5;
|
66 |
+
[dir="rtl"] & {
|
67 |
+
float: left;
|
68 |
+
}
|
69 |
}
|
70 |
|
71 |
.slb_template_tag_ui:hover {
|
72 |
+
opacity: 0.8;
|
73 |
}
|
74 |
|
75 |
.slb_slideshow .slb_template_tag {
|
85 |
background: url('../images/ui_slideshow_pause.png') 0 0 no-repeat;
|
86 |
}
|
87 |
|
88 |
+
//Navigation
|
89 |
$ui_nav_pos: 45%;
|
90 |
%ui_nav {
|
91 |
+
@extend %hide-text;
|
92 |
position: absolute;
|
93 |
top: 20%;
|
94 |
height: 71%;
|
95 |
width: 45%;
|
96 |
+
min-width: $nav_width;
|
97 |
+
min-height: $nav_height;
|
98 |
background-repeat: no-repeat;
|
99 |
+
opacity: 0.5;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
}
|
101 |
|
102 |
+
//Content
|
103 |
.slb_content {
|
104 |
+
min-height: $nav_height + $ui_controls_height;
|
105 |
+
min-width: $nav_width * 2;
|
106 |
+
|
107 |
+
.slb_prev .slb_template_tag,
|
108 |
+
[dir="rtl"] & .slb_next .slb_template_tag {
|
109 |
+
left: 4px;
|
110 |
+
right: inherit;
|
111 |
+
background-image: url('../images/nav_prev.png');
|
112 |
+
background-position: left $ui_nav_pos;
|
113 |
+
}
|
114 |
+
|
115 |
+
.slb_next .slb_template_tag,
|
116 |
+
[dir="rtl"] & .slb_prev .slb_template_tag {
|
117 |
+
right: 4px;
|
118 |
+
left: inherit;
|
119 |
+
background-image: url('../images/nav_next.png');
|
120 |
+
background-position: right $ui_nav_pos;
|
121 |
+
}
|
122 |
+
|
123 |
+
.slb_prev, .slb_next {
|
124 |
+
.slb_template_tag {
|
125 |
+
@extend %ui_nav;
|
126 |
+
&:hover {
|
127 |
+
opacity: 1
|
128 |
+
}
|
129 |
+
}
|
130 |
+
}
|
131 |
}
|
132 |
|
133 |
.slb_details {
|
|
|
134 |
line-height: 1.4em;
|
|
|
135 |
overflow: hidden;
|
136 |
position: relative;
|
137 |
+
|
|
|
|
|
|
|
138 |
.slb_data {
|
|
|
139 |
caption-side: bottom;
|
140 |
}
|
141 |
+
|
142 |
+
.slb_nav {
|
143 |
+
display: none;
|
144 |
+
}
|
145 |
}
|
146 |
|
147 |
+
//Title
|
|
|
|
|
|
|
|
|
|
|
148 |
$title-size: 23px;
|
149 |
|
150 |
+
.slb_data_title, .slb_group_status {
|
151 |
+
font-family: 'Yanone Kaffeesatz', arial, sans-serif;
|
152 |
font-size: $title-size;
|
153 |
+
margin-right: .2em;
|
154 |
+
display: inline-block;
|
155 |
+
[dir="rtl"] & {
|
156 |
+
margin-left: .2em;
|
157 |
+
margin-right: 0px;
|
158 |
+
}
|
159 |
}
|
160 |
|
161 |
.slb_group_status {
|
|
|
162 |
color: #777;
|
163 |
font-style: italic;
|
164 |
font-size: $title-size * .8;
|
169 |
margin-top: 0.5em;
|
170 |
}
|
171 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
//Media
|
173 |
|
174 |
//Small screen
|
175 |
@media screen and (max-width: 480px) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
176 |
.slb_container {
|
177 |
+
box-shadow: none;
|
|
|
|
|
|
|
178 |
border-radius: 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
}
|
180 |
.slb_controls {
|
181 |
top: 3px;
|