Version Description
- Initial Release
=
Download this release
Release Info
Developer | joesexton00 |
Plugin | Scroll Back To Top |
Version | 1.0 |
Comparing to | |
See all releases |
Version 1.0
- assets/js/admin.js +24 -0
- assets/js/scroll-back-to-top.js +91 -0
- assets/lib/jquery-textfill/CHANGES.mkd +74 -0
- assets/lib/jquery-textfill/COPYING +20 -0
- assets/lib/jquery-textfill/Makefile +9 -0
- assets/lib/jquery-textfill/README.mkd +106 -0
- assets/lib/jquery-textfill/css/index.css +57 -0
- assets/lib/jquery-textfill/img/ChimpThinking.png +0 -0
- assets/lib/jquery-textfill/img/Computer2.png +0 -0
- assets/lib/jquery-textfill/img/ComputerGlare.png +0 -0
- assets/lib/jquery-textfill/index.html +38 -0
- assets/lib/jquery-textfill/jquery.textfill.js +149 -0
- assets/lib/jquery-textfill/jquery.textfill.min.js +17 -0
- assets/lib/jquery-textfill/js/index.js +13 -0
- assets/lib/jquery-textfill/js/tests.js +364 -0
- assets/lib/jquery-textfill/tests.html +17 -0
- assets/lib/jquery-textfill/textfill.jquery.json +35 -0
- assets/screenshot-1.png +0 -0
- assets/screenshot-2.png +0 -0
- assets/screenshot-3.png +0 -0
- assets/screenshot-4.png +0 -0
- assets/screenshot-5.png +0 -0
- controller/SBTT_AdminMenuController.php +48 -0
- controller/SBTT_FrontendController.php +283 -0
- framework/JmsAdminSettingsPage.php +959 -0
- framework/JmsBootstrap.php +178 -0
- framework/JmsController.php +420 -0
- framework/JmsUserOptionsCollection.php +234 -0
- framework/readme.md +3 -0
- model/SBTT_Options.php +261 -0
- readme.txt +77 -0
- scroll-back-to-top.php +12 -0
- view/dynamic-styles.php +94 -0
- view/framework/admin/partials/checkbox_input.php +22 -0
- view/framework/admin/partials/radio_input.php +23 -0
- view/framework/admin/partials/required_indicator.php +1 -0
- view/framework/admin/partials/text_input.php +22 -0
- view/framework/admin/partials/textarea_input.php +13 -0
- view/framework/admin/settings.php +45 -0
- view/scroll-button.php +9 -0
assets/js/admin.js
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
(function($){
|
2 |
+
$(function(){
|
3 |
+
sbttLoaded();
|
4 |
+
$('[name="scroll-back-to-top[label_type]"]').on('change', sbttLoaded);
|
5 |
+
});
|
6 |
+
|
7 |
+
function sbttLoaded(){
|
8 |
+
if($('[name="scroll-back-to-top[label_type]"]:checked').val() == 'text'){
|
9 |
+
$('[name="scroll-back-to-top[icon_size]"]').prop('disabled', true);
|
10 |
+
$('[name="scroll-back-to-top[label_text]"]').prop('disabled', false);
|
11 |
+
$('[name="scroll-back-to-top[font_size]"]').prop('disabled', false);
|
12 |
+
if(!$('[name="scroll-back-to-top[font_size]"]').val()){
|
13 |
+
$('[name="scroll-back-to-top[font_size]"]').val(12);
|
14 |
+
}
|
15 |
+
} else {
|
16 |
+
$('[name="scroll-back-to-top[icon_size]"]').prop('disabled', false);
|
17 |
+
$('[name="scroll-back-to-top[label_text]"]').prop('disabled', true);
|
18 |
+
$('[name="scroll-back-to-top[font_size]"]').prop('disabled', true);
|
19 |
+
if(!$('[name="scroll-back-to-top[icon_size]"]:checked').val()){
|
20 |
+
$('[name="scroll-back-to-top[icon_size]"][value="fa-2x"]').prop('checked', true);
|
21 |
+
}
|
22 |
+
}
|
23 |
+
}
|
24 |
+
})(jQuery);
|
assets/js/scroll-back-to-top.js
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
(function($){
|
2 |
+
|
3 |
+
$(function(){
|
4 |
+
if(typeof scrollBackToTop.autoFontSize !== 'undefined' && scrollBackToTop.autoFontSize){
|
5 |
+
$('.scroll-back-to-top-wrapper').textfill({ maxFontPixels: 36 });
|
6 |
+
}
|
7 |
+
|
8 |
+
$('.scroll-back-to-top-wrapper').on('click', function(){
|
9 |
+
if(typeof scrollBackToTop.scrollDuration !== 'undefined'){
|
10 |
+
scrollToElement("body", scrollBackToTop.scrollDuration, 0);
|
11 |
+
}
|
12 |
+
});
|
13 |
+
|
14 |
+
$(document).on( 'scroll', function(){
|
15 |
+
|
16 |
+
if ($(window).scrollTop() > 100) {
|
17 |
+
$('.scroll-back-to-top-wrapper').addClass('show');
|
18 |
+
} else {
|
19 |
+
$('.scroll-back-to-top-wrapper').removeClass('show');
|
20 |
+
}
|
21 |
+
});
|
22 |
+
});
|
23 |
+
|
24 |
+
function scrollToElement(selector, time, verticalOffset) {
|
25 |
+
|
26 |
+
time = typeof(time) != 'undefined' ? time : 1000;
|
27 |
+
verticalOffset = typeof(verticalOffset) != 'undefined' ? verticalOffset : 0;
|
28 |
+
element = $(selector);
|
29 |
+
offset = element.offset();
|
30 |
+
offsetTop = offset.top + verticalOffset;
|
31 |
+
$('html, body').animate({scrollTop: offsetTop}, parseInt(time), 'linear');
|
32 |
+
}
|
33 |
+
|
34 |
+
function isFullyVisible(el) {
|
35 |
+
|
36 |
+
if ( ! el.length ) {
|
37 |
+
return false;
|
38 |
+
}
|
39 |
+
|
40 |
+
if ( el instanceof jQuery ) {
|
41 |
+
el = el[0];
|
42 |
+
}
|
43 |
+
|
44 |
+
var top = el.offsetTop;
|
45 |
+
var left = el.offsetLeft;
|
46 |
+
var width = el.offsetWidth;
|
47 |
+
var height = el.offsetHeight;
|
48 |
+
|
49 |
+
while(el.offsetParent) {
|
50 |
+
el = el.offsetParent;
|
51 |
+
top += el.offsetTop;
|
52 |
+
left += el.offsetLeft;
|
53 |
+
}
|
54 |
+
|
55 |
+
return (
|
56 |
+
top >= window.pageYOffset &&
|
57 |
+
left >= window.pageXOffset &&
|
58 |
+
(top + height) <= (window.pageYOffset + window.innerHeight) &&
|
59 |
+
(left + width) <= (window.pageXOffset + window.innerWidth)
|
60 |
+
);
|
61 |
+
}
|
62 |
+
|
63 |
+
function isPartiallyVisible(el) {
|
64 |
+
|
65 |
+
if ( ! el.length ) {
|
66 |
+
return false;
|
67 |
+
}
|
68 |
+
|
69 |
+
if ( el instanceof jQuery ) {
|
70 |
+
el = el[0];
|
71 |
+
}
|
72 |
+
|
73 |
+
var top = el.offsetTop;
|
74 |
+
var left = el.offsetLeft;
|
75 |
+
var width = el.offsetWidth;
|
76 |
+
var height = el.offsetHeight;
|
77 |
+
|
78 |
+
while(el.offsetParent) {
|
79 |
+
el = el.offsetParent;
|
80 |
+
top += el.offsetTop;
|
81 |
+
left += el.offsetLeft;
|
82 |
+
}
|
83 |
+
|
84 |
+
return (
|
85 |
+
top < (window.pageYOffset + window.innerHeight) &&
|
86 |
+
left < (window.pageXOffset + window.innerWidth) &&
|
87 |
+
(top + height) > window.pageYOffset &&
|
88 |
+
(left + width) > window.pageXOffset
|
89 |
+
);
|
90 |
+
}
|
91 |
+
})(jQuery);
|
assets/lib/jquery-textfill/CHANGES.mkd
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
CHANGES
|
2 |
+
=======
|
3 |
+
|
4 |
+
## Future
|
5 |
+
|
6 |
+
* drop `callback` callback
|
7 |
+
|
8 |
+
## Development
|
9 |
+
|
10 |
+
## Version 0.4.0 (2013-08-16T17:17:02Z)
|
11 |
+
|
12 |
+
* add tests for callbacks
|
13 |
+
* add `fail` callback (#15)
|
14 |
+
* deprecate `callback` callback with `success` callback
|
15 |
+
* fix `widthOnly` option (#4)
|
16 |
+
|
17 |
+
Height will not cause failure when `widthOnly` is set as long as width can fit into the container.
|
18 |
+
|
19 |
+
## Version 0.3.5 (2013-05-08T00:40:22Z)
|
20 |
+
|
21 |
+
* merge patch for compatibility to ZeptoJS (by sagens42 #13)
|
22 |
+
|
23 |
+
## Version 0.3.4 (2013-04-10T03:55:51Z)
|
24 |
+
|
25 |
+
* fix error when no console.debug.
|
26 |
+
* add test for debug flag.
|
27 |
+
|
28 |
+
## Version 0.3.3 (2013-03-25T23:35:21Z)
|
29 |
+
|
30 |
+
* retag for including the manefest in the tag.
|
31 |
+
|
32 |
+
## Version 0.3.2 (2013-02-09T02:43:32Z)
|
33 |
+
|
34 |
+
* fix introduced global variable fontSize by `_sizing()`
|
35 |
+
* fix container too small for bigger font size setting (#11)
|
36 |
+
|
37 |
+
## Version 0.3.1 (2013-01-27T05:10:51Z)
|
38 |
+
|
39 |
+
* Add `debug` option.
|
40 |
+
* Fix a couple of bugs, they didn't size up as big as possible
|
41 |
+
|
42 |
+
## Version 0.3 (2013-01-04T16:27:52Z)
|
43 |
+
|
44 |
+
* Allow to use *MaxFontPixels <= 0* to make sizing as big as possible.
|
45 |
+
|
46 |
+
## Version 0.2.1 (2012-11-11T07:04:20Z)
|
47 |
+
|
48 |
+
* Add explicitWidth and explicitHeight options (#6)
|
49 |
+
|
50 |
+
## Version 0.2 (2012-07-02T17:13:27Z)
|
51 |
+
|
52 |
+
* Fix resizing algorithm (#3)
|
53 |
+
* Add option widthOnly for header tags (#4)
|
54 |
+
|
55 |
+
## Version 0.1.3 (2012-03-27T04:03:30Z)
|
56 |
+
|
57 |
+
* Add callbacks for each filled and all filled. (by alex-pex #2)
|
58 |
+
|
59 |
+
## Version 0.1.2 (2012-01-29T12:46:12Z)
|
60 |
+
|
61 |
+
* Use binary search instead of plain do-while to accelerate the function.
|
62 |
+
(by acsaga #1)
|
63 |
+
|
64 |
+
## Version 0.1.1
|
65 |
+
|
66 |
+
Add minFontPixels parameter
|
67 |
+
|
68 |
+
## 2012-01-16T16:56:32Z
|
69 |
+
|
70 |
+
This project was moved to GitHub and licensed under the MIT License.
|
71 |
+
|
72 |
+
## Version 0.1
|
73 |
+
|
74 |
+
Released in May 2009.
|
assets/lib/jquery-textfill/COPYING
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Copyright (c) 2012-2013 Yu-Jie Lin
|
2 |
+
Copyright (c) 2009 Russ Painter
|
3 |
+
|
4 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
5 |
+
this software and associated documentation files (the "Software"), to deal in
|
6 |
+
the Software without restriction, including without limitation the rights to
|
7 |
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
8 |
+
of the Software, and to permit persons to whom the Software is furnished to do
|
9 |
+
so, subject to the following conditions:
|
10 |
+
|
11 |
+
The above copyright notice and this permission notice shall be included in all
|
12 |
+
copies or substantial portions of the Software.
|
13 |
+
|
14 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
20 |
+
SOFTWARE.
|
assets/lib/jquery-textfill/Makefile
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
all: jquery.textfill.min.js
|
2 |
+
|
3 |
+
jquery.textfill.min.js: jquery.textfill.js
|
4 |
+
curl --data output_info=compiled_code --data-urlencode js_code@jquery.textfill.js http://closure-compiler.appspot.com/compile > jquery.textfill.min.js
|
5 |
+
|
6 |
+
clean:
|
7 |
+
rm -f jquery.textfill.min.js
|
8 |
+
|
9 |
+
.PHONY: clean
|
assets/lib/jquery-textfill/README.mkd
ADDED
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jQuery TextFill
|
2 |
+
===============
|
3 |
+
|
4 |
+
**[jQuery TextFill][index]** resizes text to fit into a container and makes font size as big as possible.
|
5 |
+
|
6 |
+
This jQuery plugin was created by Russ Painter around May 2009, beginning with a StackOverflow [question][soq]. In very early 2012, Yu-Jie Lin helped to move the project to GitHub with version 0.1 and obtained the clearly stated open source licensing from Russ.
|
7 |
+
|
8 |
+
[soq]: http://stackoverflow.com/questions/687998/auto-size-dynamic-text-to-fill-fixed-size-container
|
9 |
+
[index]: http://jquery-textfill.github.io/jquery-textfill/index.html
|
10 |
+
|
11 |
+
Usage
|
12 |
+
-----
|
13 |
+
|
14 |
+
```html
|
15 |
+
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
|
16 |
+
<script src="http://jquery-textfill.github.io/jquery-textfill/jquery.textfill.min.js"></script>
|
17 |
+
```
|
18 |
+
|
19 |
+
The code above uses minified version. By default options, you need to put text inside of `<span/>`:
|
20 |
+
|
21 |
+
```html
|
22 |
+
<div class='textfill' style='width:100px;height:50px;'>
|
23 |
+
<span>The quick brown fox jumps over the lazy dog</span>
|
24 |
+
</div>
|
25 |
+
```
|
26 |
+
|
27 |
+
### Initialization
|
28 |
+
|
29 |
+
```js
|
30 |
+
$(selector).textfill(options);
|
31 |
+
```
|
32 |
+
|
33 |
+
For example,
|
34 |
+
|
35 |
+
```html
|
36 |
+
<script>
|
37 |
+
$(function(){
|
38 |
+
$('.textfill').textfill({ maxFontPixels: 36 });
|
39 |
+
});
|
40 |
+
</script>
|
41 |
+
```
|
42 |
+
|
43 |
+
### Options
|
44 |
+
|
45 |
+
Name | Description | Default
|
46 |
+
--- | --- | ---
|
47 |
+
`debug` | output debug message to console | `false`
|
48 |
+
`minFontPixels` | minimal font size | 4
|
49 |
+
`maxFontPixels` | sizing up the text as big as possible to this setting. For *size <= 0*, the text is sized to as big as the container can accommodate | 40
|
50 |
+
`innerTag` | the element tag to resize, select by `$(innerTag + ':visible:first', container)` | `span`
|
51 |
+
`success` | callback when a resizing is successful
|
52 |
+
`fail` | callback when a resizing is failed
|
53 |
+
`complete` | callback when all elements are done
|
54 |
+
`widthOnly` | only resizing for width restraint, this is intentionally used with CSS `white-space: nowrap` for header tags
|
55 |
+
`explicitWidth` | explicit width
|
56 |
+
`explicitHeight` | explicit height
|
57 |
+
|
58 |
+
Help and Support
|
59 |
+
----------------
|
60 |
+
|
61 |
+
### Reporting bug
|
62 |
+
|
63 |
+
When report a bug, please reproduce the bug using [Gist][] or [jsFiddle][] as a template. Environment can be different and some may be fine, some may be not. **Please make sure you can clearly demonstrate the bug** unless the bug is super easy to spot like `a < b` should be `a <= b`.
|
64 |
+
|
65 |
+
When reproduce a bug, it's important that CSS matches the page where you encounter the bug, it could be crucial that container's and innertag's styles have to be exactly the same.
|
66 |
+
|
67 |
+
Please also provide enough information about your system and browser, if necessary, here is a template:
|
68 |
+
|
69 |
+
TextFill version:
|
70 |
+
jQuery version:
|
71 |
+
Font family:
|
72 |
+
OS/Version:
|
73 |
+
Browser/Version:
|
74 |
+
|
75 |
+
Since TextFill 0.3.1, there is debugging option, can be enabled by `debug: true`, you can also include those messages.
|
76 |
+
|
77 |
+
[Gist]: https://gist.github.com/4650697
|
78 |
+
[jsFiddle]: http://jsfiddle.net/livibetter/3gMFG/
|
79 |
+
|
80 |
+
*If you can not provide a bug reprouction, then please do not report*, I could not fix something I can't see.
|
81 |
+
|
82 |
+
### Contributing
|
83 |
+
|
84 |
+
You are very welcome to contribute whatever you can, but **please do not**:
|
85 |
+
|
86 |
+
* Update version number.
|
87 |
+
* Generate minified file.
|
88 |
+
|
89 |
+
These tasks are for releasing, contributors should not take on them.
|
90 |
+
|
91 |
+
Before you submit, make sure:
|
92 |
+
|
93 |
+
* Coding style generally matches.
|
94 |
+
* Pass all [tests][] previously have passed.
|
95 |
+
* *Optional* Update [`README`](README.mkd) if necessary.
|
96 |
+
* *Optional* Update [`CHANGES`](CHANGES.mkd) if worth mentioning.
|
97 |
+
|
98 |
+
[tests]: http://jquery-textfill.github.io/jquery-textfill/tests.html
|
99 |
+
|
100 |
+
License
|
101 |
+
-------
|
102 |
+
|
103 |
+
It is licensed under the MIT License, see [`COPYING`](COPYING) file.
|
104 |
+
|
105 |
+
Copyright (c) 2012-2013 Yu-Jie Lin
|
106 |
+
Copyright (c) 2009 Russ Painter
|
assets/lib/jquery-textfill/css/index.css
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
body {
|
2 |
+
background-color: #ddf;
|
3 |
+
}
|
4 |
+
|
5 |
+
#dyntext {
|
6 |
+
width: 400px;
|
7 |
+
}
|
8 |
+
|
9 |
+
.monkeythink {
|
10 |
+
position: relative;
|
11 |
+
float: left;
|
12 |
+
width: 200px;
|
13 |
+
height: 286px;
|
14 |
+
background-image: url("../img/ChimpThinking.png");
|
15 |
+
}
|
16 |
+
|
17 |
+
.monkeythink .jtextfill {
|
18 |
+
position: absolute;
|
19 |
+
top: 30px;
|
20 |
+
left: 20px;
|
21 |
+
width: 150px;
|
22 |
+
height: 70px;
|
23 |
+
background-color: #fff;
|
24 |
+
text-align: center;
|
25 |
+
}
|
26 |
+
|
27 |
+
.monkeythink .jtextfill span {
|
28 |
+
font-family: "Happy Monkey";
|
29 |
+
}
|
30 |
+
|
31 |
+
.computer {
|
32 |
+
position: relative;
|
33 |
+
float: right;
|
34 |
+
width: 450px;
|
35 |
+
height: 424px;
|
36 |
+
background-image: url("../img/Computer2.png");
|
37 |
+
}
|
38 |
+
|
39 |
+
.computer .jtextfill {
|
40 |
+
position: absolute;
|
41 |
+
top: 70px;
|
42 |
+
left: 85px;
|
43 |
+
width: 285px;
|
44 |
+
height: 210px;
|
45 |
+
color: #8f8;
|
46 |
+
}
|
47 |
+
|
48 |
+
.computer .jtextfill span {
|
49 |
+
font-family: "VT323";
|
50 |
+
}
|
51 |
+
|
52 |
+
.computerglare {
|
53 |
+
position: absolute;
|
54 |
+
width: 450px;
|
55 |
+
height: 424px;
|
56 |
+
background-image: url("../img/ComputerGlare.png");
|
57 |
+
}
|
assets/lib/jquery-textfill/img/ChimpThinking.png
ADDED
Binary file
|
assets/lib/jquery-textfill/img/Computer2.png
ADDED
Binary file
|
assets/lib/jquery-textfill/img/ComputerGlare.png
ADDED
Binary file
|
assets/lib/jquery-textfill/index.html
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html>
|
3 |
+
<head>
|
4 |
+
<meta charset="utf-8"/>
|
5 |
+
<title>jQuery Plugin: Text Fill</title>
|
6 |
+
<link href='http://fonts.googleapis.com/css?family=VT323|Happy+Monkey' rel='stylesheet' type='text/css'/>
|
7 |
+
<link href="css/index.css" rel="stylesheet" type="text/css"/>
|
8 |
+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
|
9 |
+
<script src="jquery.textfill.js" ></script>
|
10 |
+
<script src="js/index.js" ></script>
|
11 |
+
</head>
|
12 |
+
|
13 |
+
<body>
|
14 |
+
<div>
|
15 |
+
<h1>Example of TextFill jQuery Plugin</h1>
|
16 |
+
<div>
|
17 |
+
<label for="dyntext">What is monkey thinking?</label>
|
18 |
+
<input type="text" id="dyntext" value="e=mc²"></input>
|
19 |
+
</div>
|
20 |
+
<div>
|
21 |
+
<label for="maxsize">Maximal font size in pixels?</label>
|
22 |
+
<input type="text" id="maxsize" value="0"></input>
|
23 |
+
</div>
|
24 |
+
<hr />
|
25 |
+
<div class="monkeythink">
|
26 |
+
<div class="jtextfill">
|
27 |
+
<span class="dyntextval">e=mc²</span>
|
28 |
+
</div>
|
29 |
+
</div>
|
30 |
+
<div class="computer">
|
31 |
+
<div class="jtextfill">
|
32 |
+
<span class="dyntextval">e=mc²</span>
|
33 |
+
</div>
|
34 |
+
<div class="computerglare"></div>
|
35 |
+
</div>
|
36 |
+
</div>
|
37 |
+
</body>
|
38 |
+
</html>
|
assets/lib/jquery-textfill/jquery.textfill.js
ADDED
@@ -0,0 +1,149 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* @preserve textfill
|
3 |
+
* @name jquery.textfill.js
|
4 |
+
* @author Russ Painter
|
5 |
+
* @author Yu-Jie Lin
|
6 |
+
* @version 0.4.0
|
7 |
+
* @date 2013-08-16
|
8 |
+
* @copyright (c) 2012-2013 Yu-Jie Lin
|
9 |
+
* @copyright (c) 2009 Russ Painter
|
10 |
+
* @license MIT License
|
11 |
+
* @homepage https://github.com/jquery-textfill/jquery-textfill
|
12 |
+
* @example http://jquery-textfill.github.io/jquery-textfill/index.html
|
13 |
+
*/
|
14 |
+
; (function($) {
|
15 |
+
/**
|
16 |
+
* Resizes an inner element's font so that the inner element completely fills the outer element.
|
17 |
+
* @param {Object} Options which are maxFontPixels (default=40), innerTag (default='span')
|
18 |
+
* @return All outer elements processed
|
19 |
+
*/
|
20 |
+
$.fn.textfill = function(options) {
|
21 |
+
var defaults = {
|
22 |
+
debug: false,
|
23 |
+
maxFontPixels: 40,
|
24 |
+
minFontPixels: 4,
|
25 |
+
innerTag: 'span',
|
26 |
+
widthOnly: false,
|
27 |
+
success: null, // callback when a resizing is done
|
28 |
+
callback: null, // callback when a resizing is done (deprecated, use success)
|
29 |
+
fail: null, // callback when a resizing is failed
|
30 |
+
complete: null, // callback when all is done
|
31 |
+
explicitWidth: null,
|
32 |
+
explicitHeight: null
|
33 |
+
};
|
34 |
+
var Opts = $.extend(defaults, options);
|
35 |
+
|
36 |
+
function _debug() {
|
37 |
+
if (!Opts.debug
|
38 |
+
|| typeof console == 'undefined'
|
39 |
+
|| typeof console.debug == 'undefined') {
|
40 |
+
return;
|
41 |
+
}
|
42 |
+
|
43 |
+
console.debug.apply(console, arguments);
|
44 |
+
}
|
45 |
+
|
46 |
+
function _warn() {
|
47 |
+
if (typeof console == 'undefined'
|
48 |
+
|| typeof console.warn == 'undefined') {
|
49 |
+
return;
|
50 |
+
}
|
51 |
+
|
52 |
+
console.warn.apply(console, arguments);
|
53 |
+
}
|
54 |
+
|
55 |
+
function _debug_sizing(prefix, ourText, maxHeight, maxWidth, minFontPixels, maxFontPixels) {
|
56 |
+
function _m(v1, v2) {
|
57 |
+
var marker = ' / ';
|
58 |
+
if (v1 > v2) {
|
59 |
+
marker = ' > ';
|
60 |
+
} else if (v1 == v2) {
|
61 |
+
marker = ' = ';
|
62 |
+
}
|
63 |
+
return marker;
|
64 |
+
}
|
65 |
+
|
66 |
+
_debug(
|
67 |
+
prefix +
|
68 |
+
'font: ' + ourText.css('font-size') +
|
69 |
+
', H: ' + ourText.height() + _m(ourText.height(), maxHeight) + maxHeight +
|
70 |
+
', W: ' + ourText.width() + _m(ourText.width() , maxWidth) + maxWidth +
|
71 |
+
', minFontPixels: ' + minFontPixels +
|
72 |
+
', maxFontPixels: ' + maxFontPixels
|
73 |
+
);
|
74 |
+
}
|
75 |
+
|
76 |
+
function _sizing(prefix, ourText, func, max, maxHeight, maxWidth, minFontPixels, maxFontPixels) {
|
77 |
+
_debug_sizing(prefix + ': ', ourText, maxHeight, maxWidth, minFontPixels, maxFontPixels);
|
78 |
+
while (minFontPixels < maxFontPixels - 1) {
|
79 |
+
var fontSize = Math.floor((minFontPixels + maxFontPixels) / 2)
|
80 |
+
ourText.css('font-size', fontSize);
|
81 |
+
if (func.call(ourText) <= max) {
|
82 |
+
minFontPixels = fontSize;
|
83 |
+
if (func.call(ourText) == max) {
|
84 |
+
break;
|
85 |
+
}
|
86 |
+
} else {
|
87 |
+
maxFontPixels = fontSize;
|
88 |
+
}
|
89 |
+
_debug_sizing(prefix + ': ', ourText, maxHeight, maxWidth, minFontPixels, maxFontPixels);
|
90 |
+
}
|
91 |
+
ourText.css('font-size', maxFontPixels);
|
92 |
+
if (func.call(ourText) <= max) {
|
93 |
+
minFontPixels = maxFontPixels;
|
94 |
+
_debug_sizing(prefix + '* ', ourText, maxHeight, maxWidth, minFontPixels, maxFontPixels);
|
95 |
+
}
|
96 |
+
return minFontPixels;
|
97 |
+
}
|
98 |
+
|
99 |
+
this.each(function() {
|
100 |
+
var ourText = $(Opts.innerTag + ':visible:first', this);
|
101 |
+
// Use explicit dimensions when specified
|
102 |
+
var maxHeight = Opts.explicitHeight || $(this).height();
|
103 |
+
var maxWidth = Opts.explicitWidth || $(this).width();
|
104 |
+
var oldFontSize = ourText.css('font-size');
|
105 |
+
var fontSize;
|
106 |
+
|
107 |
+
_debug('Opts: ', Opts);
|
108 |
+
_debug('Vars:' +
|
109 |
+
' maxHeight: ' + maxHeight +
|
110 |
+
', maxWidth: ' + maxWidth
|
111 |
+
);
|
112 |
+
|
113 |
+
var minFontPixels = Opts.minFontPixels;
|
114 |
+
var maxFontPixels = Opts.maxFontPixels <= 0 ? maxHeight : Opts.maxFontPixels;
|
115 |
+
var HfontSize = undefined;
|
116 |
+
if (!Opts.widthOnly) {
|
117 |
+
HfontSize = _sizing('H', ourText, $.fn.height, maxHeight, maxHeight, maxWidth, minFontPixels, maxFontPixels);
|
118 |
+
}
|
119 |
+
var WfontSize = _sizing('W', ourText, $.fn.width, maxWidth, maxHeight, maxWidth, minFontPixels, maxFontPixels);
|
120 |
+
|
121 |
+
if (Opts.widthOnly) {
|
122 |
+
ourText.css('font-size', WfontSize);
|
123 |
+
} else {
|
124 |
+
ourText.css('font-size', Math.min(HfontSize, WfontSize));
|
125 |
+
}
|
126 |
+
_debug('Final: ' + ourText.css('font-size'));
|
127 |
+
|
128 |
+
if (ourText.width() > maxWidth
|
129 |
+
|| (ourText.height() > maxHeight && !Opts.widthOnly)
|
130 |
+
) {
|
131 |
+
ourText.css('font-size', oldFontSize);
|
132 |
+
if (Opts.fail) {
|
133 |
+
Opts.fail(this);
|
134 |
+
}
|
135 |
+
} else if (Opts.success) {
|
136 |
+
Opts.success(this);
|
137 |
+
} else if (Opts.callback) {
|
138 |
+
_warn('callback is deprecated, use success, instead');
|
139 |
+
// call callback on each result
|
140 |
+
Opts.callback(this);
|
141 |
+
}
|
142 |
+
});
|
143 |
+
|
144 |
+
// call complete when all is complete
|
145 |
+
if (Opts.complete) Opts.complete(this);
|
146 |
+
|
147 |
+
return this;
|
148 |
+
};
|
149 |
+
})(window.jQuery);
|
assets/lib/jquery-textfill/jquery.textfill.min.js
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
textfill
|
3 |
+
@name jquery.textfill.js
|
4 |
+
@author Russ Painter
|
5 |
+
@author Yu-Jie Lin
|
6 |
+
@version 0.4.0
|
7 |
+
@date 2013-08-16
|
8 |
+
@copyright (c) 2012-2013 Yu-Jie Lin
|
9 |
+
@copyright (c) 2009 Russ Painter
|
10 |
+
@license MIT License
|
11 |
+
@homepage https://github.com/jquery-textfill/jquery-textfill
|
12 |
+
@example http://jquery-textfill.github.io/jquery-textfill/index.html
|
13 |
+
*/
|
14 |
+
(function(e){e.fn.textfill=function(q){function m(){a.debug&&("undefined"!=typeof console&&"undefined"!=typeof console.debug)&&console.debug.apply(console,arguments)}function r(){"undefined"!=typeof console&&"undefined"!=typeof console.warn&&console.warn.apply(console,arguments)}function n(a,b,d,h,f,k){function c(a,b){var c=" / ";a>b?c=" > ":a==b&&(c=" = ");return c}m(a+"font: "+b.css("font-size")+", H: "+b.height()+c(b.height(),d)+d+", W: "+b.width()+c(b.width(),h)+h+", minFontPixels: "+f+", maxFontPixels: "+
|
15 |
+
k)}function p(a,b,d,h,f,k,c,l){for(n(a+": ",b,f,k,c,l);c<l-1;){var e=Math.floor((c+l)/2);b.css("font-size",e);if(d.call(b)<=h){if(c=e,d.call(b)==h)break}else l=e;n(a+": ",b,f,k,c,l)}b.css("font-size",l);d.call(b)<=h&&(c=l,n(a+"* ",b,f,k,c,l));return c}var a=e.extend({debug:!1,maxFontPixels:40,minFontPixels:4,innerTag:"span",widthOnly:!1,success:null,callback:null,fail:null,complete:null,explicitWidth:null,explicitHeight:null},q);this.each(function(){var g=e(a.innerTag+":visible:first",this),b=a.explicitHeight||
|
16 |
+
e(this).height(),d=a.explicitWidth||e(this).width(),h=g.css("font-size");m("Opts: ",a);m("Vars: maxHeight: "+b+", maxWidth: "+d);var f=a.minFontPixels,k=0>=a.maxFontPixels?b:a.maxFontPixels,c=void 0;a.widthOnly||(c=p("H",g,e.fn.height,b,b,d,f,k));f=p("W",g,e.fn.width,d,b,d,f,k);a.widthOnly?g.css("font-size",f):g.css("font-size",Math.min(c,f));m("Final: "+g.css("font-size"));g.width()>d||g.height()>b&&!a.widthOnly?(g.css("font-size",h),a.fail&&a.fail(this)):a.success?a.success(this):a.callback&&(r("callback is deprecated, use success, instead"),
|
17 |
+
a.callback(this))});a.complete&&a.complete(this);return this}})(window.jQuery);
|
assets/lib/jquery-textfill/js/index.js
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
function update() {
|
2 |
+
var size = parseInt($('#maxsize').val(), 10);
|
3 |
+
if (!isNaN(size)) {
|
4 |
+
$('.dyntextval').html($('#dyntext').val());
|
5 |
+
$('.jtextfill').textfill({debug: true, maxFontPixels: size});
|
6 |
+
}
|
7 |
+
}
|
8 |
+
|
9 |
+
$(function () {
|
10 |
+
$('#maxsize').keyup(update);
|
11 |
+
$('#dyntext').keyup(update);
|
12 |
+
update()
|
13 |
+
});
|
assets/lib/jquery-textfill/js/tests.js
ADDED
@@ -0,0 +1,364 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
var JTF = 'jtf';
|
2 |
+
|
3 |
+
|
4 |
+
function setup(opts) {
|
5 |
+
var $t = $('#qunit-fixture');
|
6 |
+
var $d = $('<div/>', opts.div).appendTo($t);
|
7 |
+
var $s = $('<span/>', opts.span).appendTo($d);
|
8 |
+
}
|
9 |
+
|
10 |
+
|
11 |
+
test('capped at 10px', function () {
|
12 |
+
setup({
|
13 |
+
div: {
|
14 |
+
id: JTF,
|
15 |
+
width: 285,
|
16 |
+
height: 210
|
17 |
+
},
|
18 |
+
span: {
|
19 |
+
css: {
|
20 |
+
'font-family': 'VT323',
|
21 |
+
},
|
22 |
+
text: 'test'
|
23 |
+
}
|
24 |
+
});
|
25 |
+
|
26 |
+
var $jtf = $('#' + JTF);
|
27 |
+
var $span = $jtf.find('span');
|
28 |
+
$jtf.textfill({debug: true, maxFontPixels: 10});
|
29 |
+
equal($span.css('font-size'), '10px');
|
30 |
+
});
|
31 |
+
|
32 |
+
|
33 |
+
test('size up to max', function () {
|
34 |
+
setup({
|
35 |
+
div: {
|
36 |
+
id: JTF,
|
37 |
+
width: 285,
|
38 |
+
height: 210
|
39 |
+
},
|
40 |
+
span: {
|
41 |
+
css: {
|
42 |
+
'font-family': 'VT323',
|
43 |
+
},
|
44 |
+
text: 'test'
|
45 |
+
}
|
46 |
+
});
|
47 |
+
|
48 |
+
var $jtf = $('#' + JTF);
|
49 |
+
var $span = $jtf.find('span');
|
50 |
+
$jtf.textfill({debug: true, maxFontPixels: 0});
|
51 |
+
equal($span.css('font-size'), '172px');
|
52 |
+
});
|
53 |
+
|
54 |
+
|
55 |
+
test('width be maxWidth', function () {
|
56 |
+
setup({
|
57 |
+
div: {
|
58 |
+
id: JTF,
|
59 |
+
width: 196,
|
60 |
+
height: 210
|
61 |
+
},
|
62 |
+
span: {
|
63 |
+
css: {
|
64 |
+
'font-family': 'VT323',
|
65 |
+
},
|
66 |
+
text: 'test'
|
67 |
+
}
|
68 |
+
});
|
69 |
+
|
70 |
+
var $jtf = $('#' + JTF);
|
71 |
+
var $span = $jtf.find('span');
|
72 |
+
$jtf.textfill({debug: true, maxFontPixels: 0});
|
73 |
+
equal($span.css('font-size'), '119px');
|
74 |
+
});
|
75 |
+
|
76 |
+
|
77 |
+
test('height be maxHeight', function () {
|
78 |
+
setup({
|
79 |
+
div: {
|
80 |
+
id: JTF,
|
81 |
+
width: 285,
|
82 |
+
height: 158
|
83 |
+
},
|
84 |
+
span: {
|
85 |
+
css: {
|
86 |
+
'font-family': 'VT323',
|
87 |
+
},
|
88 |
+
text: 'test'
|
89 |
+
}
|
90 |
+
});
|
91 |
+
|
92 |
+
var $jtf = $('#' + JTF);
|
93 |
+
var $span = $jtf.find('span');
|
94 |
+
$jtf.textfill({debug: true, maxFontPixels: 0});
|
95 |
+
equal($span.css('font-size'), '158px');
|
96 |
+
});
|
97 |
+
|
98 |
+
|
99 |
+
test('minFontPixels too big to fit in', function () {
|
100 |
+
setup({
|
101 |
+
div: {
|
102 |
+
id: JTF,
|
103 |
+
width: 40,
|
104 |
+
height: 40
|
105 |
+
},
|
106 |
+
span: {
|
107 |
+
css: {
|
108 |
+
'font-family': 'VT323',
|
109 |
+
'font-size': '20px',
|
110 |
+
},
|
111 |
+
text: 'test'
|
112 |
+
}
|
113 |
+
});
|
114 |
+
|
115 |
+
var $jtf = $('#' + JTF);
|
116 |
+
var $span = $jtf.find('span');
|
117 |
+
$jtf.textfill({debug: true, minFontPixels: 100, maxFontPixels: 0});
|
118 |
+
equal($span.css('font-size'), '20px');
|
119 |
+
});
|
120 |
+
|
121 |
+
|
122 |
+
test('minFontPixels too big to fit in, but widthOnly = True and width fits', function () {
|
123 |
+
// @ fontSize = 60 => H > 10, W = 100
|
124 |
+
setup({
|
125 |
+
div: {
|
126 |
+
id: JTF,
|
127 |
+
// just enough to fit in with minFontPixels
|
128 |
+
width: 100,
|
129 |
+
// H is busted, but widthOnly = True, so ignored
|
130 |
+
height: 10
|
131 |
+
},
|
132 |
+
span: {
|
133 |
+
css: {
|
134 |
+
'font-family': 'VT323',
|
135 |
+
'font-size': '20px',
|
136 |
+
},
|
137 |
+
text: 'test'
|
138 |
+
}
|
139 |
+
});
|
140 |
+
|
141 |
+
var $jtf = $('#' + JTF);
|
142 |
+
var $span = $jtf.find('span');
|
143 |
+
$jtf.textfill({
|
144 |
+
debug: true,
|
145 |
+
minFontPixels: 20,
|
146 |
+
maxFontPixels: 100,
|
147 |
+
widthOnly: true
|
148 |
+
});
|
149 |
+
equal($span.css('font-size'), '60px');
|
150 |
+
});
|
151 |
+
|
152 |
+
|
153 |
+
test('minFontPixels too big to fit in, W/H both fail, even widthOnly = True', function () {
|
154 |
+
setup({
|
155 |
+
div: {
|
156 |
+
id: JTF,
|
157 |
+
width: 10,
|
158 |
+
height: 10
|
159 |
+
},
|
160 |
+
span: {
|
161 |
+
css: {
|
162 |
+
'font-family': 'VT323',
|
163 |
+
'font-size': '20px',
|
164 |
+
},
|
165 |
+
text: 'test'
|
166 |
+
}
|
167 |
+
});
|
168 |
+
|
169 |
+
var $jtf = $('#' + JTF);
|
170 |
+
var $span = $jtf.find('span');
|
171 |
+
$jtf.textfill({
|
172 |
+
debug: true,
|
173 |
+
minFontPixels: 20,
|
174 |
+
maxFontPixels: 100,
|
175 |
+
widthOnly: true
|
176 |
+
});
|
177 |
+
equal($span.css('font-size'), '20px');
|
178 |
+
});
|
179 |
+
|
180 |
+
|
181 |
+
/*************/
|
182 |
+
/* callbacks */
|
183 |
+
/*************/
|
184 |
+
|
185 |
+
test('success callback', 1, function() {
|
186 |
+
setup({
|
187 |
+
div: {
|
188 |
+
id: JTF,
|
189 |
+
width: 285,
|
190 |
+
height: 210
|
191 |
+
},
|
192 |
+
span: {
|
193 |
+
css: {
|
194 |
+
'font-family': 'VT323',
|
195 |
+
},
|
196 |
+
text: 'test'
|
197 |
+
}
|
198 |
+
});
|
199 |
+
|
200 |
+
var $jtf = $('#' + JTF);
|
201 |
+
var $span = $jtf.find('span');
|
202 |
+
$jtf.textfill({
|
203 |
+
debug: true,
|
204 |
+
maxFontPixels: 0,
|
205 |
+
success: function(e) {
|
206 |
+
equal(e, $jtf[0]);
|
207 |
+
}
|
208 |
+
});
|
209 |
+
});
|
210 |
+
|
211 |
+
|
212 |
+
test('callback callback (deprecated)', 1, function() {
|
213 |
+
setup({
|
214 |
+
div: {
|
215 |
+
id: JTF,
|
216 |
+
width: 285,
|
217 |
+
height: 210
|
218 |
+
},
|
219 |
+
span: {
|
220 |
+
css: {
|
221 |
+
'font-family': 'VT323',
|
222 |
+
},
|
223 |
+
text: 'test'
|
224 |
+
}
|
225 |
+
});
|
226 |
+
|
227 |
+
var $jtf = $('#' + JTF);
|
228 |
+
var $span = $jtf.find('span');
|
229 |
+
$jtf.textfill({
|
230 |
+
debug: true,
|
231 |
+
maxFontPixels: 0,
|
232 |
+
callback: function(e) {
|
233 |
+
equal(e, $jtf[0]);
|
234 |
+
}
|
235 |
+
});
|
236 |
+
});
|
237 |
+
|
238 |
+
|
239 |
+
test('fail callback', 1, function () {
|
240 |
+
setup({
|
241 |
+
div: {
|
242 |
+
id: JTF,
|
243 |
+
width: 40,
|
244 |
+
height: 40
|
245 |
+
},
|
246 |
+
span: {
|
247 |
+
css: {
|
248 |
+
'font-family': 'VT323',
|
249 |
+
'font-size': '20px',
|
250 |
+
},
|
251 |
+
text: 'test'
|
252 |
+
}
|
253 |
+
});
|
254 |
+
|
255 |
+
var $jtf = $('#' + JTF);
|
256 |
+
var $span = $jtf.find('span');
|
257 |
+
$jtf.textfill({
|
258 |
+
debug: true,
|
259 |
+
minFontPixels: 100,
|
260 |
+
maxFontPixels: 0,
|
261 |
+
fail: function(e) {
|
262 |
+
equal(e, $jtf[0]);
|
263 |
+
}
|
264 |
+
});
|
265 |
+
});
|
266 |
+
|
267 |
+
|
268 |
+
test('complete callback', 2, function() {
|
269 |
+
setup({
|
270 |
+
div: {
|
271 |
+
id: JTF,
|
272 |
+
width: 285,
|
273 |
+
height: 210
|
274 |
+
},
|
275 |
+
span: {
|
276 |
+
css: {
|
277 |
+
'font-family': 'VT323',
|
278 |
+
},
|
279 |
+
text: 'test'
|
280 |
+
}
|
281 |
+
});
|
282 |
+
|
283 |
+
var $jtf = $('#' + JTF);
|
284 |
+
$jtf.textfill({
|
285 |
+
debug: true,
|
286 |
+
maxFontPixels: 0,
|
287 |
+
callback: function(e) {
|
288 |
+
equal(e, $jtf[0]);
|
289 |
+
},
|
290 |
+
complete: function(e) {
|
291 |
+
equal(e, $jtf);
|
292 |
+
}
|
293 |
+
});
|
294 |
+
});
|
295 |
+
|
296 |
+
|
297 |
+
/****************/
|
298 |
+
/* debug option */
|
299 |
+
/****************/
|
300 |
+
|
301 |
+
module('debug option', {
|
302 |
+
setup: function () {
|
303 |
+
if (console.debug_original) {
|
304 |
+
throw 'console.debug_original already has value.';
|
305 |
+
}
|
306 |
+
console.debug_original = console.debug;
|
307 |
+
console.debug_called = false;
|
308 |
+
console.debug = function () {
|
309 |
+
console.debug_called = true;
|
310 |
+
}
|
311 |
+
},
|
312 |
+
teardown: function () {
|
313 |
+
if (!console.debug_original) {
|
314 |
+
throw 'console.debug_original is empty.';
|
315 |
+
}
|
316 |
+
console.debug = console.debug_original;
|
317 |
+
console.debug_original = undefined;
|
318 |
+
console.debug_called = undefined;
|
319 |
+
}
|
320 |
+
});
|
321 |
+
|
322 |
+
|
323 |
+
test('debug used', function () {
|
324 |
+
setup({
|
325 |
+
div: {
|
326 |
+
id: JTF,
|
327 |
+
width: 285,
|
328 |
+
height: 210
|
329 |
+
},
|
330 |
+
span: {
|
331 |
+
css: {
|
332 |
+
'font-family': 'VT323',
|
333 |
+
},
|
334 |
+
text: 'test'
|
335 |
+
}
|
336 |
+
});
|
337 |
+
|
338 |
+
var $jtf = $('#' + JTF);
|
339 |
+
$jtf.textfill({debug: true, maxFontPixels: 10});
|
340 |
+
equal(console.debug_called, true);
|
341 |
+
});
|
342 |
+
|
343 |
+
|
344 |
+
test('debug not used', function () {
|
345 |
+
setup({
|
346 |
+
div: {
|
347 |
+
id: JTF,
|
348 |
+
width: 285,
|
349 |
+
height: 210
|
350 |
+
},
|
351 |
+
span: {
|
352 |
+
css: {
|
353 |
+
'font-family': 'VT323',
|
354 |
+
},
|
355 |
+
text: 'test'
|
356 |
+
}
|
357 |
+
});
|
358 |
+
|
359 |
+
var $jtf = $('#' + JTF);
|
360 |
+
$jtf.textfill({debug: false, maxFontPixels: 10});
|
361 |
+
equal(console.debug_called, false);
|
362 |
+
});
|
363 |
+
|
364 |
+
|
assets/lib/jquery-textfill/tests.html
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html>
|
3 |
+
<head>
|
4 |
+
<meta charset="utf-8"/>
|
5 |
+
<title>Tests of jQuery Plugin: Text Fill</title>
|
6 |
+
<link href='http://fonts.googleapis.com/css?family=VT323' rel='stylesheet' type='text/css'/>
|
7 |
+
<link href='http://code.jquery.com/qunit/qunit-1.11.0.css' rel='stylesheet' type='text/css'/>
|
8 |
+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
|
9 |
+
<script src='http://code.jquery.com/qunit/qunit-1.11.0.js'></script>
|
10 |
+
<script src='jquery.textfill.js'></script>
|
11 |
+
<script src='js/tests.js'></script>
|
12 |
+
</head>
|
13 |
+
<body>
|
14 |
+
<div id="qunit"></div>
|
15 |
+
<div id="qunit-fixture"></div>
|
16 |
+
</body>
|
17 |
+
</html>
|
assets/lib/jquery-textfill/textfill.jquery.json
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "textfill",
|
3 |
+
"version": "0.4.0",
|
4 |
+
"title": "jQuery TextFill",
|
5 |
+
"author": {
|
6 |
+
"name": "jQuery TextFill contributors",
|
7 |
+
"url": "https://github.com/jquery-textfill/jquery-textfill"
|
8 |
+
},
|
9 |
+
"licenses": [
|
10 |
+
{
|
11 |
+
"type": "MIT",
|
12 |
+
"url": "https://github.com/jquery-textfill/jquery-textfill/blob/master/COPYING"
|
13 |
+
}
|
14 |
+
],
|
15 |
+
"dependencies": {
|
16 |
+
"jquery": "*"
|
17 |
+
},
|
18 |
+
|
19 |
+
"description": "Resizing text to fit into container.",
|
20 |
+
"keywords": [
|
21 |
+
"resize",
|
22 |
+
"text"
|
23 |
+
],
|
24 |
+
"homepage": "https://github.com/jquery-textfill/jquery-textfill",
|
25 |
+
"docs": "https://github.com/jquery-textfill/jquery-textfill",
|
26 |
+
"demo": "http://jquery-textfill.github.io/jquery-textfill/index.html",
|
27 |
+
"bugs": "https://github.com/jquery-textfill/jquery-textfill/issues",
|
28 |
+
"maintainers": [
|
29 |
+
{
|
30 |
+
"name": "Yu-Jie Lin",
|
31 |
+
"email": "livibetter@gmail.com",
|
32 |
+
"url": "http://yjl.im"
|
33 |
+
}
|
34 |
+
]
|
35 |
+
}
|
assets/screenshot-1.png
ADDED
Binary file
|
assets/screenshot-2.png
ADDED
Binary file
|
assets/screenshot-3.png
ADDED
Binary file
|
assets/screenshot-4.png
ADDED
Binary file
|
assets/screenshot-5.png
ADDED
Binary file
|
controller/SBTT_AdminMenuController.php
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* SBTT Admin Menu Controller class
|
4 |
+
*
|
5 |
+
* @author Joe Sexton <joe@josephmsexton.com>
|
6 |
+
* @package WordPress
|
7 |
+
* @subpackage scroll-back-to-top
|
8 |
+
*/
|
9 |
+
if ( !class_exists( 'SBTT_AdminMenuController' ) ){
|
10 |
+
class SBTT_AdminMenuController extends JmsAdminSettingsPage {
|
11 |
+
|
12 |
+
/**
|
13 |
+
* register Wordpress actions and filters
|
14 |
+
*/
|
15 |
+
protected function _init() {
|
16 |
+
|
17 |
+
$options = new SBTT_Options();
|
18 |
+
$this->addOptionsPage(
|
19 |
+
__( 'Scroll Back to Top Settings', $this->textDomain() ),
|
20 |
+
__( 'Scroll Back to Top', $this->textDomain() ),
|
21 |
+
$options
|
22 |
+
);
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* enqueue admin scripts
|
27 |
+
*/
|
28 |
+
public function enqueueAdminScripts() {
|
29 |
+
|
30 |
+
$this->enqueueScript( 'sbtt-admin', 'admin' );
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* enqueue admin styles
|
35 |
+
*/
|
36 |
+
public function enqueueAdminStyles() {
|
37 |
+
$this->enqueueCdnStyle( 'font-awesome', '//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css' );
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* on plugin activation init default options
|
42 |
+
*/
|
43 |
+
public function onActivation() {
|
44 |
+
|
45 |
+
$this->options->initDefaultOptions();
|
46 |
+
}
|
47 |
+
}
|
48 |
+
}
|
controller/SBTT_FrontendController.php
ADDED
@@ -0,0 +1,283 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* SBTT Frontend Controller class
|
4 |
+
*
|
5 |
+
* @author Joe Sexton <joe@josephmsexton.com>
|
6 |
+
* @package WordPress
|
7 |
+
* @subpackage scroll-back-to-top
|
8 |
+
*/
|
9 |
+
if ( !class_exists( 'SBTT_FrontEndController' ) ){
|
10 |
+
class SBTT_FrontEndController extends JmsController {
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @var array
|
14 |
+
*/
|
15 |
+
protected $args;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var SBTT_Options
|
19 |
+
*/
|
20 |
+
protected $options;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Register Wordpress actions and filters
|
24 |
+
*/
|
25 |
+
protected function _init() {
|
26 |
+
|
27 |
+
$this->options = new SBTT_Options();
|
28 |
+
$this->args = $this->_getScrollButtonArgs();
|
29 |
+
|
30 |
+
$this->_preprocessArgs();
|
31 |
+
|
32 |
+
add_action('wp_head', array( $this, 'headSection' ) );
|
33 |
+
add_action('wp_footer', array( $this, 'footerSection' ) );
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Enqueue scripts
|
38 |
+
*
|
39 |
+
* @return false if not enabled
|
40 |
+
*/
|
41 |
+
public function enqueueScripts(){
|
42 |
+
|
43 |
+
if ( !$this->isAuthorized() ) {
|
44 |
+
return false;
|
45 |
+
}
|
46 |
+
|
47 |
+
$dependencies = array( 'jquery' );
|
48 |
+
$vars = array( 'scrollBackToTop' => array() );
|
49 |
+
|
50 |
+
if ( isset($this->args['scroll_duration']) ) {
|
51 |
+
$vars['scrollBackToTop']['scrollDuration'] = $this->args['scroll_duration'];
|
52 |
+
}
|
53 |
+
|
54 |
+
if ( isset($this->args['fade_duration']) ) {
|
55 |
+
$vars['scrollBackToTop']['fadeDuration'] = $this->args['fade_duration'];
|
56 |
+
}
|
57 |
+
|
58 |
+
// load textfill js only if using auto font sizing
|
59 |
+
if ( isset($this->args['label_type']) && isset($this->args['font_size']) && $this->args['font_size'] == '0px' ) {
|
60 |
+
$this->enqueueCdnScript('text-fill', 'http://jquery-textfill.github.io/jquery-textfill/jquery.textfill.min.js' );
|
61 |
+
$dependencies = array( 'jquery', 'text-fill' );
|
62 |
+
$vars['scrollBackToTop']['autoFontSize'] = true;
|
63 |
+
}
|
64 |
+
|
65 |
+
$this->enqueueScript( 'scroll-back-to-top', 'scroll-back-to-top', $dependencies, null, true, $vars );
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Enqueue styles
|
70 |
+
*
|
71 |
+
* @return false if not enabled
|
72 |
+
*/
|
73 |
+
public function enqueueStyles(){
|
74 |
+
|
75 |
+
if ( !$this->isAuthorized() ) {
|
76 |
+
return false;
|
77 |
+
}
|
78 |
+
|
79 |
+
// Only need the font pack if using icons, not text
|
80 |
+
if ( isset( $this->args['label_type'] ) && $this->args['label_type'] != 'text' ) {
|
81 |
+
$this->enqueueCdnStyle( 'font-awesome', '//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css' );
|
82 |
+
}
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Render head markup
|
87 |
+
*
|
88 |
+
* @return false if not enabled
|
89 |
+
*/
|
90 |
+
public function headSection(){
|
91 |
+
|
92 |
+
if ( !$this->isAuthorized() ) {
|
93 |
+
return false;
|
94 |
+
}
|
95 |
+
|
96 |
+
echo apply_filters( 'sbtt_styles', $this->render( 'dynamic-styles', $this->args, false ) );
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Render footer markup
|
101 |
+
*
|
102 |
+
* @return false if not enabled
|
103 |
+
*/
|
104 |
+
public function footerSection(){
|
105 |
+
|
106 |
+
if ( !$this->isAuthorized() ) {
|
107 |
+
return false;
|
108 |
+
}
|
109 |
+
|
110 |
+
echo apply_filters( 'sbtt_button_markup', $this->render( 'scroll-button', $this->args, false ) );
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Get options
|
115 |
+
*
|
116 |
+
* @return array
|
117 |
+
*/
|
118 |
+
protected function _getScrollButtonArgs() {
|
119 |
+
|
120 |
+
return get_option( $this->options->optionsKey() );
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Preprocess variables
|
125 |
+
*/
|
126 |
+
protected function _preprocessArgs() {
|
127 |
+
|
128 |
+
$this->_processFade();
|
129 |
+
$this->_processHorizontalAlignment();
|
130 |
+
$this->_processVerticalAlignment();
|
131 |
+
$this->_processVerticalAlignment();
|
132 |
+
$this->_processBorderRadii();
|
133 |
+
$this->_processSize();
|
134 |
+
$this->_processOpacity();
|
135 |
+
$this->_processIconSize();
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Process fade
|
140 |
+
*/
|
141 |
+
protected function _processFade(){
|
142 |
+
|
143 |
+
if ( isset( $this->args['fade_duration'] ) ) {
|
144 |
+
$this->args['fade_duration'] = number_format( ( $this->args['fade_duration'] ) / 1000, 1 );
|
145 |
+
}
|
146 |
+
}
|
147 |
+
|
148 |
+
/**
|
149 |
+
* Process horizontal alignment
|
150 |
+
*/
|
151 |
+
protected function _processHorizontalAlignment(){
|
152 |
+
|
153 |
+
if ( isset( $this->args['align_x'] ) && isset( $this->args['margin_x'] )) {
|
154 |
+
|
155 |
+
if ( $this->args['align_x'] == 'right' ) {
|
156 |
+
|
157 |
+
$this->args['css_right'] = $this->args['margin_x'] . 'px';
|
158 |
+
|
159 |
+
} elseif ( $this->args['align_x'] == 'left' ) {
|
160 |
+
|
161 |
+
$this->args['css_left'] = $this->args['margin_x'] . 'px';
|
162 |
+
|
163 |
+
} elseif ( $this->args['align_x'] == 'center' ) {
|
164 |
+
|
165 |
+
$this->args['css_left'] = '50%';
|
166 |
+
$this->args['margin_left'] = isset( $this->args['size_w'] ) ? (string)( $this->args['size_w'] / -2 ) . 'px' : '0px';
|
167 |
+
}
|
168 |
+
}
|
169 |
+
}
|
170 |
+
|
171 |
+
/**
|
172 |
+
* Process vertical alignment
|
173 |
+
*/
|
174 |
+
protected function _processVerticalAlignment(){
|
175 |
+
|
176 |
+
if ( isset( $this->args['align_y'] ) && isset( $this->args['margin_y'] )) {
|
177 |
+
|
178 |
+
if ( $this->args['align_y'] == 'bottom' ) {
|
179 |
+
|
180 |
+
$this->args['css_bottom'] = $this->args['margin_y'] . 'px';
|
181 |
+
|
182 |
+
} elseif ( $this->args['align_y'] == 'top' ) {
|
183 |
+
|
184 |
+
$this->args['css_top'] = $this->args['margin_y'] . 'px';
|
185 |
+
|
186 |
+
}
|
187 |
+
}
|
188 |
+
}
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Process border radii
|
192 |
+
*/
|
193 |
+
protected function _processBorderRadii(){
|
194 |
+
|
195 |
+
// Border Radius
|
196 |
+
// Because the button could be touching the edge of the screen,
|
197 |
+
// check that margin is greater than border radius for corners that touch.
|
198 |
+
if (
|
199 |
+
!isset( $this->args['border_radius'] ) ||
|
200 |
+
!isset( $this->args['align_x'] ) ||
|
201 |
+
!isset( $this->args['align_y'] ) ||
|
202 |
+
!isset( $this->args['margin_x'] ) ||
|
203 |
+
!isset( $this->args['margin_y'] )
|
204 |
+
) {
|
205 |
+
return false;
|
206 |
+
}
|
207 |
+
|
208 |
+
$x_sides = array( 'left', 'right' );
|
209 |
+
$y_sides = array( 'top', 'bottom' );
|
210 |
+
|
211 |
+
foreach ( $x_sides as $x_side ) {
|
212 |
+
foreach ( $y_sides as $y_side ) {
|
213 |
+
|
214 |
+
if (
|
215 |
+
!( $this->args['align_x'] == $x_side && $this->args['margin_x'] == 0 ) && // touching left or right
|
216 |
+
!( $this->args['align_y'] == $y_side && $this->args['margin_y'] == 0 ) // touching top or bottom
|
217 |
+
) {
|
218 |
+
$this->args["border_radius_{$y_side}_{$x_side}"] = (string)$this->args['border_radius'] . 'px';
|
219 |
+
}
|
220 |
+
}
|
221 |
+
}
|
222 |
+
|
223 |
+
return true;
|
224 |
+
}
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Process size
|
228 |
+
*/
|
229 |
+
protected function _processSize(){
|
230 |
+
|
231 |
+
if ( isset( $this->args['size_w'] ) ) {
|
232 |
+
$this->args['size_w'] = (string)$this->args['size_w'] . 'px';
|
233 |
+
}
|
234 |
+
if ( isset( $this->args['size_h'] ) ) {
|
235 |
+
$this->args['size_h'] = (string)($this->args['size_h'] - 2) . 'px';
|
236 |
+
$this->args['padding_top'] = '2px';
|
237 |
+
}
|
238 |
+
}
|
239 |
+
|
240 |
+
/**
|
241 |
+
* Process opacity
|
242 |
+
*/
|
243 |
+
protected function _processOpacity(){
|
244 |
+
|
245 |
+
if ( isset( $this->args['opacity'] ) ) {
|
246 |
+
$this->args['opacity'] = number_format( ( $this->args['opacity'] ) / 100, 1 );
|
247 |
+
}
|
248 |
+
}
|
249 |
+
|
250 |
+
/**
|
251 |
+
* Process icon size
|
252 |
+
*/
|
253 |
+
protected function _processIconSize(){
|
254 |
+
|
255 |
+
// Text size
|
256 |
+
if ( isset( $this->args['font_size'] ) ) {
|
257 |
+
$this->args['font_size'] = (string)$this->args['font_size'] . 'px';
|
258 |
+
}
|
259 |
+
|
260 |
+
// Default icon size
|
261 |
+
if ( !isset( $this->args['icon_size'] ) ) {
|
262 |
+
$this->args['icon_size'] = 'fa-2x';
|
263 |
+
}
|
264 |
+
}
|
265 |
+
|
266 |
+
/**
|
267 |
+
* Scroll button allowed right now?
|
268 |
+
*
|
269 |
+
* @return bool
|
270 |
+
*/
|
271 |
+
public function isAuthorized(){
|
272 |
+
|
273 |
+
if ( isset( $this->args['enabled'] ) ) {
|
274 |
+
if ( $this->args['enabled'] == 'public' ) {
|
275 |
+
return true;
|
276 |
+
} elseif ( $this->args['enabled'] == 'preview' && is_user_logged_in() ) {
|
277 |
+
return true;
|
278 |
+
}
|
279 |
+
}
|
280 |
+
return false;
|
281 |
+
}
|
282 |
+
|
283 |
+
}}
|
framework/JmsAdminSettingsPage.php
ADDED
@@ -0,0 +1,959 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Admin Settings Page class
|
4 |
+
* This is an abstract implementation of an admin menu settings page
|
5 |
+
*
|
6 |
+
* @author Joe Sexton <joe@josephmsexton.com>
|
7 |
+
* @package WordPress
|
8 |
+
* @subpackage JMS Plugin Framework
|
9 |
+
* @version 1.2
|
10 |
+
* @uses JmsController
|
11 |
+
* @uses JmsUserOptionsCollection
|
12 |
+
*/
|
13 |
+
if ( !class_exists( 'JmsAdminSettingsPage' ) ){
|
14 |
+
abstract class JmsAdminSettingsPage extends JmsController {
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @var string
|
18 |
+
*/
|
19 |
+
protected $settingsPageTitle = '';
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @var string
|
23 |
+
*/
|
24 |
+
protected $settingsMenuTitle = '';
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @var string
|
28 |
+
*/
|
29 |
+
protected $settingsMenuSlug = '';
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @var JmsUserOptionsCollection
|
33 |
+
*/
|
34 |
+
protected $options = '';
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @var string
|
38 |
+
*/
|
39 |
+
protected $icon = '';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @var string
|
43 |
+
*/
|
44 |
+
protected $menuPosition = null;
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @var string
|
48 |
+
*/
|
49 |
+
protected $manageSettingsCapability = 'manage_options';
|
50 |
+
|
51 |
+
/**
|
52 |
+
* settings page title
|
53 |
+
*
|
54 |
+
* @return string
|
55 |
+
*/
|
56 |
+
public function settingsPageTitle() {
|
57 |
+
|
58 |
+
return $this->settingsPageTitle;
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* settings menu title
|
63 |
+
*
|
64 |
+
* @return string
|
65 |
+
*/
|
66 |
+
public function settingsMenuTitle() {
|
67 |
+
|
68 |
+
return $this->settingsMenuTitle;
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* settings menu slug
|
73 |
+
*
|
74 |
+
* @return string
|
75 |
+
*/
|
76 |
+
public function settingsMenuSlug() {
|
77 |
+
|
78 |
+
return $this->settingsMenuSlug;
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* manage settings capability
|
83 |
+
*
|
84 |
+
* @return string
|
85 |
+
*/
|
86 |
+
public function manageSettingsCapability() {
|
87 |
+
|
88 |
+
return $this->manageSettingsCapability;
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* init admin settings page
|
93 |
+
*
|
94 |
+
* @param string $settingsPageTitle
|
95 |
+
* @param string $settingsMenuTitle
|
96 |
+
* @param JmsUserOptionsCollection $options
|
97 |
+
* @param string $menuMethod
|
98 |
+
*/
|
99 |
+
protected function _initAdminSettingsPage( $settingsPageTitle, $settingsMenuTitle, JmsUserOptionsCollection $options, $menuMethod ){
|
100 |
+
|
101 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'enqueueAdminSettingsPageScripts' ) );
|
102 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'enqueueAdminSettingsPageStyles' ) );
|
103 |
+
|
104 |
+
add_action( 'admin_init', array( $this, 'registerSettings' ) );
|
105 |
+
|
106 |
+
$this->settingsPageTitle = $settingsPageTitle;
|
107 |
+
$this->settingsMenuTitle = $settingsMenuTitle;
|
108 |
+
$this->options = $options;
|
109 |
+
|
110 |
+
$this->settingsMenuSlug = sanitize_title( $settingsMenuTitle );
|
111 |
+
|
112 |
+
$actionName = $menuMethod . 'Action';
|
113 |
+
add_action( 'admin_menu', array( $this, $actionName ) );
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* enqueue admin settings page scripts
|
118 |
+
*/
|
119 |
+
public function enqueueAdminSettingsPageScripts() {
|
120 |
+
|
121 |
+
wp_enqueue_script( 'jquery' );
|
122 |
+
wp_enqueue_script( 'wp-color-picker' );
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* enqueue admin settings page styles
|
127 |
+
*/
|
128 |
+
public function enqueueAdminSettingsPageStyles() {
|
129 |
+
|
130 |
+
wp_enqueue_style( 'wp-color-picker' );
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* allows a user to call $this->addXxxxxPage( string $pageTitle, string $menuTitle, JmsUserOptionsCollection $options )
|
135 |
+
* internally handles calls like $this->addXxxxxPageAction() and adds the appropriate menu page
|
136 |
+
*
|
137 |
+
* @param string $method
|
138 |
+
* @param array $args
|
139 |
+
* @return boolean|void
|
140 |
+
*/
|
141 |
+
public function __call( $method, $args ){
|
142 |
+
|
143 |
+
// first letters are 'add', last letters are 'Page'
|
144 |
+
if ( $this->_callMethodHasPrefixAndSuffix( $method, 'add', 'Page' ) ) {
|
145 |
+
// must be a valid menu type
|
146 |
+
$menuType = $this->_getCallMethodTypeFromCalledMethod( $method, 'add', 'Page' );
|
147 |
+
if ( !$this->_isValidMenuType( $menuType ) && !$this->_isValidSubMenuType( $menuType ) ) {
|
148 |
+
|
149 |
+
return false;
|
150 |
+
}
|
151 |
+
|
152 |
+
// must have correct arguments to initialize
|
153 |
+
if ( $this->_calledMethodWithCorrectArguments( $args ) ) {
|
154 |
+
|
155 |
+
$this->_initAdminSettingsPage( $args[0], $args[1], $args[2], $method );
|
156 |
+
}
|
157 |
+
|
158 |
+
return true;
|
159 |
+
|
160 |
+
// first letters are 'add', last letters are 'PageAction'
|
161 |
+
} elseif ( $this->_callMethodHasPrefixAndSuffix( $method, 'add', 'PageAction' ) ) {
|
162 |
+
|
163 |
+
// get method name
|
164 |
+
$menuType = $this->_getCallMethodTypeFromCalledMethod( $method, 'add', 'PageAction' );
|
165 |
+
if ( !$this->_isValidMenuType( $menuType ) && !$this->_isValidSubMenuType( $menuType ) ) {
|
166 |
+
|
167 |
+
return false;
|
168 |
+
}
|
169 |
+
|
170 |
+
$this->_callAddMenuPageMethod( $menuType );
|
171 |
+
|
172 |
+
return true;
|
173 |
+
}
|
174 |
+
|
175 |
+
// bad method call
|
176 |
+
return false;
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* __call method has a prefix and suffix
|
181 |
+
*
|
182 |
+
* @param string $method
|
183 |
+
* @param string $prefix
|
184 |
+
* @param string $suffix
|
185 |
+
* @return boolean
|
186 |
+
*/
|
187 |
+
protected function _callMethodHasPrefixAndSuffix( $method, $prefix, $suffix ){
|
188 |
+
|
189 |
+
return substr( $method, 0, 3 ) == $prefix &&
|
190 |
+
substr( $method, ( strlen( $method ) - strlen( $suffix ) ), strlen( $method ) ) == $suffix;
|
191 |
+
}
|
192 |
+
|
193 |
+
/**
|
194 |
+
* __call'ed method with correct parameters
|
195 |
+
*
|
196 |
+
* @param array $args
|
197 |
+
* @return boolean
|
198 |
+
*/
|
199 |
+
protected function _calledMethodWithCorrectArguments( $args ){
|
200 |
+
|
201 |
+
return isset( $args[0] ) &&
|
202 |
+
isset( $args[1] ) &&
|
203 |
+
isset( $args[2] ) &&
|
204 |
+
is_string( $args[0] ) &&
|
205 |
+
is_string( $args[1] ) &&
|
206 |
+
$args[2] instanceof JmsUserOptionsCollection;
|
207 |
+
}
|
208 |
+
|
209 |
+
/**
|
210 |
+
* get method type from the called method name
|
211 |
+
*
|
212 |
+
* @param string $method
|
213 |
+
* @param string $prefix
|
214 |
+
* @param string $suffix
|
215 |
+
* @return string
|
216 |
+
*/
|
217 |
+
protected function _getCallMethodTypeFromCalledMethod( $method, $prefix, $suffix ){
|
218 |
+
|
219 |
+
$method = substr( $method, ( strlen( $prefix ) ), ( strlen( $method ) - strlen( $suffix ) - strlen( $prefix ) ) );
|
220 |
+
$method = strtolower( $method );
|
221 |
+
|
222 |
+
return $method;
|
223 |
+
}
|
224 |
+
|
225 |
+
/**
|
226 |
+
* is a valid menu type
|
227 |
+
*
|
228 |
+
* @param string $menuType
|
229 |
+
* @return bool
|
230 |
+
*/
|
231 |
+
protected function _isValidMenuType( $menuType ){
|
232 |
+
|
233 |
+
$menuPageMethods = $this->_getMenuPageMethods();
|
234 |
+
|
235 |
+
return isset( $menuPageMethods[$menuType] );
|
236 |
+
}
|
237 |
+
|
238 |
+
/**
|
239 |
+
* is a valid sub menu type
|
240 |
+
*
|
241 |
+
* @param string $menuType
|
242 |
+
* @return bool
|
243 |
+
*/
|
244 |
+
protected function _isValidSubMenuType( $menuType ) {
|
245 |
+
|
246 |
+
$subMenuPageMethods = $this->_getSubMenuPageMethods();
|
247 |
+
|
248 |
+
return isset($subMenuPageMethods[$menuType] );
|
249 |
+
}
|
250 |
+
|
251 |
+
/**
|
252 |
+
* get the correct add_xxxx_menu() menu page method
|
253 |
+
*
|
254 |
+
* @param string $menuType
|
255 |
+
* @return string|null
|
256 |
+
*/
|
257 |
+
protected function _getAddMenuPageMethod( $menuType ){
|
258 |
+
|
259 |
+
$menuPageMethods = $this->_getMenuPageMethods();
|
260 |
+
|
261 |
+
return isset( $menuPageMethods[$menuType] ) ? $menuPageMethods[$menuType] : null;
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* get the correct add_xxxx_menu() submenu page method
|
266 |
+
*
|
267 |
+
* @param string $menuType
|
268 |
+
* @return string|null
|
269 |
+
*/
|
270 |
+
protected function _getAddSubMenuPageMethod( $menuType ){
|
271 |
+
|
272 |
+
$subMenuPageMethods = $this->_getSubMenuPageMethods();
|
273 |
+
|
274 |
+
return isset( $subMenuPageMethods[$menuType] ) ? $subMenuPageMethods[$menuType] : null;
|
275 |
+
}
|
276 |
+
|
277 |
+
/**
|
278 |
+
* returns an array of menu page methods
|
279 |
+
*
|
280 |
+
* @return array
|
281 |
+
* @see http://codex.wordpress.org/Administration_Menus
|
282 |
+
*/
|
283 |
+
protected function _getMenuPageMethods(){
|
284 |
+
|
285 |
+
// menu pages
|
286 |
+
return array(
|
287 |
+
'menu' => 'add_menu_page',
|
288 |
+
'object' => 'add_object_page',
|
289 |
+
'utility' => 'add_utility_page',
|
290 |
+
);
|
291 |
+
}
|
292 |
+
|
293 |
+
/**
|
294 |
+
* returns an array of sub menu page methods
|
295 |
+
*
|
296 |
+
* @return array
|
297 |
+
* @see http://codex.wordpress.org/Administration_Menus
|
298 |
+
*/
|
299 |
+
protected function _getSubMenuPageMethods(){
|
300 |
+
|
301 |
+
// submenu pages
|
302 |
+
return array(
|
303 |
+
'dashboard' => 'add_dashboard_page',
|
304 |
+
'posts' => 'add_posts_page',
|
305 |
+
'media' => 'add_media_page',
|
306 |
+
'links' => 'add_links_page',
|
307 |
+
'pages' => 'add_pages_page',
|
308 |
+
'comments' => 'add_comments_page',
|
309 |
+
'theme' => 'add_theme_page',
|
310 |
+
'plugins' => 'add_plugins_page',
|
311 |
+
'users' => 'add_users_page',
|
312 |
+
'management' => 'add_management_page',
|
313 |
+
'options' => 'add_options_page',
|
314 |
+
);
|
315 |
+
}
|
316 |
+
|
317 |
+
/**
|
318 |
+
* calls the add menu/submenu page method with the appropriate arguments
|
319 |
+
*
|
320 |
+
* @param string $menuType
|
321 |
+
*/
|
322 |
+
protected function _callAddMenuPageMethod( $menuType ){
|
323 |
+
|
324 |
+
// add menu page
|
325 |
+
if ( $this->_isValidMenuType( $menuType ) ) {
|
326 |
+
|
327 |
+
$method = $this->_getAddMenuPageMethod( $menuType );
|
328 |
+
$method(
|
329 |
+
__( $this->settingsPageTitle(), $this->textDomain() ),
|
330 |
+
__( $this->settingsMenuTitle(), $this->textDomain() ),
|
331 |
+
$this->manageSettingsCapability(),
|
332 |
+
$this->settingsMenuSlug(),
|
333 |
+
array( $this, 'renderAdminPage' )
|
334 |
+
);
|
335 |
+
|
336 |
+
// add admin submenu page
|
337 |
+
} else {
|
338 |
+
|
339 |
+
$method = $this->_getAddSubMenuPageMethod( $menuType );
|
340 |
+
|
341 |
+
// it's a pretty big pain to determine default menu positions, only add that param
|
342 |
+
// if we actually have a menu position set
|
343 |
+
if ( $this->menuPosition ) {
|
344 |
+
|
345 |
+
$method(
|
346 |
+
__( $this->settingsPageTitle(), $this->textDomain() ),
|
347 |
+
__( $this->settingsMenuTitle(), $this->textDomain() ),
|
348 |
+
$this->manageSettingsCapability(),
|
349 |
+
$this->settingsMenuSlug(),
|
350 |
+
array( $this, 'renderAdminPage' ),
|
351 |
+
$this->icon,
|
352 |
+
$this->menuPosition
|
353 |
+
);
|
354 |
+
} else {
|
355 |
+
$method(
|
356 |
+
__( $this->settingsPageTitle(), $this->textDomain() ),
|
357 |
+
__( $this->settingsMenuTitle(), $this->textDomain() ),
|
358 |
+
$this->manageSettingsCapability(),
|
359 |
+
$this->settingsMenuSlug(),
|
360 |
+
array( $this, 'renderAdminPage' ),
|
361 |
+
$this->icon
|
362 |
+
);
|
363 |
+
}
|
364 |
+
}
|
365 |
+
}
|
366 |
+
|
367 |
+
/**
|
368 |
+
* render admin page
|
369 |
+
*/
|
370 |
+
public function renderAdminPage() {
|
371 |
+
|
372 |
+
if ( !current_user_can( $this->manageSettingsCapability() ) ) {
|
373 |
+
wp_die( __( 'You do not have sufficient permissions to access this page.', $this->textDomain() ) );
|
374 |
+
}
|
375 |
+
|
376 |
+
$args = array(
|
377 |
+
'settings_page_slug' => $this->settingsMenuSlug(),
|
378 |
+
'option_group' => $this->options->optionsGroup(),
|
379 |
+
'option_key' => $this->options->optionsKey(),
|
380 |
+
);
|
381 |
+
|
382 |
+
$this->render( 'framework:admin:settings', $args );
|
383 |
+
}
|
384 |
+
|
385 |
+
/**
|
386 |
+
* admin settings init
|
387 |
+
*/
|
388 |
+
public function registerSettings() {
|
389 |
+
|
390 |
+
$map = $this->options->optionMap();
|
391 |
+
|
392 |
+
register_setting(
|
393 |
+
$this->options->optionsGroup(),
|
394 |
+
$this->options->optionsKey(),
|
395 |
+
array( $this, 'validateFields' )
|
396 |
+
);
|
397 |
+
|
398 |
+
// map is broken up into sections, parse each one
|
399 |
+
foreach ( $map as $sectionKey => $sectionDetails ) {
|
400 |
+
$this->_addSettingsSection( $sectionKey, $sectionDetails );
|
401 |
+
}
|
402 |
+
}
|
403 |
+
|
404 |
+
/**
|
405 |
+
* add settings section
|
406 |
+
*
|
407 |
+
* @param string $sectionKey
|
408 |
+
* @param string $sectionDetails
|
409 |
+
* @return bool|void
|
410 |
+
*/
|
411 |
+
protected function _addSettingsSection( $sectionKey, $sectionDetails ) {
|
412 |
+
|
413 |
+
if ( !isset( $sectionDetails['label'] ) || !isset( $sectionDetails['fields'] ) ) {
|
414 |
+
return false;
|
415 |
+
}
|
416 |
+
|
417 |
+
add_settings_section(
|
418 |
+
$sectionKey,
|
419 |
+
$sectionDetails['label'],
|
420 |
+
array( $this, 'renderSectionText' ),
|
421 |
+
$this->settingsMenuSlug()
|
422 |
+
);
|
423 |
+
|
424 |
+
foreach ( $sectionDetails['fields'] as $fieldKey => $fieldDetails ) {
|
425 |
+
|
426 |
+
$this->_addSettingsField( $fieldKey, $sectionKey );
|
427 |
+
}
|
428 |
+
}
|
429 |
+
|
430 |
+
/**
|
431 |
+
* add settings field
|
432 |
+
*
|
433 |
+
* @param string $fieldKey
|
434 |
+
* @param string $sectionKey
|
435 |
+
*/
|
436 |
+
protected function _addSettingsField( $fieldKey, $sectionKey ) {
|
437 |
+
|
438 |
+
$fieldLabel = $this->options->fieldOption( $fieldKey, 'label' );
|
439 |
+
$fieldType = $this->options->fieldOption( $fieldKey, 'type' );
|
440 |
+
$required = $this->options->fieldOption( $fieldKey, 'required' );
|
441 |
+
|
442 |
+
if ( $required === true ) {
|
443 |
+
$fieldLabel .= $this->requiredIndicator();
|
444 |
+
}
|
445 |
+
|
446 |
+
$callback = $this->_getInputCallback( $fieldType );
|
447 |
+
|
448 |
+
add_settings_field(
|
449 |
+
$fieldKey,
|
450 |
+
apply_filters( 'jms_admin_settings_option_field_label', $fieldLabel ),
|
451 |
+
array( $this, $callback ),
|
452 |
+
$this->settingsMenuSlug(),
|
453 |
+
$sectionKey,
|
454 |
+
array(
|
455 |
+
'field_key' => $fieldKey,
|
456 |
+
)
|
457 |
+
);
|
458 |
+
}
|
459 |
+
|
460 |
+
/**
|
461 |
+
* get input callback function
|
462 |
+
*
|
463 |
+
* @param string $type
|
464 |
+
* @return string
|
465 |
+
*/
|
466 |
+
protected function _getInputCallback( $type ){
|
467 |
+
|
468 |
+
switch ($type) {
|
469 |
+
case 'radio':
|
470 |
+
return 'renderRadioInput';
|
471 |
+
case 'checkbox':
|
472 |
+
return 'renderCheckboxInput';
|
473 |
+
case 'textarea':
|
474 |
+
return 'renderTextareaInput';
|
475 |
+
case 'text':
|
476 |
+
default:
|
477 |
+
return 'renderTextInput';
|
478 |
+
}
|
479 |
+
}
|
480 |
+
|
481 |
+
/**
|
482 |
+
* render section text
|
483 |
+
*
|
484 |
+
* @param array $sectionDetails
|
485 |
+
*/
|
486 |
+
public function renderSectionText( $sectionDetails ) {
|
487 |
+
|
488 |
+
$key = isset( $sectionDetails['id'] ) ? $sectionDetails['id'] : null;
|
489 |
+
|
490 |
+
if ( $key ) {
|
491 |
+
echo apply_filters( 'jms_admin_settings_section_text', $this->options->sectionOption( $key, 'description' ) );
|
492 |
+
}
|
493 |
+
}
|
494 |
+
|
495 |
+
/**
|
496 |
+
* render text input
|
497 |
+
*
|
498 |
+
* @param array $args
|
499 |
+
*/
|
500 |
+
public function renderTextInput( $args ) {
|
501 |
+
$fieldKey = $args['field_key'];
|
502 |
+
|
503 |
+
$dataType = $this->options->fieldOption( $fieldKey, 'data_type' );
|
504 |
+
|
505 |
+
if ( $dataType == 'integer' || $dataType == 'float' ) {
|
506 |
+
$inputType = 'number';
|
507 |
+
} else {
|
508 |
+
$inputType = 'text';
|
509 |
+
}
|
510 |
+
|
511 |
+
$args = array(
|
512 |
+
'plugin_option_name' => $this->options->optionsKey(),
|
513 |
+
'field_key' => $fieldKey,
|
514 |
+
'option_value' => $this->options->getOption( $fieldKey ),
|
515 |
+
'input_type' => $inputType,
|
516 |
+
'extra_attributes' => $this->_extraAtts( $fieldKey, $inputType ),
|
517 |
+
'units' => $this->options->fieldOption( $fieldKey, 'units' ),
|
518 |
+
'options' => $this->options->fieldOption( $fieldKey, 'options' ),
|
519 |
+
);
|
520 |
+
|
521 |
+
$this->render( apply_filters( 'jms_admin_settings_text_input_template', 'framework:admin:partials:text_input' ), $args );
|
522 |
+
}
|
523 |
+
|
524 |
+
/**
|
525 |
+
* render checkbox input
|
526 |
+
*
|
527 |
+
* @param array $args
|
528 |
+
*/
|
529 |
+
public function renderCheckboxInput( $args ) {
|
530 |
+
$fieldKey = $args['field_key'];
|
531 |
+
|
532 |
+
$args = array(
|
533 |
+
'plugin_option_name' => $this->options->optionsKey(),
|
534 |
+
'field_key' => $fieldKey,
|
535 |
+
'field_label' => $this->options->fieldOption( $fieldKey, 'label' ),
|
536 |
+
'option_value' => $this->options->getOption( $fieldKey ),
|
537 |
+
'extra_attributes' => $this->_extraAtts( $fieldKey, 'checkbox' ),
|
538 |
+
);
|
539 |
+
|
540 |
+
$this->render( apply_filters( 'jms_admin_settings_checkbox_input_template', 'framework:admin:partials:checkbox_input' ), $args );
|
541 |
+
}
|
542 |
+
|
543 |
+
/**
|
544 |
+
* render radio input
|
545 |
+
*
|
546 |
+
* @param array $args
|
547 |
+
*/
|
548 |
+
public function renderRadioInput( $args ) {
|
549 |
+
$fieldKey = $args['field_key'];
|
550 |
+
|
551 |
+
$args = array(
|
552 |
+
'plugin_option_name' => $this->options->optionsKey(),
|
553 |
+
'field_key' => $fieldKey,
|
554 |
+
'option_value' => $this->options->getOption( $fieldKey ),
|
555 |
+
'extra_attributes' => $this->_extraAtts( $fieldKey, 'radio' ),
|
556 |
+
);
|
557 |
+
|
558 |
+
foreach ( $this->options->fieldOption( $fieldKey, 'choices' ) as $choiceKey => $choiceLabel ) {
|
559 |
+
|
560 |
+
$args['choice_key'] = $choiceKey;
|
561 |
+
$args['choice_label'] = $choiceLabel;
|
562 |
+
|
563 |
+
$this->render( apply_filters( 'jms_admin_settings_radio_input_template', 'framework:admin:partials:radio_input' ), $args );
|
564 |
+
}
|
565 |
+
}
|
566 |
+
|
567 |
+
/**
|
568 |
+
* render textarea input
|
569 |
+
*
|
570 |
+
* @param array $args
|
571 |
+
*/
|
572 |
+
public function renderTextareaInput( $args ) {
|
573 |
+
$fieldKey = $args['field_key'];
|
574 |
+
|
575 |
+
$args = array(
|
576 |
+
'plugin_option_name' => $this->options->optionsKey(),
|
577 |
+
'field_key' => $fieldKey,
|
578 |
+
'option_value' => $this->options->getOption( $fieldKey ),
|
579 |
+
'extra_attributes' => $this->_extraAtts( $fieldKey, 'textarea' ),
|
580 |
+
);
|
581 |
+
|
582 |
+
$this->render( apply_filters( 'jms_admin_settings_textarea_input_template', 'framework:admin:partials:textarea_input' ), $args );
|
583 |
+
}
|
584 |
+
|
585 |
+
/**
|
586 |
+
* get extra html attributes
|
587 |
+
*
|
588 |
+
* @param string $fieldKey
|
589 |
+
* @param string $inputType
|
590 |
+
* @return string
|
591 |
+
*/
|
592 |
+
protected function _extraAtts( $fieldKey, $inputType ){
|
593 |
+
|
594 |
+
$atts = array();
|
595 |
+
|
596 |
+
$dataType = $this->options->fieldOption( $fieldKey, 'data_type' );
|
597 |
+
|
598 |
+
switch ( $inputType ) {
|
599 |
+
case 'number':
|
600 |
+
if ( $dataType == 'integer' ) {
|
601 |
+
$atts[] = 'step="1"';
|
602 |
+
$atts[] = 'pattern="\d+"';
|
603 |
+
} elseif( $dataType == 'float') {
|
604 |
+
$atts[] = 'step="any"';
|
605 |
+
}
|
606 |
+
|
607 |
+
$min = $this->options->fieldOption( $fieldKey, 'min' );
|
608 |
+
$max = $this->options->fieldOption( $fieldKey, 'max' );
|
609 |
+
|
610 |
+
if ( is_int( $min ) ) {
|
611 |
+
$atts[] = 'min="' . $min . '"';
|
612 |
+
}
|
613 |
+
if ( is_int( $max ) ) {
|
614 |
+
$atts[] = 'max="' . $max . '"';
|
615 |
+
}
|
616 |
+
$atts = apply_filters( 'jms_admin_settings_number_input_field_extra_attributes', $atts );
|
617 |
+
break;
|
618 |
+
case 'textarea':
|
619 |
+
$columns = $this->options->fieldOption( $fieldKey, 'columns' );
|
620 |
+
$rows = $this->options->fieldOption( $fieldKey, 'rows' );
|
621 |
+
|
622 |
+
if ( is_int( $columns ) ) {
|
623 |
+
$atts[] = 'cols="' . $columns . '"';
|
624 |
+
}
|
625 |
+
if ( is_int( $rows ) ) {
|
626 |
+
$atts[] = 'rows="' . $rows . '"';
|
627 |
+
}
|
628 |
+
$atts = apply_filters( 'jms_admin_settings_textarea_input_field_extra_attributes', $atts );
|
629 |
+
break;
|
630 |
+
case 'text':
|
631 |
+
$atts = apply_filters( 'jms_admin_settings_text_input_field_extra_attributes', $atts );
|
632 |
+
break;
|
633 |
+
case 'radio':
|
634 |
+
$atts = apply_filters( 'jms_admin_settings_radio_input_field_extra_attributes', $atts );
|
635 |
+
break;
|
636 |
+
case 'checkbox':
|
637 |
+
$atts = apply_filters( 'jms_admin_settings_checkbox_input_field_extra_attributes', $atts );
|
638 |
+
break;
|
639 |
+
default:
|
640 |
+
break;
|
641 |
+
}
|
642 |
+
|
643 |
+
if ( $this->options->fieldOption( $fieldKey, 'required' ) === true ) {
|
644 |
+
$atts[] = 'required="required"';
|
645 |
+
}
|
646 |
+
|
647 |
+
return apply_filters( 'jms_admin_settings_input_field_extra_attributes', implode( ' ', $atts ) );
|
648 |
+
}
|
649 |
+
|
650 |
+
/**
|
651 |
+
* validate form fields
|
652 |
+
*
|
653 |
+
* @param array $fields
|
654 |
+
* @return array
|
655 |
+
*/
|
656 |
+
public function validateFields( $fields ) {
|
657 |
+
|
658 |
+
// check for restore to defaults
|
659 |
+
if ( isset( $fields['restore'] ) ) {
|
660 |
+
return $this->options->defaultOptions();
|
661 |
+
}
|
662 |
+
|
663 |
+
$options = $this->options->fields();
|
664 |
+
|
665 |
+
// make sure no extra options were posted.
|
666 |
+
foreach ( $fields as $fieldKey => $fieldVal ) {
|
667 |
+
if ( !isset( $fieldKey, $fields ) ) {
|
668 |
+
add_settings_error(
|
669 |
+
$fieldKey,
|
670 |
+
'error',
|
671 |
+
apply_filters( 'jms_admin_settings_error_invalid', __( $fieldKey . ' is not a valid option', $this->textDomain() ) ),
|
672 |
+
'error'
|
673 |
+
);
|
674 |
+
}
|
675 |
+
}
|
676 |
+
|
677 |
+
// process each option in the options map since we may not have been posted every option.
|
678 |
+
foreach ( $options as $optionKey => $optionLabel ) {
|
679 |
+
|
680 |
+
$this->_validateField( $fields, $optionKey, $optionLabel );
|
681 |
+
}
|
682 |
+
|
683 |
+
return $fields;
|
684 |
+
}
|
685 |
+
|
686 |
+
/**
|
687 |
+
* validate field
|
688 |
+
*
|
689 |
+
* @param array $fields
|
690 |
+
* @param string $optionKey
|
691 |
+
* @param string $optionLabel
|
692 |
+
*/
|
693 |
+
protected function _validateField( &$fields, $optionKey, $optionLabel ) {
|
694 |
+
|
695 |
+
$dataType = $this->options->fieldOption( $optionKey, 'data_type' );
|
696 |
+
|
697 |
+
// if the option wasn't posted it may be a boolean false, or may be a value the user wants to remove
|
698 |
+
if ( isset( $fields[$optionKey] ) ) {
|
699 |
+
if ( ( $dataType == 'integer' || $dataType == 'float' ) ) {
|
700 |
+
$this->_validateNumberField( $fields, $optionKey, $optionLabel );
|
701 |
+
} elseif( $dataType == 'string' ) {
|
702 |
+
$this->_validateStringField( $fields, $optionKey, $optionLabel );
|
703 |
+
} elseif ( $dataType == 'choice' ) {
|
704 |
+
$this->_validateChoiceField( $fields, $optionKey, $optionLabel );
|
705 |
+
} elseif ( $dataType == 'boolean' ) {
|
706 |
+
$this->_validateBooleanField( $fields, $optionKey, $optionLabel );
|
707 |
+
}
|
708 |
+
} elseif( $dataType == 'boolean' ) {
|
709 |
+
$fields[$optionKey] = 0;
|
710 |
+
}
|
711 |
+
}
|
712 |
+
|
713 |
+
/**
|
714 |
+
* validate numeric field
|
715 |
+
*
|
716 |
+
* @param array $fields
|
717 |
+
* @param string $optionKey
|
718 |
+
* @param string $optionLabel
|
719 |
+
*/
|
720 |
+
protected function _validateNumberField( &$fields, $optionKey, $optionLabel ) {
|
721 |
+
|
722 |
+
if ( !is_numeric( $fields[$optionKey] ) ) {
|
723 |
+
$fields[$optionKey] = $this->options->getOption( $optionKey );
|
724 |
+
add_settings_error(
|
725 |
+
$optionKey,
|
726 |
+
'error',
|
727 |
+
apply_filters( 'jms_admin_settings_error_invalid_number', __( $optionLabel . ' must be a numeric value', $this->textDomain() ) ),
|
728 |
+
'error'
|
729 |
+
);
|
730 |
+
}
|
731 |
+
|
732 |
+
$min = $this->options->fieldOption( $optionKey, 'min' );
|
733 |
+
if ( $fields[$optionKey] < $min ) {
|
734 |
+
$fields[$optionKey] = $this->options->getOption( $optionKey );
|
735 |
+
add_settings_error(
|
736 |
+
$optionKey,
|
737 |
+
'error',
|
738 |
+
apply_filters( 'jms_admin_settings_error_invalid_number', sprintf( __( $optionLabel . ' cannot be less than %s', $this->textDomain() ), $min ) ),
|
739 |
+
'error'
|
740 |
+
);
|
741 |
+
}
|
742 |
+
|
743 |
+
$max = $this->options->fieldOption( $optionKey, 'max' );
|
744 |
+
if ( $fields[$optionKey] > $max ) {
|
745 |
+
$fields[$optionKey] = $this->options->getOption( $optionKey );
|
746 |
+
add_settings_error(
|
747 |
+
$optionKey,
|
748 |
+
'error',
|
749 |
+
apply_filters( 'jms_admin_settings_error_invalid_number', sprintf( __( $optionLabel . ' cannot be greater than %s', $this->textDomain() ), $max ) ),
|
750 |
+
'error'
|
751 |
+
);
|
752 |
+
}
|
753 |
+
|
754 |
+
$dataType = $this->options->fieldOption( $optionKey, 'data_type' );
|
755 |
+
if ( $dataType == 'integer' ) {
|
756 |
+
$fields[$optionKey] = (int)$fields[$optionKey];
|
757 |
+
}
|
758 |
+
if ( $dataType == 'float' ) {
|
759 |
+
$fields[$optionKey] = (float)$fields[$optionKey];
|
760 |
+
}
|
761 |
+
}
|
762 |
+
|
763 |
+
/**
|
764 |
+
* validate string field
|
765 |
+
*
|
766 |
+
* @param array $fields
|
767 |
+
* @param string $optionKey
|
768 |
+
* @param string $optionLabel
|
769 |
+
*/
|
770 |
+
protected function _validateStringField( &$fields, $optionKey, $optionLabel ) {
|
771 |
+
// sanitize strings
|
772 |
+
$fields[$optionKey] = filter_var( $fields[$optionKey], FILTER_SANITIZE_STRING );
|
773 |
+
|
774 |
+
// check color
|
775 |
+
if ( $this->options->fieldOption( $optionKey, 'options' ) == 'color-picker' ) {
|
776 |
+
$this->_validateColorField( $fields, $optionKey, $optionLabel );
|
777 |
+
}
|
778 |
+
}
|
779 |
+
|
780 |
+
/**
|
781 |
+
* validate color field
|
782 |
+
*
|
783 |
+
* @param array $fields
|
784 |
+
* @param string $optionKey
|
785 |
+
* @param string $optionLabel
|
786 |
+
*/
|
787 |
+
protected function _validateColorField( &$fields, $optionKey, $optionLabel ) {
|
788 |
+
|
789 |
+
$colorHex = $fields[$optionKey];
|
790 |
+
if ( substr( $colorHex, 0, 1 ) == '#' ) {
|
791 |
+
$colorHex = substr( $colorHex, 1 );
|
792 |
+
}
|
793 |
+
|
794 |
+
if ( !ctype_xdigit( $colorHex ) ) {
|
795 |
+
$fields[$optionKey] = $this->options->getOption( $optionKey );
|
796 |
+
add_settings_error(
|
797 |
+
$optionKey,
|
798 |
+
'error',
|
799 |
+
apply_filters( 'jms_admin_settings_error_invalid_color', __( $optionLabel . ' must be a valid hexadecimal color value', $this->textDomain() ) ),
|
800 |
+
'error'
|
801 |
+
);
|
802 |
+
}
|
803 |
+
}
|
804 |
+
|
805 |
+
/**
|
806 |
+
* validate choice field
|
807 |
+
*
|
808 |
+
* @param array $fields
|
809 |
+
* @param string $optionKey
|
810 |
+
* @param string $optionLabel
|
811 |
+
*/
|
812 |
+
protected function _validateChoiceField( &$fields, $optionKey, $optionLabel ) {
|
813 |
+
|
814 |
+
$choices = $this->options->fieldOption( $optionKey, 'choices' );
|
815 |
+
if ( !isset( $choices[$fields[$optionKey]] ) ) {
|
816 |
+
$fields[$optionKey] = $this->options->getOption( $optionKey );
|
817 |
+
add_settings_error(
|
818 |
+
$optionKey,
|
819 |
+
'error',
|
820 |
+
apply_filters( 'jms_admin_settings_error_invalid_choice', __( $optionLabel . ' is not a valid selection', $this->textDomain() ) ),
|
821 |
+
'error'
|
822 |
+
);
|
823 |
+
}
|
824 |
+
}
|
825 |
+
|
826 |
+
/**
|
827 |
+
* validate boolean field
|
828 |
+
*
|
829 |
+
* @param array $fields
|
830 |
+
* @param string $optionKey
|
831 |
+
* @param string $optionLabel
|
832 |
+
*/
|
833 |
+
protected function _validateBooleanField( &$fields, $optionKey, $optionLabel ) {
|
834 |
+
$fields[$optionKey] = (bool)$fields[$optionKey];
|
835 |
+
}
|
836 |
+
|
837 |
+
/**
|
838 |
+
* required indicator
|
839 |
+
*
|
840 |
+
* @return string
|
841 |
+
*/
|
842 |
+
public function requiredIndicator(){
|
843 |
+
|
844 |
+
return $this->render( apply_filters( 'jms_admin_settings_required_indicator_template', 'framework:admin:partials:required_indicator' ), array(), false );
|
845 |
+
}
|
846 |
+
|
847 |
+
/**
|
848 |
+
* @param string $icon
|
849 |
+
*/
|
850 |
+
public function setIcon( $icon )
|
851 |
+
{
|
852 |
+
$this->icon = $icon;
|
853 |
+
}
|
854 |
+
|
855 |
+
/**
|
856 |
+
* @return string
|
857 |
+
*/
|
858 |
+
public function getIcon()
|
859 |
+
{
|
860 |
+
return $this->icon;
|
861 |
+
}
|
862 |
+
|
863 |
+
/**
|
864 |
+
* @param string $manageSettingsCapability
|
865 |
+
*/
|
866 |
+
public function setManageSettingsCapability( $manageSettingsCapability )
|
867 |
+
{
|
868 |
+
$this->manageSettingsCapability = $manageSettingsCapability;
|
869 |
+
}
|
870 |
+
|
871 |
+
/**
|
872 |
+
* @return string
|
873 |
+
*/
|
874 |
+
public function getManageSettingsCapability()
|
875 |
+
{
|
876 |
+
return $this->manageSettingsCapability;
|
877 |
+
}
|
878 |
+
|
879 |
+
/**
|
880 |
+
* @param string $menuPosition
|
881 |
+
*/
|
882 |
+
public function setMenuPosition( $menuPosition )
|
883 |
+
{
|
884 |
+
$this->menuPosition = $menuPosition;
|
885 |
+
}
|
886 |
+
|
887 |
+
/**
|
888 |
+
* @return string
|
889 |
+
*/
|
890 |
+
public function getMenuPosition()
|
891 |
+
{
|
892 |
+
return $this->menuPosition;
|
893 |
+
}
|
894 |
+
|
895 |
+
/**
|
896 |
+
* @param \JmsUserOptionsCollection $options
|
897 |
+
*/
|
898 |
+
public function setOptions( $options )
|
899 |
+
{
|
900 |
+
$this->options = $options;
|
901 |
+
}
|
902 |
+
|
903 |
+
/**
|
904 |
+
* @return \JmsUserOptionsCollection
|
905 |
+
*/
|
906 |
+
public function getOptions()
|
907 |
+
{
|
908 |
+
return $this->options;
|
909 |
+
}
|
910 |
+
|
911 |
+
/**
|
912 |
+
* @param string $settingsPageTitle
|
913 |
+
*/
|
914 |
+
public function setSettingsPageTitle( $settingsPageTitle )
|
915 |
+
{
|
916 |
+
$this->settingsPageTitle = $settingsPageTitle;
|
917 |
+
}
|
918 |
+
|
919 |
+
/**
|
920 |
+
* @return string
|
921 |
+
*/
|
922 |
+
public function getSettingsPageTitle()
|
923 |
+
{
|
924 |
+
return $this->settingsPageTitle;
|
925 |
+
}
|
926 |
+
|
927 |
+
/**
|
928 |
+
* @param string $settingsMenuSlug
|
929 |
+
*/
|
930 |
+
public function setSettingsMenuSlug( $settingsMenuSlug )
|
931 |
+
{
|
932 |
+
$this->settingsMenuSlug = $settingsMenuSlug;
|
933 |
+
}
|
934 |
+
|
935 |
+
/**
|
936 |
+
* @return string
|
937 |
+
*/
|
938 |
+
public function getSettingsMenuSlug()
|
939 |
+
{
|
940 |
+
return $this->settingsMenuSlug;
|
941 |
+
}
|
942 |
+
|
943 |
+
/**
|
944 |
+
* @param string $settingsMenuTitle
|
945 |
+
*/
|
946 |
+
public function setSettingsMenuTitle( $settingsMenuTitle )
|
947 |
+
{
|
948 |
+
$this->settingsMenuTitle = $settingsMenuTitle;
|
949 |
+
}
|
950 |
+
|
951 |
+
/**
|
952 |
+
* @return string
|
953 |
+
*/
|
954 |
+
public function getSettingsMenuTitle()
|
955 |
+
{
|
956 |
+
return $this->settingsMenuTitle;
|
957 |
+
}
|
958 |
+
}
|
959 |
+
}
|
framework/JmsBootstrap.php
ADDED
@@ -0,0 +1,178 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Bootstrap
|
4 |
+
* This class autoloads all classes in the plugin directory
|
5 |
+
* This class will instantiate each controller class automatically
|
6 |
+
*
|
7 |
+
* @author Joe Sexton <joe@josephmsexton.com>
|
8 |
+
* @package WordPress
|
9 |
+
* @subpackage JMS Plugin Framework
|
10 |
+
* @version 1.2
|
11 |
+
*/
|
12 |
+
if ( !class_exists( 'JmsBootstrap' ) ){
|
13 |
+
class JmsBootstrap {
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @var string
|
17 |
+
*/
|
18 |
+
protected $rootPath;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @var string
|
22 |
+
*/
|
23 |
+
protected $fwPath;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @var string
|
27 |
+
*/
|
28 |
+
protected $controllerPath;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* @var string
|
32 |
+
*/
|
33 |
+
protected $modelPath;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @var array
|
37 |
+
*/
|
38 |
+
protected $objects = array();
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @var string
|
42 |
+
*/
|
43 |
+
protected $pluginName;
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @var string
|
47 |
+
*/
|
48 |
+
protected $pluginFile;
|
49 |
+
|
50 |
+
/**
|
51 |
+
* constructor
|
52 |
+
*
|
53 |
+
* @param string $pluginFile
|
54 |
+
* @param string $pluginName
|
55 |
+
*/
|
56 |
+
public function __construct( $pluginFile, $pluginName = '' ) {
|
57 |
+
|
58 |
+
$rootPath = plugin_dir_path( $pluginFile );
|
59 |
+
|
60 |
+
if ( !$rootPath )
|
61 |
+
$rootPath = dirname( __FILE__ );
|
62 |
+
$this->rootPath = trailingslashit( $rootPath );
|
63 |
+
|
64 |
+
$this->fwPath = $this->rootPath . 'framework/';
|
65 |
+
$this->controllerPath = $this->rootPath . 'controller/';
|
66 |
+
$this->modelPath = $this->rootPath . 'model/';
|
67 |
+
|
68 |
+
$this->pluginFile = $pluginFile;
|
69 |
+
$this->pluginName = $pluginName;
|
70 |
+
|
71 |
+
spl_autoload_register( array( $this, '_autoload' ) );
|
72 |
+
|
73 |
+
$this->initControllers();
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* autoload
|
78 |
+
*
|
79 |
+
* @param $class
|
80 |
+
*/
|
81 |
+
protected function _autoload( $class ){
|
82 |
+
|
83 |
+
$this->_loadClassFile( $class );
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* load class file
|
88 |
+
* recursively searches all directories/subdirectories for class
|
89 |
+
* if class file is found, include()
|
90 |
+
*
|
91 |
+
* @param string $class
|
92 |
+
* @param string $dir
|
93 |
+
* @return bool
|
94 |
+
*/
|
95 |
+
protected function _loadClassFile( $class, $dir = null ) {
|
96 |
+
|
97 |
+
if ( is_null( $dir ) )
|
98 |
+
$dir = $this->rootPath;
|
99 |
+
|
100 |
+
foreach ( scandir( $dir ) as $file ) {
|
101 |
+
|
102 |
+
// directory?
|
103 |
+
if ( is_dir( $dir . $file ) && substr( $file, 0, 1 ) !== '.' )
|
104 |
+
$this->_loadClassFile( $class, $dir . $file . '/' );
|
105 |
+
|
106 |
+
// php file and filename matches class?
|
107 |
+
if (
|
108 |
+
substr( $file, 0, 1 ) !== '.' &&
|
109 |
+
preg_match( "/.php$/i" , $file ) &&
|
110 |
+
(str_replace( '.php', '', $file ) == $class || str_replace( '.class.php', '', $file ) == $class )
|
111 |
+
) {
|
112 |
+
include $dir . $file;
|
113 |
+
}
|
114 |
+
}
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* init controllers
|
119 |
+
* recursively instantiates all controllers in the controllers directory/subdirectory
|
120 |
+
*
|
121 |
+
* @param string $dir
|
122 |
+
* @return boolean
|
123 |
+
*/
|
124 |
+
public function initControllers( $dir = null ) {
|
125 |
+
|
126 |
+
if ( is_null( $dir ) )
|
127 |
+
$dir = $this->controllerPath;
|
128 |
+
|
129 |
+
if ( !is_dir( $dir ) )
|
130 |
+
return false;
|
131 |
+
|
132 |
+
foreach ( scandir( $dir ) as $file ) {
|
133 |
+
|
134 |
+
// directory?
|
135 |
+
if ( is_dir( $dir . $file ) && substr( $file, 0, 1 ) !== '.' )
|
136 |
+
$this->initControllers( $dir . $file . '/' );
|
137 |
+
|
138 |
+
// php file?
|
139 |
+
if( substr( $file, 0, 1 ) !== '.' && preg_match( "/.php$/i" , $file ) ) {
|
140 |
+
|
141 |
+
$class = str_replace( '.class.php', '', $file );
|
142 |
+
$class = str_replace( '.php', '', $class );
|
143 |
+
if ( class_exists( $class ) ) {
|
144 |
+
$this->objects[$class] = new $class( $this->pluginFile, $this->pluginName );
|
145 |
+
}
|
146 |
+
}
|
147 |
+
}
|
148 |
+
|
149 |
+
return true;
|
150 |
+
}
|
151 |
+
|
152 |
+
/**
|
153 |
+
* get objects
|
154 |
+
*
|
155 |
+
* @return array
|
156 |
+
*/
|
157 |
+
public function getObjects() {
|
158 |
+
|
159 |
+
return $this->objects;
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* get object
|
164 |
+
*
|
165 |
+
* @param string $class
|
166 |
+
* @return object|null
|
167 |
+
*/
|
168 |
+
public function getObject( $class ) {
|
169 |
+
|
170 |
+
if ( !empty( $this->objects[$class] ) ) {
|
171 |
+
|
172 |
+
return $this->objects[$class];
|
173 |
+
}
|
174 |
+
|
175 |
+
return null;
|
176 |
+
}
|
177 |
+
}
|
178 |
+
}
|
framework/JmsController.php
ADDED
@@ -0,0 +1,420 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Controller
|
5 |
+
* This is an abstract base controller that adds some handy properties and methods
|
6 |
+
*
|
7 |
+
* @author Joe Sexton <joe@josephmsexton.com>
|
8 |
+
* @package WordPress
|
9 |
+
* @subpackage JMS Plugin Framework
|
10 |
+
* @version 1.2
|
11 |
+
*/
|
12 |
+
if ( !class_exists( 'JmsController' ) ){
|
13 |
+
abstract class JmsController {
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @var string
|
17 |
+
*/
|
18 |
+
protected $rootPath;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @var string
|
22 |
+
*/
|
23 |
+
protected $fwPath;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @var string
|
27 |
+
*/
|
28 |
+
protected $controllerPath;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* @var string
|
32 |
+
*/
|
33 |
+
protected $modelPath;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @var string
|
37 |
+
*/
|
38 |
+
protected $viewPath;
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @var string
|
42 |
+
*/
|
43 |
+
protected $assetPath;
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @var string
|
47 |
+
*/
|
48 |
+
protected $pluginName;
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @var string
|
52 |
+
*/
|
53 |
+
protected $pluginSlug;
|
54 |
+
|
55 |
+
/**
|
56 |
+
* @var string
|
57 |
+
*/
|
58 |
+
protected $pluginFile;
|
59 |
+
|
60 |
+
/**
|
61 |
+
* constructor
|
62 |
+
*
|
63 |
+
* @param string $pluginFile
|
64 |
+
* @param string $pluginName
|
65 |
+
*/
|
66 |
+
public function __construct( $pluginFile, $pluginName = '' ) {
|
67 |
+
|
68 |
+
$rootPath = plugin_dir_path( $pluginFile );
|
69 |
+
$rootUrl = plugin_dir_url( $pluginFile );
|
70 |
+
|
71 |
+
$this->rootPath = $rootPath;
|
72 |
+
|
73 |
+
$this->fwPath = $this->rootPath . 'framework/';
|
74 |
+
$this->controllerPath = $this->rootPath . 'controller/';
|
75 |
+
$this->modelPath = $this->rootPath . 'model/';
|
76 |
+
$this->viewPath = $this->rootPath . 'view/';
|
77 |
+
$this->assetPath = $rootUrl . 'assets/';
|
78 |
+
|
79 |
+
$this->pluginFile = $pluginFile;
|
80 |
+
$this->pluginName = $pluginName;
|
81 |
+
|
82 |
+
$pathParts = explode( '/', $pluginFile );
|
83 |
+
$filename = array_pop( $pathParts );
|
84 |
+
$filenameParts = explode( '.', $filename );
|
85 |
+
$this->pluginSlug = array_shift( $filenameParts );
|
86 |
+
|
87 |
+
add_action( 'wp_enqueue_scripts', array( $this, 'enqueueScripts' ) );
|
88 |
+
add_action( 'wp_enqueue_scripts', array( $this, 'enqueueStyles' ) );
|
89 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'enqueueAdminScripts' ) );
|
90 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'enqueueAdminStyles' ) );
|
91 |
+
|
92 |
+
register_activation_hook( $this->pluginFile, array( $this, 'onActivation' ) );
|
93 |
+
register_deactivation_hook( $this->pluginFile, array( $this, 'onDeactivation' ) );
|
94 |
+
|
95 |
+
$this->_init();
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* enqueue script
|
100 |
+
* enqueue script using : separators for dirs in assets directory
|
101 |
+
* ie. render('acme:test') will render /assets/js/acme/test.js
|
102 |
+
*
|
103 |
+
* @param string $handle
|
104 |
+
* @param string $script
|
105 |
+
* @param array $deps
|
106 |
+
* @param string $ver
|
107 |
+
* @param boolean $footer
|
108 |
+
* @param array $localizedVars
|
109 |
+
* @return boolean
|
110 |
+
*/
|
111 |
+
public function enqueueScript(
|
112 |
+
$handle,
|
113 |
+
$script,
|
114 |
+
array $deps = array( 'jquery' ),
|
115 |
+
$ver = null,
|
116 |
+
$footer = true,
|
117 |
+
array $localizedVars = array()
|
118 |
+
) {
|
119 |
+
|
120 |
+
$script = str_replace( ':', '/', $script );
|
121 |
+
$file = $this->assetPath . 'js/' . $script . '.js';
|
122 |
+
|
123 |
+
wp_register_script( $handle, $file, $deps, $ver, $footer );
|
124 |
+
wp_enqueue_script( $handle );
|
125 |
+
|
126 |
+
foreach ( $localizedVars as $name => $vars ) {
|
127 |
+
|
128 |
+
wp_localize_script( $handle, $name, $vars );
|
129 |
+
}
|
130 |
+
|
131 |
+
return true;
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* enqueue style
|
136 |
+
* enqueue style using : separators for dirs in assets directory
|
137 |
+
* ie. render('acme:test') will render /assets/css/acme/test.css
|
138 |
+
*
|
139 |
+
* @param string $handle
|
140 |
+
* @param string $style
|
141 |
+
* @param array $deps
|
142 |
+
* @param string $ver
|
143 |
+
* @param string $media
|
144 |
+
* @return boolean
|
145 |
+
*/
|
146 |
+
public function enqueueStyle(
|
147 |
+
$handle,
|
148 |
+
$style,
|
149 |
+
array $deps = array(),
|
150 |
+
$ver = null,
|
151 |
+
$media = 'screen'
|
152 |
+
) {
|
153 |
+
|
154 |
+
$style = str_replace( ':', '/', $style );
|
155 |
+
$file = $this->assetPath . 'css/' . $style . '.css';
|
156 |
+
|
157 |
+
wp_register_style( $handle, $file, $deps, $ver, $media );
|
158 |
+
wp_enqueue_style( $handle );
|
159 |
+
|
160 |
+
return true;
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* enqueue script
|
165 |
+
* enqueue script using a public web path
|
166 |
+
*
|
167 |
+
* @param string $handle
|
168 |
+
* @param string $path
|
169 |
+
* @param array $deps
|
170 |
+
* @param string $ver
|
171 |
+
* @param boolean $footer
|
172 |
+
* @param array $localizedVars
|
173 |
+
* @return boolean
|
174 |
+
*/
|
175 |
+
public function enqueueCdnScript(
|
176 |
+
$handle,
|
177 |
+
$path,
|
178 |
+
array $deps = array( 'jquery' ),
|
179 |
+
$ver = null,
|
180 |
+
$footer = true,
|
181 |
+
array $localizedVars = array()
|
182 |
+
) {
|
183 |
+
wp_register_script( $handle, $path, $deps, $ver, $footer );
|
184 |
+
wp_enqueue_script( $handle );
|
185 |
+
|
186 |
+
foreach ( $localizedVars as $name => $vars ) {
|
187 |
+
|
188 |
+
wp_localize_script( $handle, $name, $vars );
|
189 |
+
}
|
190 |
+
|
191 |
+
return true;
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* enqueue style
|
196 |
+
* enqueue style using a public web path
|
197 |
+
*
|
198 |
+
* @param string $handle
|
199 |
+
* @param string $path
|
200 |
+
* @param array $deps
|
201 |
+
* @param string $ver
|
202 |
+
* @param string $media
|
203 |
+
* @return boolean
|
204 |
+
*/
|
205 |
+
public function enqueueCdnStyle(
|
206 |
+
$handle,
|
207 |
+
$path,
|
208 |
+
array $deps = array(),
|
209 |
+
$ver = null,
|
210 |
+
$media = 'screen'
|
211 |
+
) {
|
212 |
+
wp_register_style( $handle, $path, $deps, $ver, $media );
|
213 |
+
wp_enqueue_style( $handle );
|
214 |
+
|
215 |
+
return true;
|
216 |
+
}
|
217 |
+
|
218 |
+
/**
|
219 |
+
* render view
|
220 |
+
* call view using : separators for dirs in view directory
|
221 |
+
* ie. render('acme:test') will render /view/acme/test.php
|
222 |
+
*
|
223 |
+
* @param string $view view template
|
224 |
+
* @param array $args arguments used in the view
|
225 |
+
* @param boolean $echo true=print false=return
|
226 |
+
* @return string|boolean
|
227 |
+
*/
|
228 |
+
function render( $view, array $args = array(), $echo = true ){
|
229 |
+
|
230 |
+
$view = str_replace( ':', '/', $view );
|
231 |
+
$file = $this->viewPath . $view . '.php';
|
232 |
+
$assetPath = $this->assetPath;
|
233 |
+
|
234 |
+
if( !empty( $args ) )
|
235 |
+
extract( $args );
|
236 |
+
|
237 |
+
if ( !file_exists( $file ) )
|
238 |
+
return false;
|
239 |
+
|
240 |
+
if ( $echo ) {
|
241 |
+
include $file;
|
242 |
+
|
243 |
+
return true;
|
244 |
+
|
245 |
+
} else {
|
246 |
+
ob_start();
|
247 |
+
include $file;
|
248 |
+
$output = ob_get_contents();
|
249 |
+
ob_end_clean();
|
250 |
+
|
251 |
+
return $output;
|
252 |
+
}
|
253 |
+
}
|
254 |
+
|
255 |
+
/**
|
256 |
+
* render shortcode
|
257 |
+
* call view using : separators for dirs in view directory
|
258 |
+
* ie. renderShortcode('acme:test', $atts) will render /view/acme/test.php
|
259 |
+
*
|
260 |
+
* @param string $view view template
|
261 |
+
* @param array $atts attributes passed
|
262 |
+
* @param array $pairs supported/default attributes
|
263 |
+
* @param string $shortcode shortcode name
|
264 |
+
* @return string
|
265 |
+
*/
|
266 |
+
public function renderShortcode( $view, $atts, array $pairs = array(), $shortcode = '' ) {
|
267 |
+
|
268 |
+
$view = str_replace( ':', '/', $view );
|
269 |
+
$file = $this->viewPath . $view . '.php';
|
270 |
+
$assetPath = $this->assetPath;
|
271 |
+
|
272 |
+
extract( shortcode_atts( $pairs, $atts, $shortcode ) );
|
273 |
+
|
274 |
+
if ( !file_exists( $file ) )
|
275 |
+
return false;
|
276 |
+
|
277 |
+
ob_start();
|
278 |
+
include $file;
|
279 |
+
$output = ob_get_contents();
|
280 |
+
ob_end_clean();
|
281 |
+
|
282 |
+
return $output;
|
283 |
+
}
|
284 |
+
|
285 |
+
/**
|
286 |
+
* add actions
|
287 |
+
*/
|
288 |
+
protected function _init() {}
|
289 |
+
|
290 |
+
/**
|
291 |
+
* enqueue admin scripts
|
292 |
+
*/
|
293 |
+
public function enqueueScripts() {}
|
294 |
+
|
295 |
+
/**
|
296 |
+
* enqueue admin styles
|
297 |
+
*/
|
298 |
+
public function enqueueStyles() {}
|
299 |
+
|
300 |
+
/**
|
301 |
+
* enqueue admin scripts
|
302 |
+
*/
|
303 |
+
public function enqueueAdminScripts() {}
|
304 |
+
|
305 |
+
/**
|
306 |
+
* enqueue admin styles
|
307 |
+
*/
|
308 |
+
public function enqueueAdminStyles() {}
|
309 |
+
|
310 |
+
/**
|
311 |
+
* on activation
|
312 |
+
*/
|
313 |
+
public function onActivation() {}
|
314 |
+
|
315 |
+
/**
|
316 |
+
* on deactivation
|
317 |
+
*/
|
318 |
+
public function onDeactivation() {}
|
319 |
+
|
320 |
+
/**
|
321 |
+
* root path
|
322 |
+
*
|
323 |
+
* @return string
|
324 |
+
*/
|
325 |
+
public function rootPath(){
|
326 |
+
|
327 |
+
return $this->rootPath;
|
328 |
+
}
|
329 |
+
|
330 |
+
/**
|
331 |
+
* fw path
|
332 |
+
*
|
333 |
+
* @return string
|
334 |
+
*/
|
335 |
+
public function fwPath(){
|
336 |
+
|
337 |
+
return $this->fwPath;
|
338 |
+
}
|
339 |
+
|
340 |
+
/**
|
341 |
+
* controller path
|
342 |
+
*
|
343 |
+
* @return string
|
344 |
+
*/
|
345 |
+
public function controllerPath(){
|
346 |
+
|
347 |
+
return $this->controllerPath;
|
348 |
+
}
|
349 |
+
|
350 |
+
/**
|
351 |
+
* model path
|
352 |
+
*
|
353 |
+
* @return string
|
354 |
+
*/
|
355 |
+
public function modelPath(){
|
356 |
+
|
357 |
+
return $this->modelPath;
|
358 |
+
}
|
359 |
+
|
360 |
+
/**
|
361 |
+
* view path
|
362 |
+
*
|
363 |
+
* @return string
|
364 |
+
*/
|
365 |
+
public function viewPath(){
|
366 |
+
|
367 |
+
return $this->viewPath;
|
368 |
+
}
|
369 |
+
|
370 |
+
/**
|
371 |
+
* asset path
|
372 |
+
*
|
373 |
+
* @return string
|
374 |
+
*/
|
375 |
+
public function assetPath(){
|
376 |
+
|
377 |
+
return $this->assetPath;
|
378 |
+
}
|
379 |
+
|
380 |
+
/**
|
381 |
+
* plugin name
|
382 |
+
*
|
383 |
+
* @return string
|
384 |
+
*/
|
385 |
+
public function pluginName(){
|
386 |
+
|
387 |
+
return $this->pluginName;
|
388 |
+
}
|
389 |
+
|
390 |
+
/**
|
391 |
+
* plugin slug
|
392 |
+
*
|
393 |
+
* @return string
|
394 |
+
*/
|
395 |
+
public function pluginSlug(){
|
396 |
+
|
397 |
+
return $this->pluginSlug;
|
398 |
+
}
|
399 |
+
|
400 |
+
/**
|
401 |
+
* plugin file
|
402 |
+
*
|
403 |
+
* @return string
|
404 |
+
*/
|
405 |
+
public function pluginFile(){
|
406 |
+
|
407 |
+
return $this->pluginFile;
|
408 |
+
}
|
409 |
+
|
410 |
+
/**
|
411 |
+
* text domain
|
412 |
+
*
|
413 |
+
* @return string
|
414 |
+
*/
|
415 |
+
public function textDomain(){
|
416 |
+
|
417 |
+
return $this->pluginSlug;
|
418 |
+
}
|
419 |
+
}
|
420 |
+
}
|
framework/JmsUserOptionsCollection.php
ADDED
@@ -0,0 +1,234 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* User Options Collection class
|
4 |
+
* This class manages plugin options that a user would change.
|
5 |
+
*
|
6 |
+
* @author Joe Sexton <joe@josephmsexton.com>
|
7 |
+
* @package WordPress
|
8 |
+
* @subpackage JMS Plugin Framework
|
9 |
+
* @version 1.2
|
10 |
+
*/
|
11 |
+
if ( !class_exists( 'JmsPluginUserOptionsCollection' ) ){
|
12 |
+
class JmsUserOptionsCollection {
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @var string
|
16 |
+
*/
|
17 |
+
protected $optionsGroup = 'jms-framework-options';
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @var string
|
21 |
+
*/
|
22 |
+
protected $optionsKey = 'jms-framework';
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @var array
|
26 |
+
*/
|
27 |
+
protected $optionMap = array();
|
28 |
+
|
29 |
+
/**
|
30 |
+
* get options group
|
31 |
+
*
|
32 |
+
* @return string
|
33 |
+
*/
|
34 |
+
public function optionsGroup(){
|
35 |
+
|
36 |
+
return $this->optionsGroup;
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* get options key
|
41 |
+
*
|
42 |
+
* @return string
|
43 |
+
*/
|
44 |
+
public function optionsKey(){
|
45 |
+
|
46 |
+
return $this->optionsKey;
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* get option from array of options
|
51 |
+
*
|
52 |
+
* @param string $key
|
53 |
+
* @return string
|
54 |
+
*/
|
55 |
+
public function getOption( $key ) {
|
56 |
+
|
57 |
+
$options = get_option( $this->optionsKey, array() );
|
58 |
+
$value = isset( $options[$key] ) ? $options[$key] : '';
|
59 |
+
|
60 |
+
return $value;
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* add/update option value
|
65 |
+
*
|
66 |
+
* @param string $key
|
67 |
+
* @param mixed $val
|
68 |
+
* @return bool
|
69 |
+
*/
|
70 |
+
public function updateOption( $key, $val ) {
|
71 |
+
|
72 |
+
$options = get_option( $this->optionsKey, array() );
|
73 |
+
$options[$key] = $val;
|
74 |
+
|
75 |
+
return update_option( $this->optionsKey, $options );
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* option set yet?
|
80 |
+
*
|
81 |
+
* @param string $key
|
82 |
+
* @return boolean
|
83 |
+
*/
|
84 |
+
public function hasOption( $key ){
|
85 |
+
|
86 |
+
$options = get_option( $this->optionsKey, array() );
|
87 |
+
|
88 |
+
return isset( $options[$key] );
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* options collection set yet?
|
93 |
+
*
|
94 |
+
* @return boolean
|
95 |
+
*/
|
96 |
+
public function hasOptionCollection(){
|
97 |
+
|
98 |
+
$options = get_option( $this->optionsKey, array() );
|
99 |
+
|
100 |
+
return !empty( $options );
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* get section map
|
105 |
+
*
|
106 |
+
* @param string $sectionKey
|
107 |
+
* @return array
|
108 |
+
*/
|
109 |
+
public function sectionMap( $sectionKey ) {
|
110 |
+
|
111 |
+
$map = $this->optionMap();
|
112 |
+
|
113 |
+
return isset( $map[$sectionKey] ) ? $map[$sectionKey] : array();
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* get section option setting
|
118 |
+
*
|
119 |
+
* @param string $sectionKey
|
120 |
+
* @param string $optionKey
|
121 |
+
* @return null
|
122 |
+
*/
|
123 |
+
public function sectionOption( $sectionKey, $optionKey ) {
|
124 |
+
|
125 |
+
$map = $this->sectionMap( $sectionKey );
|
126 |
+
|
127 |
+
if ( isset( $map[$optionKey] ) ) {
|
128 |
+
return $map[$optionKey];
|
129 |
+
} else {
|
130 |
+
return NULL;
|
131 |
+
}
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* get all fields
|
136 |
+
*
|
137 |
+
* @return array
|
138 |
+
*/
|
139 |
+
public function fields() {
|
140 |
+
|
141 |
+
$map = $this->optionMap();
|
142 |
+
$fields = array();
|
143 |
+
|
144 |
+
foreach ( $map as $sectionKey => $sectionDetails ) {
|
145 |
+
|
146 |
+
if ( isset( $sectionDetails['fields'] ) ) {
|
147 |
+
foreach ( $sectionDetails['fields'] as $fieldKey => $fieldDetails ) {
|
148 |
+
|
149 |
+
$fields[$fieldKey] = isset( $fieldDetails['label'] ) ? $fieldDetails['label'] : $fieldKey;
|
150 |
+
}
|
151 |
+
}
|
152 |
+
}
|
153 |
+
|
154 |
+
return $fields;
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* get field map
|
159 |
+
*
|
160 |
+
* @param string $fieldKey
|
161 |
+
* @return array
|
162 |
+
*/
|
163 |
+
public function fieldMap( $fieldKey ) {
|
164 |
+
|
165 |
+
$map = $this->optionMap();
|
166 |
+
|
167 |
+
foreach ( $map as $sectionKey => $sectionDetails ) {
|
168 |
+
|
169 |
+
if ( isset( $sectionDetails['fields'][$fieldKey] ) ) {
|
170 |
+
return $sectionDetails['fields'][$fieldKey];
|
171 |
+
}
|
172 |
+
}
|
173 |
+
|
174 |
+
return array();
|
175 |
+
}
|
176 |
+
|
177 |
+
/**
|
178 |
+
* get field option setting
|
179 |
+
*
|
180 |
+
* @param string $fieldKey
|
181 |
+
* @param string $optionKey
|
182 |
+
* @return null
|
183 |
+
*/
|
184 |
+
public function fieldOption( $fieldKey, $optionKey ) {
|
185 |
+
|
186 |
+
$map = $this->fieldMap( $fieldKey );
|
187 |
+
|
188 |
+
if ( isset( $map[$optionKey] ) ) {
|
189 |
+
return $map[$optionKey];
|
190 |
+
} else {
|
191 |
+
return NULL;
|
192 |
+
}
|
193 |
+
}
|
194 |
+
|
195 |
+
/**
|
196 |
+
* get default options
|
197 |
+
*
|
198 |
+
* @return array
|
199 |
+
*/
|
200 |
+
public function defaultOptions() {
|
201 |
+
|
202 |
+
$defaults = array();
|
203 |
+
|
204 |
+
$fields = $this->fields();
|
205 |
+
foreach ( $fields as $fieldKey => $fieldLabel ) {
|
206 |
+
|
207 |
+
$defaults[$fieldKey] = $this->fieldOption( $fieldKey, 'default' );
|
208 |
+
}
|
209 |
+
|
210 |
+
return $defaults;
|
211 |
+
}
|
212 |
+
|
213 |
+
/**
|
214 |
+
* init plugin's options to default settings
|
215 |
+
*
|
216 |
+
* @return boolean
|
217 |
+
*/
|
218 |
+
function initDefaultOptions(){
|
219 |
+
|
220 |
+
$defaults = $this->defaultOptions();
|
221 |
+
return update_option( $this->optionsKey, $defaults );
|
222 |
+
}
|
223 |
+
|
224 |
+
/**
|
225 |
+
* options mapping
|
226 |
+
*
|
227 |
+
* @return array
|
228 |
+
*/
|
229 |
+
public function optionMap() {
|
230 |
+
|
231 |
+
return $this->optionMap;
|
232 |
+
}
|
233 |
+
}
|
234 |
+
}
|
framework/readme.md
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
v1.0 - Initial bootstrap class created, initial controller created
|
2 |
+
v1.1 - Updates to bootstrap, implement autoloading. Minor controller updates
|
3 |
+
v1.2 - Adds plugin name and text domain to bootstrap and controller. Minor controller updates. Adds basic plugin user options framework. Changes to parameters passed to bootstrap and controller, update all existing plugins.
|
model/SBTT_Options.php
ADDED
@@ -0,0 +1,261 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* SBTT Options class
|
4 |
+
*
|
5 |
+
* @author Joe Sexton <joe@josephmsexton.com>
|
6 |
+
* @package WordPress
|
7 |
+
* @subpackage scroll-back-to-top
|
8 |
+
*/
|
9 |
+
if ( !class_exists( 'SBTT_Options' ) ){
|
10 |
+
class SBTT_Options extends JmsUserOptionsCollection {
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @var string
|
14 |
+
*/
|
15 |
+
protected $optionsGroup = 'scroll-back-to-top-options';
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var string
|
19 |
+
*/
|
20 |
+
protected $optionsKey = 'scroll-back-to-top';
|
21 |
+
|
22 |
+
/**
|
23 |
+
* configure options mapping
|
24 |
+
*/
|
25 |
+
public function __construct() {
|
26 |
+
|
27 |
+
$this->optionMap['visibility'] = array(
|
28 |
+
'label' => __( 'Visibility', 'scroll-back-to-top' ),
|
29 |
+
'description' => __( 'Button visibility status options', 'scroll-back-to-top' ),
|
30 |
+
'fields' => array(
|
31 |
+
'enabled' => array(
|
32 |
+
'label' => __( 'Status', 'scroll-back-to-top' ),
|
33 |
+
'type' => 'radio',
|
34 |
+
'default' => 'public',
|
35 |
+
'data_type' => 'choice',
|
36 |
+
'choices' => array(
|
37 |
+
'public' => __( 'Publicly Visible', 'scroll-back-to-top' ),
|
38 |
+
'preview' => __( 'Preview Mode', 'scroll-back-to-top' ),
|
39 |
+
'disabled' => __( 'Disabled', 'scroll-back-to-top' ),
|
40 |
+
),
|
41 |
+
'required' => true,
|
42 |
+
),
|
43 |
+
),
|
44 |
+
);
|
45 |
+
$this->optionMap['appearance'] = array(
|
46 |
+
'label' => __( 'Button Appearance', 'scroll-back-to-top' ),
|
47 |
+
'description' => __( 'Change the look and feel of the scroll to top button', 'scroll-back-to-top' ),
|
48 |
+
'fields' => array(
|
49 |
+
'size_w' => array(
|
50 |
+
'label' => __( 'Width', 'scroll-back-to-top' ),
|
51 |
+
'type' => 'text',
|
52 |
+
'default' => 50,
|
53 |
+
'min' => 0,
|
54 |
+
'max' => 2000,
|
55 |
+
'units' => __( 'px', 'scroll-back-to-top' ),
|
56 |
+
'data_type' => 'integer',
|
57 |
+
'required' => true,
|
58 |
+
),
|
59 |
+
'size_h' => array(
|
60 |
+
'label' => __( 'Height', 'scroll-back-to-top' ),
|
61 |
+
'type' => 'text',
|
62 |
+
'default' => 50,
|
63 |
+
'min' => 0,
|
64 |
+
'max' => 2000,
|
65 |
+
'units' => __( 'px', 'scroll-back-to-top' ),
|
66 |
+
'data_type' => 'integer',
|
67 |
+
'required' => true,
|
68 |
+
),
|
69 |
+
'color_background' => array(
|
70 |
+
'label' => __( 'Background Color', 'scroll-back-to-top' ),
|
71 |
+
'type' => 'text',
|
72 |
+
'default' => '#777777',
|
73 |
+
'options' => 'color-picker',
|
74 |
+
'data_type' => 'string',
|
75 |
+
'required' => true,
|
76 |
+
),
|
77 |
+
'color_hover' => array(
|
78 |
+
'label' => __( 'Hover Color', 'scroll-back-to-top' ),
|
79 |
+
'type' => 'text',
|
80 |
+
'default' => '#888888',
|
81 |
+
'options' => 'color-picker',
|
82 |
+
'data_type' => 'string',
|
83 |
+
'required' => true,
|
84 |
+
),
|
85 |
+
'color_foreground' => array(
|
86 |
+
'label' => __( 'Foreground Color', 'scroll-back-to-top' ),
|
87 |
+
'type' => 'text',
|
88 |
+
'default' => '#eeeeee',
|
89 |
+
'options' => 'color-picker',
|
90 |
+
'data_type' => 'string',
|
91 |
+
'required' => true,
|
92 |
+
),
|
93 |
+
'opacity' => array(
|
94 |
+
'label' => __( 'Opacity', 'scroll-back-to-top' ),
|
95 |
+
'type' => 'text',
|
96 |
+
'default' => 100,
|
97 |
+
'min' => 0,
|
98 |
+
'max' => 100,
|
99 |
+
'units' => __( '%', 'scroll-back-to-top' ),
|
100 |
+
'data_type' => 'integer',
|
101 |
+
'required' => true,
|
102 |
+
),
|
103 |
+
'border_radius' => array(
|
104 |
+
'label' => __( 'Border Radius', 'scroll-back-to-top' ),
|
105 |
+
'type' => 'text',
|
106 |
+
'default' => 10,
|
107 |
+
'min' => 0,
|
108 |
+
'max' => 100,
|
109 |
+
'units' => __( 'px', 'scroll-back-to-top' ),
|
110 |
+
'data_type' => 'integer',
|
111 |
+
'required' => true,
|
112 |
+
),
|
113 |
+
),
|
114 |
+
);
|
115 |
+
$this->optionMap['location'] = array(
|
116 |
+
'label' => __( 'Button Location', 'scroll-back-to-top' ),
|
117 |
+
'description' => __( 'Change where the button is located on the page', 'scroll-back-to-top' ),
|
118 |
+
'fields' => array(
|
119 |
+
'align_x' => array(
|
120 |
+
'label' => __( 'Horizontal Alignment', 'scroll-back-to-top' ),
|
121 |
+
'type' => 'radio',
|
122 |
+
'default' => 'right',
|
123 |
+
'data_type' => 'choice',
|
124 |
+
'choices' => array(
|
125 |
+
'left' => __( 'Left', 'scroll-back-to-top' ),
|
126 |
+
'center' => __( 'Center', 'scroll-back-to-top' ),
|
127 |
+
'right' => __( 'Right', 'scroll-back-to-top' ),
|
128 |
+
),
|
129 |
+
'required' => true,
|
130 |
+
),
|
131 |
+
'align_y' => array(
|
132 |
+
'label' => __( 'Vertical Alignment', 'scroll-back-to-top' ),
|
133 |
+
'type' => 'radio',
|
134 |
+
'default' => 'bottom',
|
135 |
+
'data_type' => 'choice',
|
136 |
+
'choices' => array(
|
137 |
+
'top' => __( 'Top', 'scroll-back-to-top' ),
|
138 |
+
'bottom' => __( 'Bottom', 'scroll-back-to-top' ),
|
139 |
+
),
|
140 |
+
'required' => true,
|
141 |
+
),
|
142 |
+
'margin_x' => array(
|
143 |
+
'label' => __( 'Horizontal Distance from Edge', 'scroll-back-to-top' ),
|
144 |
+
'type' => 'text',
|
145 |
+
'default' => 30,
|
146 |
+
'min' => 0,
|
147 |
+
'max' => 2000,
|
148 |
+
'units' => __( 'px margin', 'scroll-back-to-top' ),
|
149 |
+
'data_type' => 'integer',
|
150 |
+
'required' => true,
|
151 |
+
),
|
152 |
+
'margin_y' => array(
|
153 |
+
'label' => __( 'Vertical Distance from Edge', 'scroll-back-to-top' ),
|
154 |
+
'type' => 'text',
|
155 |
+
'default' => 30,
|
156 |
+
'min' => 0,
|
157 |
+
'max' => 2000,
|
158 |
+
'units' => __( 'px margin', 'scroll-back-to-top' ),
|
159 |
+
'data_type' => 'integer',
|
160 |
+
'required' => true,
|
161 |
+
),
|
162 |
+
),
|
163 |
+
);
|
164 |
+
$this->optionMap['label'] = array(
|
165 |
+
'label' => __( 'Button Label', 'scroll-back-to-top' ),
|
166 |
+
'description' => __( 'Change what appears on the button', 'scroll-back-to-top' ),
|
167 |
+
'fields' => array(
|
168 |
+
'label_type' => array(
|
169 |
+
'label' => __( 'Label Type', 'scroll-back-to-top' ),
|
170 |
+
'type' => 'radio',
|
171 |
+
'default' => 'fa-arrow-circle-up',
|
172 |
+
'data_type' => 'choice',
|
173 |
+
'choices' => array(
|
174 |
+
'fa-angle-up' => '<i class="fa fa-angle-up fa-lg"></i>',
|
175 |
+
'fa-angle-double-up' => '<i class="fa fa-angle-double-up fa-lg"></i>',
|
176 |
+
'fa-arrow-up' => '<i class="fa fa-arrow-up fa-lg"></i>',
|
177 |
+
'fa-arrow-circle-o-up' => '<i class="fa fa-arrow-circle-o-up fa-lg"></i>',
|
178 |
+
'fa-arrow-circle-up' => '<i class="fa fa-arrow-circle-up fa-lg"></i>',
|
179 |
+
'fa-caret-up' => '<i class="fa fa-caret-up fa-lg"></i>',
|
180 |
+
'fa-caret-square-o-up' => '<i class="fa fa-caret-square-o-up fa-lg"></i>',
|
181 |
+
'fa-chevron-up' => '<i class="fa fa-chevron-up fa-lg"></i>',
|
182 |
+
'fa-chevron-circle-up' => '<i class="fa fa-chevron-circle-up fa-lg"></i>',
|
183 |
+
'fa-hand-o-up' => '<i class="fa fa-hand-o-up fa-lg"></i>',
|
184 |
+
'fa-long-arrow-up' => '<i class="fa fa-long-arrow-up fa-lg"></i>',
|
185 |
+
'text' => __( 'Custom Text', 'scroll-back-to-top' ),
|
186 |
+
),
|
187 |
+
'required' => true,
|
188 |
+
),
|
189 |
+
'icon_size' => array(
|
190 |
+
'label' => __( 'Icon Size', 'scroll-back-to-top' ),
|
191 |
+
'type' => 'radio',
|
192 |
+
'default' => 'fa-2x',
|
193 |
+
'data_type' => 'choice',
|
194 |
+
'choices' => array(
|
195 |
+
'fa-sm' => '1',
|
196 |
+
'fa-lg' => '2',
|
197 |
+
'fa-2x' => '3',
|
198 |
+
'fa-3x' => '4',
|
199 |
+
'fa-4x' => '5',
|
200 |
+
'fa-5x' => '6',
|
201 |
+
),
|
202 |
+
),
|
203 |
+
'label_text' => array(
|
204 |
+
'label' => __( 'Custom Label Text', 'scroll-back-to-top' ),
|
205 |
+
'type' => 'text',
|
206 |
+
'default' => '',
|
207 |
+
'data_type' => 'string',
|
208 |
+
),
|
209 |
+
'font_size' => array(
|
210 |
+
'label' => __( 'Font Size', 'scroll-back-to-top' ),
|
211 |
+
'type' => 'number',
|
212 |
+
'default' => 12,
|
213 |
+
'min' => 0,
|
214 |
+
'max' => 100,
|
215 |
+
'units' => __( 'px - Using 0px will auto-size text to fit the button', 'scroll-back-to-top' ),
|
216 |
+
'data_type' => 'integer',
|
217 |
+
),
|
218 |
+
),
|
219 |
+
);
|
220 |
+
$this->optionMap['behavior'] = array(
|
221 |
+
'label' => __( 'Animation Options', 'scroll-back-to-top' ),
|
222 |
+
'description' => __( 'Change animation options', 'scroll-back-to-top' ),
|
223 |
+
'fields' => array(
|
224 |
+
'scroll_duration' => array(
|
225 |
+
'label' => __( 'Scroll Duration', 'scroll-back-to-top' ),
|
226 |
+
'type' => 'text',
|
227 |
+
'default' => 500,
|
228 |
+
'min' => 0,
|
229 |
+
'max' => 5000,
|
230 |
+
'units' => __( 'ms', 'scroll-back-to-top' ),
|
231 |
+
'data_type' => 'integer',
|
232 |
+
'required' => true,
|
233 |
+
),
|
234 |
+
'fade_duration' => array(
|
235 |
+
'label' => __( 'Fade Duration', 'scroll-back-to-top' ),
|
236 |
+
'type' => 'text',
|
237 |
+
'default' => 500,
|
238 |
+
'min' => 0,
|
239 |
+
'max' => 5000,
|
240 |
+
'units' => __( 'ms', 'scroll-back-to-top' ),
|
241 |
+
'data_type' => 'integer',
|
242 |
+
'required' => true,
|
243 |
+
),
|
244 |
+
),
|
245 |
+
);
|
246 |
+
$this->optionMap['advanced'] = array(
|
247 |
+
'label' => __( 'Advanced Options', 'scroll-back-to-top' ),
|
248 |
+
'description' => __( 'Advanced options, this requires some knowledge of css to use.', 'scroll-back-to-top' ),
|
249 |
+
'fields' => array(
|
250 |
+
'extra_css' => array(
|
251 |
+
'label' => __( 'Extra CSS', 'scroll-back-to-top' ),
|
252 |
+
'type' => 'textarea',
|
253 |
+
'columns' => 50,
|
254 |
+
'rows' => 10,
|
255 |
+
'data_type' => 'string',
|
256 |
+
),
|
257 |
+
),
|
258 |
+
);
|
259 |
+
}
|
260 |
+
}
|
261 |
+
}
|
readme.txt
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
=== Scroll Back To Top ===
|
2 |
+
Contributors: joesexton00
|
3 |
+
Tags: back to top, jquery, scroll to top, button, scroll, scroll top, scroll back to top, scroll up, widget, icon, scroller, vertical scroller, arrow, link to top, back to top, smooth scroll, top, back
|
4 |
+
Requires at least: 3.0
|
5 |
+
Tested up to: 3.9
|
6 |
+
Stable tag: 1.0
|
7 |
+
|
8 |
+
This plugin will add a button that allows users to scroll smoothly to the top of the page.
|
9 |
+
|
10 |
+
== Description ==
|
11 |
+
|
12 |
+
Scroll Back to Top is a Wordpress plugin to add a button that appears only when users scroll down the page allowing them to scroll to the top of the page. The plugin comes pre-configured and is fully functional on activation. The plugin offers a number of webmaster-friendly features to completely customize the look, position, and animation. In addition, there is a setting to allow you to put the button in preview mode so it only appears when logged in, which is great for configuration, then fully enable it for everyone to see! This button is built on jQuery and is designed to be dead easy, without the need to modify any markup or the theme.
|
13 |
+
|
14 |
+
= Usage =
|
15 |
+
This was built for anyone to use, with no knowledge of HTML or CSS required!
|
16 |
+
|
17 |
+
* Install the plugin through the Plugins interface or by uploading the `scroll-back-to-top` directory to your `/wp-content/plugins/` directory.
|
18 |
+
* Activate the Scroll Back to Top plugin.
|
19 |
+
* You're done, the scroll back to top button should appear on all pages after you scroll down a little bit. If you'd like to customize the design you may continue.
|
20 |
+
|
21 |
+
Optional Customization Steps
|
22 |
+
|
23 |
+
* A new setting page will be located within Settings > Scroll Back to Top, navigate to that page to for customization options.
|
24 |
+
* Change enabled status, size, color, opacity, location, icon/text, or fades.
|
25 |
+
|
26 |
+
= More Support =
|
27 |
+
More support can be found at <a target="_blank" href="http://www.webtipblog.com/scroll-back-top-wordpress-plugin">our plugin support page</a>.
|
28 |
+
<br />
|
29 |
+
<br />This plugin is developed by <a target="_blank" href="http://www.josephmsexton.com">Joe Sexton</a>
|
30 |
+
|
31 |
+
== Installation ==
|
32 |
+
|
33 |
+
1. Install the plugin through the Plugins interface or by uploading the `scroll-back-to-top` directory to your `/wp-content/plugins/` directory.
|
34 |
+
2. Activate the Scroll Back to Top plugin.
|
35 |
+
3. You're done, the scroll back to top button should appear on all pages after you scroll down a little bit. If you'd like to customize the design you may continue.
|
36 |
+
|
37 |
+
Optional Customization Steps
|
38 |
+
|
39 |
+
* A new setting page will be located within Settings > Scroll Back to Top, navigate to that page to for customization options.
|
40 |
+
* Change enabled status, size, color, opacity, location, icon/text, or fades.
|
41 |
+
|
42 |
+
== Screenshots ==
|
43 |
+
|
44 |
+
1. This plugin offers a number of configuration options to easliy customize the look and feel of the scroll up button.
|
45 |
+
2. This is the default button that comes pre-configured with the plugin.
|
46 |
+
3. It is possible to add custom text, color, and change the position of the button.
|
47 |
+
4. It's also possible to make the button a circle.
|
48 |
+
5. Easily add icons or dock the button to the edge of the screen.
|
49 |
+
|
50 |
+
== Frequently Asked Questions ==
|
51 |
+
|
52 |
+
= Does this plugin require modification to the theme? =
|
53 |
+
|
54 |
+
Absolutely not. This plugin is added/configured entirely from the website's wp-admin section.
|
55 |
+
|
56 |
+
= Does this require any knowledge of HTML or CSS? =
|
57 |
+
|
58 |
+
Absolutely not. This plugin can be configured with no knowledge of HTML or CSS, using a simple Wordpress settings page.
|
59 |
+
|
60 |
+
= Do I need to configure this plugin? =
|
61 |
+
|
62 |
+
Absolutely not. This plugin is designed to work immediately upon activation, with a nicely designed scroll back to top button ready to go.
|
63 |
+
|
64 |
+
== Change Log ==
|
65 |
+
|
66 |
+
= 1.0 =
|
67 |
+
- Initial Release
|
68 |
+
|
69 |
+
== Upgrade Notice ==
|
70 |
+
|
71 |
+
Make sure you get the latest version.
|
72 |
+
|
73 |
+
== Localization ==
|
74 |
+
|
75 |
+
= Available in English =
|
76 |
+
|
77 |
+
Want to contribute with a translation to your language? Please contact me at joe@josephmsexton.com
|
scroll-back-to-top.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Plugin Name: Scroll Back to Top
|
4 |
+
Description: Adds a scroll to top button
|
5 |
+
Text Domain: scroll-back-to-top
|
6 |
+
Version: 1.0
|
7 |
+
Author: Joe Sexton
|
8 |
+
Author URI: http://www.josephmsexton.com
|
9 |
+
*/
|
10 |
+
|
11 |
+
require_once 'framework/JmsBootstrap.php';
|
12 |
+
$wpClassLoader = new JmsBootstrap( __FILE__, __( 'Scroll Back to Top', 'scroll-back-to-top') );
|
view/dynamic-styles.php
ADDED
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php $test = ''; ?>
|
2 |
+
<style>
|
3 |
+
.scroll-back-to-top-wrapper {
|
4 |
+
position: fixed;
|
5 |
+
opacity: 0;
|
6 |
+
visibility: hidden;
|
7 |
+
overflow: hidden;
|
8 |
+
text-align: center;
|
9 |
+
z-index: 99999999;
|
10 |
+
<?php if ( isset( $label_type ) && $label_type == 'text' && isset( $font_size ) && $font_size != '0px' ) : ?>
|
11 |
+
font-size: <?php echo $font_size; ?>;
|
12 |
+
<?php endif; ?>
|
13 |
+
<?php if ( isset( $color_background ) ) : ?>
|
14 |
+
background-color: <?php echo $color_background; ?>;
|
15 |
+
<?php endif; ?>
|
16 |
+
<?php if ( isset( $color_foreground ) ) : ?>
|
17 |
+
color: <?php echo $color_foreground; ?>;
|
18 |
+
<?php endif; ?>
|
19 |
+
<?php if ( isset( $size_w ) ) : ?>
|
20 |
+
width: <?php echo $size_w; ?>;
|
21 |
+
<?php endif; ?>
|
22 |
+
<?php if ( isset( $size_h ) ) : ?>
|
23 |
+
height: <?php echo $size_h; ?>;
|
24 |
+
line-height: <?php echo $size_h; ?>;
|
25 |
+
<?php endif; ?>
|
26 |
+
<?php if ( isset( $margin_top ) ) : ?>
|
27 |
+
margin-top: <?php echo $margin_top; ?>;
|
28 |
+
<?php endif; ?>
|
29 |
+
<?php if ( isset( $margin_right ) ) : ?>
|
30 |
+
margin-right: <?php echo $margin_right; ?>;
|
31 |
+
<?php endif; ?>
|
32 |
+
<?php if ( isset( $margin_bottom ) ) : ?>
|
33 |
+
margin-bottom: <?php echo $margin_bottom; ?>;
|
34 |
+
<?php endif; ?>
|
35 |
+
<?php if ( isset( $margin_left ) ) : ?>
|
36 |
+
margin-left: <?php echo $margin_left; ?>;
|
37 |
+
<?php endif; ?>
|
38 |
+
<?php if ( isset( $css_top ) ) : ?>
|
39 |
+
top: <?php echo $css_top; ?>;
|
40 |
+
<?php endif; ?>
|
41 |
+
<?php if ( isset( $css_right ) ) : ?>
|
42 |
+
right: <?php echo $css_right; ?>;
|
43 |
+
<?php endif; ?>
|
44 |
+
<?php if ( isset( $css_bottom ) ) : ?>
|
45 |
+
bottom: <?php echo $css_bottom; ?>;
|
46 |
+
<?php endif; ?>
|
47 |
+
<?php if ( isset( $css_left ) ) : ?>
|
48 |
+
left: <?php echo $css_left; ?>;
|
49 |
+
<?php endif; ?>
|
50 |
+
<?php if ( isset( $padding_top ) ) : ?>
|
51 |
+
padding-top: <?php echo $padding_top; ?>;
|
52 |
+
<?php endif; ?>
|
53 |
+
<?php if ( isset( $border_radius_top_left ) ) : ?>
|
54 |
+
border-top-left-radius: <?php echo $border_radius_top_left; ?>;
|
55 |
+
<?php endif; ?>
|
56 |
+
<?php if ( isset( $border_radius_top_right ) ) : ?>
|
57 |
+
border-top-right-radius: <?php echo $border_radius_top_right; ?>;
|
58 |
+
<?php endif; ?>
|
59 |
+
<?php if ( isset( $border_radius_bottom_right ) ) : ?>
|
60 |
+
border-bottom-right-radius: <?php echo $border_radius_bottom_right; ?>;
|
61 |
+
<?php endif; ?>
|
62 |
+
<?php if ( isset( $border_radius_bottom_left ) ) : ?>
|
63 |
+
border-bottom-left-radius: <?php echo $border_radius_bottom_left; ?>;
|
64 |
+
<?php endif; ?>
|
65 |
+
<?php if ( isset( $fade_duration ) ) : ?>
|
66 |
+
-webkit-transition: all <?php echo $fade_duration; ?>s ease-in-out;
|
67 |
+
-moz-transition: all <?php echo $fade_duration; ?>s ease-in-out;
|
68 |
+
-ms-transition: all <?php echo $fade_duration; ?>s ease-in-out;
|
69 |
+
-o-transition: all <?php echo $fade_duration; ?>s ease-in-out;
|
70 |
+
transition: all <?php echo $fade_duration; ?>s ease-in-out;
|
71 |
+
<?php endif; ?>
|
72 |
+
}
|
73 |
+
.scroll-back-to-top-wrapper:hover {
|
74 |
+
<?php if ( isset( $color_hover ) ) : ?>
|
75 |
+
background-color: <?php echo $color_hover; ?>;
|
76 |
+
<?php endif; ?>
|
77 |
+
}
|
78 |
+
.scroll-back-to-top-wrapper.show {
|
79 |
+
visibility:visible;
|
80 |
+
cursor:pointer;
|
81 |
+
<?php if ( isset( $opacity ) ) : ?>
|
82 |
+
opacity: <?php echo $opacity; ?>;
|
83 |
+
<?php endif; ?>
|
84 |
+
}
|
85 |
+
.scroll-back-to-top-wrapper i.fa {
|
86 |
+
line-height: inherit;
|
87 |
+
}
|
88 |
+
.scroll-back-to-top-wrapper .fa-lg {
|
89 |
+
vertical-align: 0;
|
90 |
+
}
|
91 |
+
<?php if ( isset( $extra_css ) ) : ?>
|
92 |
+
<?php echo $extra_css; ?>
|
93 |
+
<?php endif; ?>
|
94 |
+
</style>
|
view/framework/admin/partials/checkbox_input.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$plugin_option_name = isset( $plugin_option_name ) ? $plugin_option_name : '';
|
3 |
+
$field_key = isset( $field_key ) ? $field_key : '';
|
4 |
+
$field_label = isset( $field_label ) ? $field_label : '';
|
5 |
+
$option_value = isset( $option_value ) ? $option_value : '';
|
6 |
+
$extra_attributes = isset( $extra_attributes ) ? $extra_attributes : '';
|
7 |
+
?>
|
8 |
+
|
9 |
+
<label
|
10 |
+
for="<?php echo $plugin_option_name; ?>[<?php echo $field_key; ?>]"
|
11 |
+
style="margin-right:15px;"
|
12 |
+
>
|
13 |
+
<input
|
14 |
+
class="<?php echo $plugin_option_name; ?> <?php echo $field_key; ?>"
|
15 |
+
type="checkbox"
|
16 |
+
id="<?php echo $plugin_option_name; ?>[<?php echo $field_key; ?>]"
|
17 |
+
name="<?php echo $plugin_option_name; ?>[<?php echo $field_key; ?>]"
|
18 |
+
value="1"
|
19 |
+
<?php checked( $option_value, 1 ); ?>
|
20 |
+
<?php echo $extra_attributes; ?>
|
21 |
+
><?php echo $field_label; ?>
|
22 |
+
</label>
|
view/framework/admin/partials/radio_input.php
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$plugin_option_name = isset( $plugin_option_name ) ? $plugin_option_name : '';
|
3 |
+
$field_key = isset( $field_key ) ? $field_key : '';
|
4 |
+
$choice_key = isset( $choice_key ) ? $choice_key : '';
|
5 |
+
$choice_label = isset( $choice_label ) ? $choice_label : '';
|
6 |
+
$option_value = isset( $option_value ) ? $option_value : '';
|
7 |
+
$extra_attributes = isset( $extra_attributes ) ? $extra_attributes : '';
|
8 |
+
?>
|
9 |
+
|
10 |
+
<label
|
11 |
+
for="<?php echo $plugin_option_name; ?>[<?php echo $field_key; ?>].<?php echo $choice_key; ?>"
|
12 |
+
style="margin-right:15px;"
|
13 |
+
>
|
14 |
+
<input
|
15 |
+
class="<?php echo $plugin_option_name; ?> <?php echo $field_key; ?>"
|
16 |
+
type="radio"
|
17 |
+
id="<?php echo $plugin_option_name; ?>[<?php echo $field_key; ?>].<?php echo $choice_key; ?>"
|
18 |
+
name="<?php echo $plugin_option_name; ?>[<?php echo $field_key; ?>]"
|
19 |
+
value="<?php echo $choice_key; ?>"
|
20 |
+
<?php checked( $option_value, $choice_key ); ?>
|
21 |
+
<?php echo $extra_attributes; ?>
|
22 |
+
><?php echo $choice_label; ?>
|
23 |
+
</label>
|
view/framework/admin/partials/required_indicator.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<span class="input-required">*</span>
|
view/framework/admin/partials/text_input.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$plugin_option_name = isset( $plugin_option_name ) ? $plugin_option_name : '';
|
3 |
+
$field_key = isset( $field_key ) ? $field_key : '';
|
4 |
+
$option_value = isset( $option_value ) ? $option_value : '';
|
5 |
+
$input_type = isset( $input_type ) ? $input_type : '';
|
6 |
+
$extra_attributes = isset( $extra_attributes ) ? $extra_attributes : '';
|
7 |
+
$units = isset( $units ) ? $units : '';
|
8 |
+
$options = isset( $options ) ? $options : '';
|
9 |
+
?>
|
10 |
+
|
11 |
+
<input
|
12 |
+
class="<?php echo $plugin_option_name; ?> <?php echo $field_key; ?>"
|
13 |
+
type="<?php echo $input_type != '' ? $input_type : 'text'; ?>"
|
14 |
+
id="<?php echo $plugin_option_name; ?>[<?php echo $field_key; ?>]"
|
15 |
+
name="<?php echo $plugin_option_name; ?>[<?php echo $field_key; ?>]"
|
16 |
+
value="<?php echo $option_value; ?>"
|
17 |
+
<?php echo $extra_attributes; ?>
|
18 |
+
><small class="units"><?php echo $units; ?></small>
|
19 |
+
|
20 |
+
<?php if ( $options == 'color-picker' ) : ?>
|
21 |
+
<script> jQuery(document).ready(function($){ $('.<?php echo $field_key; ?>').wpColorPicker(); }); </script>
|
22 |
+
<?php endif; ?>
|
view/framework/admin/partials/textarea_input.php
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$plugin_option_name = isset( $plugin_option_name ) ? $plugin_option_name : '';
|
3 |
+
$field_key = isset( $field_key ) ? $field_key : '';
|
4 |
+
$option_value = isset( $option_value ) ? $option_value : '';
|
5 |
+
$extra_attributes = isset( $extra_attributes ) ? $extra_attributes : '';
|
6 |
+
?>
|
7 |
+
|
8 |
+
<textarea
|
9 |
+
class="<?php echo $plugin_option_name; ?> <?php echo $field_key; ?>"
|
10 |
+
id="<?php echo $plugin_option_name; ?>[<?php echo $field_key; ?>]"
|
11 |
+
name="<?php echo $plugin_option_name; ?>[<?php echo $field_key; ?>]"
|
12 |
+
<?php echo $extra_attributes; ?>
|
13 |
+
><?php echo $option_value; ?></textarea>
|
view/framework/admin/settings.php
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Admin Settings Page
|
4 |
+
*
|
5 |
+
* @author Joe Sexton <joe@josephmsexton.com>
|
6 |
+
* @package WordPress
|
7 |
+
* @subpackage JMS Plugin Framework
|
8 |
+
* @version 1.2
|
9 |
+
*/
|
10 |
+
?>
|
11 |
+
|
12 |
+
<style type="text/css">
|
13 |
+
input:disabled { background:rgba(255, 13, 13, 0.23); }
|
14 |
+
</style>
|
15 |
+
|
16 |
+
<div class="wrap">
|
17 |
+
|
18 |
+
<?php screen_icon( 'plugins' ); ?>
|
19 |
+
<h2><?php echo esc_html( get_admin_page_title() ); ?></h2>
|
20 |
+
|
21 |
+
<?php if ( isset( $option_group ) && isset( $settings_page_slug ) && isset( $option_key ) ) : ?>
|
22 |
+
<form action="options.php" method="post" id="sbtt_options_form">
|
23 |
+
<?php settings_fields( $option_group ); ?>
|
24 |
+
<?php do_settings_sections( $settings_page_slug ); ?>
|
25 |
+
<div>
|
26 |
+
<?php submit_button( null, 'primary', 'submit', false ); ?>
|
27 |
+
<?php submit_button( 'Resore Default Settings', 'secondary', $option_key . '[restore]', false ); ?>
|
28 |
+
|
29 |
+
</div>
|
30 |
+
</form>
|
31 |
+
|
32 |
+
<script>
|
33 |
+
jQuery(document).ready(function($){
|
34 |
+
$('[name="<?php echo $option_key . '[restore]'; ?>"]').on('click', function(e){
|
35 |
+
if(!confirm("<?php _e('Are you sure you want to restore defualt settings? This will erase all current settings', 'scroll-back-to-top' ); ?>")) {
|
36 |
+
e.preventDefault();
|
37 |
+
}
|
38 |
+
});
|
39 |
+
});
|
40 |
+
</script>
|
41 |
+
|
42 |
+
<?php endif; ?>
|
43 |
+
</div>
|
44 |
+
|
45 |
+
|
view/scroll-button.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="scroll-back-to-top-wrapper">
|
2 |
+
<span class="scroll-back-to-top-inner">
|
3 |
+
<?php if ( isset( $label_type ) && $label_type == 'text' && isset( $label_text ) ) : ?>
|
4 |
+
<?php echo $label_text; ?>
|
5 |
+
<?php elseif( isset( $label_type ) && isset( $icon_size )) : ?>
|
6 |
+
<i class="fa <?php echo $icon_size; ?> <?php echo $label_type; ?>"></i>
|
7 |
+
<?php endif; ?>
|
8 |
+
</span>
|
9 |
+
</div>
|