Ned Zimmerman
7 years ago
18 changed files with 4327 additions and 0 deletions
@ -0,0 +1,65 @@ |
|||||||
|
module.exports = function( grunt ) { |
||||||
|
'use strict'; |
||||||
|
|
||||||
|
grunt.initConfig({ |
||||||
|
|
||||||
|
// Setting folder templates.
|
||||||
|
dirs: { |
||||||
|
css: 'scss' |
||||||
|
}, |
||||||
|
|
||||||
|
// Compile all .scss files.
|
||||||
|
sass: { |
||||||
|
compile: { |
||||||
|
options: { |
||||||
|
sourcemap: 'none', |
||||||
|
loadPath: require( 'node-bourbon' ).includePaths |
||||||
|
}, |
||||||
|
files: [{ |
||||||
|
expand: true, |
||||||
|
cwd: '<%= dirs.css %>/', |
||||||
|
src: ['*.scss'], |
||||||
|
dest: './', |
||||||
|
ext: '.css' |
||||||
|
}] |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
// Minify all .css files.
|
||||||
|
cssmin: { |
||||||
|
minify: { |
||||||
|
expand: true, |
||||||
|
cwd: './', |
||||||
|
src: [ |
||||||
|
'*.css', |
||||||
|
'!*.min.css' |
||||||
|
], |
||||||
|
dest: './', |
||||||
|
ext: '.min.css' |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
// Watch changes for assets.
|
||||||
|
watch: { |
||||||
|
css: { |
||||||
|
files: ['<%= dirs.css %>/*.scss'], |
||||||
|
tasks: ['sass', 'cssmin'] |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
// Load NPM tasks to be used here
|
||||||
|
grunt.loadNpmTasks( 'grunt-contrib-sass' ); |
||||||
|
grunt.loadNpmTasks( 'grunt-contrib-cssmin' ); |
||||||
|
grunt.loadNpmTasks( 'grunt-contrib-watch' ); |
||||||
|
|
||||||
|
// Register tasks
|
||||||
|
grunt.registerTask( 'default', [ |
||||||
|
'css' |
||||||
|
]); |
||||||
|
|
||||||
|
grunt.registerTask( 'css', [ |
||||||
|
'sass', |
||||||
|
'cssmin' |
||||||
|
]); |
||||||
|
}; |
@ -0,0 +1,339 @@ |
|||||||
|
GNU GENERAL PUBLIC LICENSE |
||||||
|
Version 2, June 1991 |
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/> |
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||||
|
Everyone is permitted to copy and distribute verbatim copies |
||||||
|
of this license document, but changing it is not allowed. |
||||||
|
|
||||||
|
Preamble |
||||||
|
|
||||||
|
The licenses for most software are designed to take away your |
||||||
|
freedom to share and change it. By contrast, the GNU General Public |
||||||
|
License is intended to guarantee your freedom to share and change free |
||||||
|
software--to make sure the software is free for all its users. This |
||||||
|
General Public License applies to most of the Free Software |
||||||
|
Foundation's software and to any other program whose authors commit to |
||||||
|
using it. (Some other Free Software Foundation software is covered by |
||||||
|
the GNU Lesser General Public License instead.) You can apply it to |
||||||
|
your programs, too. |
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not |
||||||
|
price. Our General Public Licenses are designed to make sure that you |
||||||
|
have the freedom to distribute copies of free software (and charge for |
||||||
|
this service if you wish), that you receive source code or can get it |
||||||
|
if you want it, that you can change the software or use pieces of it |
||||||
|
in new free programs; and that you know you can do these things. |
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid |
||||||
|
anyone to deny you these rights or to ask you to surrender the rights. |
||||||
|
These restrictions translate to certain responsibilities for you if you |
||||||
|
distribute copies of the software, or if you modify it. |
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether |
||||||
|
gratis or for a fee, you must give the recipients all the rights that |
||||||
|
you have. You must make sure that they, too, receive or can get the |
||||||
|
source code. And you must show them these terms so they know their |
||||||
|
rights. |
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and |
||||||
|
(2) offer you this license which gives you legal permission to copy, |
||||||
|
distribute and/or modify the software. |
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain |
||||||
|
that everyone understands that there is no warranty for this free |
||||||
|
software. If the software is modified by someone else and passed on, we |
||||||
|
want its recipients to know that what they have is not the original, so |
||||||
|
that any problems introduced by others will not reflect on the original |
||||||
|
authors' reputations. |
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software |
||||||
|
patents. We wish to avoid the danger that redistributors of a free |
||||||
|
program will individually obtain patent licenses, in effect making the |
||||||
|
program proprietary. To prevent this, we have made it clear that any |
||||||
|
patent must be licensed for everyone's free use or not licensed at all. |
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and |
||||||
|
modification follow. |
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE |
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains |
||||||
|
a notice placed by the copyright holder saying it may be distributed |
||||||
|
under the terms of this General Public License. The "Program", below, |
||||||
|
refers to any such program or work, and a "work based on the Program" |
||||||
|
means either the Program or any derivative work under copyright law: |
||||||
|
that is to say, a work containing the Program or a portion of it, |
||||||
|
either verbatim or with modifications and/or translated into another |
||||||
|
language. (Hereinafter, translation is included without limitation in |
||||||
|
the term "modification".) Each licensee is addressed as "you". |
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not |
||||||
|
covered by this License; they are outside its scope. The act of |
||||||
|
running the Program is not restricted, and the output from the Program |
||||||
|
is covered only if its contents constitute a work based on the |
||||||
|
Program (independent of having been made by running the Program). |
||||||
|
Whether that is true depends on what the Program does. |
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's |
||||||
|
source code as you receive it, in any medium, provided that you |
||||||
|
conspicuously and appropriately publish on each copy an appropriate |
||||||
|
copyright notice and disclaimer of warranty; keep intact all the |
||||||
|
notices that refer to this License and to the absence of any warranty; |
||||||
|
and give any other recipients of the Program a copy of this License |
||||||
|
along with the Program. |
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and |
||||||
|
you may at your option offer warranty protection in exchange for a fee. |
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion |
||||||
|
of it, thus forming a work based on the Program, and copy and |
||||||
|
distribute such modifications or work under the terms of Section 1 |
||||||
|
above, provided that you also meet all of these conditions: |
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices |
||||||
|
stating that you changed the files and the date of any change. |
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in |
||||||
|
whole or in part contains or is derived from the Program or any |
||||||
|
part thereof, to be licensed as a whole at no charge to all third |
||||||
|
parties under the terms of this License. |
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively |
||||||
|
when run, you must cause it, when started running for such |
||||||
|
interactive use in the most ordinary way, to print or display an |
||||||
|
announcement including an appropriate copyright notice and a |
||||||
|
notice that there is no warranty (or else, saying that you provide |
||||||
|
a warranty) and that users may redistribute the program under |
||||||
|
these conditions, and telling the user how to view a copy of this |
||||||
|
License. (Exception: if the Program itself is interactive but |
||||||
|
does not normally print such an announcement, your work based on |
||||||
|
the Program is not required to print an announcement.) |
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If |
||||||
|
identifiable sections of that work are not derived from the Program, |
||||||
|
and can be reasonably considered independent and separate works in |
||||||
|
themselves, then this License, and its terms, do not apply to those |
||||||
|
sections when you distribute them as separate works. But when you |
||||||
|
distribute the same sections as part of a whole which is a work based |
||||||
|
on the Program, the distribution of the whole must be on the terms of |
||||||
|
this License, whose permissions for other licensees extend to the |
||||||
|
entire whole, and thus to each and every part regardless of who wrote it. |
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest |
||||||
|
your rights to work written entirely by you; rather, the intent is to |
||||||
|
exercise the right to control the distribution of derivative or |
||||||
|
collective works based on the Program. |
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program |
||||||
|
with the Program (or with a work based on the Program) on a volume of |
||||||
|
a storage or distribution medium does not bring the other work under |
||||||
|
the scope of this License. |
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it, |
||||||
|
under Section 2) in object code or executable form under the terms of |
||||||
|
Sections 1 and 2 above provided that you also do one of the following: |
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable |
||||||
|
source code, which must be distributed under the terms of Sections |
||||||
|
1 and 2 above on a medium customarily used for software interchange; or, |
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three |
||||||
|
years, to give any third party, for a charge no more than your |
||||||
|
cost of physically performing source distribution, a complete |
||||||
|
machine-readable copy of the corresponding source code, to be |
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium |
||||||
|
customarily used for software interchange; or, |
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer |
||||||
|
to distribute corresponding source code. (This alternative is |
||||||
|
allowed only for noncommercial distribution and only if you |
||||||
|
received the program in object code or executable form with such |
||||||
|
an offer, in accord with Subsection b above.) |
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for |
||||||
|
making modifications to it. For an executable work, complete source |
||||||
|
code means all the source code for all modules it contains, plus any |
||||||
|
associated interface definition files, plus the scripts used to |
||||||
|
control compilation and installation of the executable. However, as a |
||||||
|
special exception, the source code distributed need not include |
||||||
|
anything that is normally distributed (in either source or binary |
||||||
|
form) with the major components (compiler, kernel, and so on) of the |
||||||
|
operating system on which the executable runs, unless that component |
||||||
|
itself accompanies the executable. |
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering |
||||||
|
access to copy from a designated place, then offering equivalent |
||||||
|
access to copy the source code from the same place counts as |
||||||
|
distribution of the source code, even though third parties are not |
||||||
|
compelled to copy the source along with the object code. |
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program |
||||||
|
except as expressly provided under this License. Any attempt |
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is |
||||||
|
void, and will automatically terminate your rights under this License. |
||||||
|
However, parties who have received copies, or rights, from you under |
||||||
|
this License will not have their licenses terminated so long as such |
||||||
|
parties remain in full compliance. |
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not |
||||||
|
signed it. However, nothing else grants you permission to modify or |
||||||
|
distribute the Program or its derivative works. These actions are |
||||||
|
prohibited by law if you do not accept this License. Therefore, by |
||||||
|
modifying or distributing the Program (or any work based on the |
||||||
|
Program), you indicate your acceptance of this License to do so, and |
||||||
|
all its terms and conditions for copying, distributing or modifying |
||||||
|
the Program or works based on it. |
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the |
||||||
|
Program), the recipient automatically receives a license from the |
||||||
|
original licensor to copy, distribute or modify the Program subject to |
||||||
|
these terms and conditions. You may not impose any further |
||||||
|
restrictions on the recipients' exercise of the rights granted herein. |
||||||
|
You are not responsible for enforcing compliance by third parties to |
||||||
|
this License. |
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent |
||||||
|
infringement or for any other reason (not limited to patent issues), |
||||||
|
conditions are imposed on you (whether by court order, agreement or |
||||||
|
otherwise) that contradict the conditions of this License, they do not |
||||||
|
excuse you from the conditions of this License. If you cannot |
||||||
|
distribute so as to satisfy simultaneously your obligations under this |
||||||
|
License and any other pertinent obligations, then as a consequence you |
||||||
|
may not distribute the Program at all. For example, if a patent |
||||||
|
license would not permit royalty-free redistribution of the Program by |
||||||
|
all those who receive copies directly or indirectly through you, then |
||||||
|
the only way you could satisfy both it and this License would be to |
||||||
|
refrain entirely from distribution of the Program. |
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under |
||||||
|
any particular circumstance, the balance of the section is intended to |
||||||
|
apply and the section as a whole is intended to apply in other |
||||||
|
circumstances. |
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any |
||||||
|
patents or other property right claims or to contest validity of any |
||||||
|
such claims; this section has the sole purpose of protecting the |
||||||
|
integrity of the free software distribution system, which is |
||||||
|
implemented by public license practices. Many people have made |
||||||
|
generous contributions to the wide range of software distributed |
||||||
|
through that system in reliance on consistent application of that |
||||||
|
system; it is up to the author/donor to decide if he or she is willing |
||||||
|
to distribute software through any other system and a licensee cannot |
||||||
|
impose that choice. |
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to |
||||||
|
be a consequence of the rest of this License. |
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in |
||||||
|
certain countries either by patents or by copyrighted interfaces, the |
||||||
|
original copyright holder who places the Program under this License |
||||||
|
may add an explicit geographical distribution limitation excluding |
||||||
|
those countries, so that distribution is permitted only in or among |
||||||
|
countries not thus excluded. In such case, this License incorporates |
||||||
|
the limitation as if written in the body of this License. |
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions |
||||||
|
of the General Public License from time to time. Such new versions will |
||||||
|
be similar in spirit to the present version, but may differ in detail to |
||||||
|
address new problems or concerns. |
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program |
||||||
|
specifies a version number of this License which applies to it and "any |
||||||
|
later version", you have the option of following the terms and conditions |
||||||
|
either of that version or of any later version published by the Free |
||||||
|
Software Foundation. If the Program does not specify a version number of |
||||||
|
this License, you may choose any version ever published by the Free Software |
||||||
|
Foundation. |
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free |
||||||
|
programs whose distribution conditions are different, write to the author |
||||||
|
to ask for permission. For software which is copyrighted by the Free |
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes |
||||||
|
make exceptions for this. Our decision will be guided by the two goals |
||||||
|
of preserving the free status of all derivatives of our free software and |
||||||
|
of promoting the sharing and reuse of software generally. |
||||||
|
|
||||||
|
NO WARRANTY |
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED |
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS |
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE |
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, |
||||||
|
REPAIR OR CORRECTION. |
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, |
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING |
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED |
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY |
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER |
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE |
||||||
|
POSSIBILITY OF SUCH DAMAGES. |
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS |
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs |
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest |
||||||
|
possible use to the public, the best way to achieve this is to make it |
||||||
|
free software which everyone can redistribute and change under these terms. |
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest |
||||||
|
to attach them to the start of each source file to most effectively |
||||||
|
convey the exclusion of warranty; and each file should have at least |
||||||
|
the "copyright" line and a pointer to where the full notice is found. |
||||||
|
|
||||||
|
{description} |
||||||
|
Copyright (C) {year} {fullname} |
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify |
||||||
|
it under the terms of the GNU General Public License as published by |
||||||
|
the Free Software Foundation; either version 2 of the License, or |
||||||
|
(at your option) any later version. |
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, |
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
GNU General Public License for more details. |
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along |
||||||
|
with this program; if not, write to the Free Software Foundation, Inc., |
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail. |
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this |
||||||
|
when it starts in an interactive mode: |
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author |
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
||||||
|
This is free software, and you are welcome to redistribute it |
||||||
|
under certain conditions; type `show c' for details. |
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate |
||||||
|
parts of the General Public License. Of course, the commands you use may |
||||||
|
be called something other than `show w' and `show c'; they could even be |
||||||
|
mouse-clicks or menu items--whatever suits your program. |
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your |
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if |
||||||
|
necessary. Here is a sample; alter the names: |
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program |
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker. |
||||||
|
|
||||||
|
{signature of Ty Coon}, 1 April 1989 |
||||||
|
Ty Coon, President of Vice |
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into |
||||||
|
proprietary programs. If your program is a subroutine library, you may |
||||||
|
consider it more useful to permit linking proprietary applications with the |
||||||
|
library. If this is what you want to do, use the GNU Lesser General |
||||||
|
Public License instead of this License. |
@ -0,0 +1,69 @@ |
|||||||
|
# Who? |
||||||
|
_huh_ was dreamt up by [secret pizza party](https://secretpizza.party) and brought to life by the amazing [Dan Hauk](https://danhauk.com/). Seriously, Dan is the best. He took a broad idea and really brought it to life like only he could. The SPP offices are open on Christmas Day but we close on May 5th (Dan's birthday) as it's a company wide holiday. |
||||||
|
|
||||||
|
# What? |
||||||
|
_huh_ is the best way to offer in dashboard documentation for all your WordPress projects. The content is generated from a markdown file which makes it super quick & easy to update your documentation whenever you want. You can learn more from the launch post [here](https://secretpizza.party/huh-making-documentation-easier/). |
||||||
|
|
||||||
|
# Where? |
||||||
|
We think _huh_ is awesome and we really want you to use it in all your projects. It's totally free/open source and you can find it on [github](https://github.com/secretpizzaparty/huh/). |
||||||
|
|
||||||
|
## Wanna Contribute? |
||||||
|
If you found a bug, [report it here](https://github.com/secretpizzaparty/huh/issues/new). If you're a developer, we welcome pull requests of all types! |
||||||
|
|
||||||
|
### Development Workflow |
||||||
|
1. Make sure you have `git`, `node`, and `npm` installed and a working WordPress installation. |
||||||
|
2. Clone this repository inside your theme directory. |
||||||
|
|
||||||
|
``` |
||||||
|
$ git clone https://github.com/secretpizzaparty/huh.git |
||||||
|
$ cd huh |
||||||
|
``` |
||||||
|
|
||||||
|
3. Watch the front-end CSS/Sass for changes and rebuild accordingly with [Grunt](https://github.com/gruntjs/grunt). Please only modify the Sass files to keep the CSS consistent and clean. |
||||||
|
|
||||||
|
``` |
||||||
|
$ npm install |
||||||
|
$ grunt watch |
||||||
|
``` |
||||||
|
|
||||||
|
4. Open `/wp-admin/` in your browser. |
||||||
|
5. Have fun! |
||||||
|
|
||||||
|
|
||||||
|
# Why? |
||||||
|
[secret pizza party](https://secretpizza.party) is in the process of developing a bunch of new WordPress themes and while they are quite simple there is still a need for a wee bit of documentation. External documentation is dumb and everything should be contained in the dashboard. We created _huh_ to make that happen. |
||||||
|
|
||||||
|
# How? |
||||||
|
Adding _huh_ to your theme is incredibly easy. |
||||||
|
|
||||||
|
## Formatting your markdown |
||||||
|
_huh_ pulls all of your `<h1>` tags to use as a table of contents. Each section of your documentation will be contained between these `<h1>` tags. For example: |
||||||
|
|
||||||
|
``` |
||||||
|
# First section |
||||||
|
The content of the first section of your documentation would go here. You can include links, bullets, images, anything! |
||||||
|
|
||||||
|
# Second section |
||||||
|
This would be the next section. |
||||||
|
|
||||||
|
## You can even use subheadings |
||||||
|
It will all be formatted correctly, but only the first-level headings will show on the table of contents. |
||||||
|
``` |
||||||
|
|
||||||
|
## Adding _huh_ to your theme |
||||||
|
Once you have your documentation formatted correctly, adding _huh_ to your theme is simple. |
||||||
|
|
||||||
|
Just download the zipped plugin and extract it to your theme directory. At the bottom of your theme's `functions.php` file add the following lines: |
||||||
|
|
||||||
|
``` php |
||||||
|
require get_stylesheet_directory() . '/huh/huh.php'; |
||||||
|
function secretpizzaparty_huh() { |
||||||
|
// Enter the URL of your markdown file below |
||||||
|
$markdown_url = 'https://raw.githubusercontent.com/secretpizzaparty/huh/master/README.md'; |
||||||
|
$huh = new WP_Huh(); |
||||||
|
$huh->init( $markdown_url ); |
||||||
|
} |
||||||
|
add_action( 'admin_init', 'secretpizzaparty_huh' ); |
||||||
|
``` |
||||||
|
|
||||||
|
Make sure you change the URL of the `$markdown_url` variable to point to your markdown file. It's that easy! |
@ -0,0 +1,262 @@ |
|||||||
|
@keyframes popIn { |
||||||
|
0% { |
||||||
|
opacity: 0; |
||||||
|
transform: scale(0); } |
||||||
|
55% { |
||||||
|
opacity: 0; |
||||||
|
transform: scale(0); } |
||||||
|
75% { |
||||||
|
opacity: 1; |
||||||
|
transform: scale(1.1); } |
||||||
|
90% { |
||||||
|
opacity: 1; |
||||||
|
transform: scale(0.9); } |
||||||
|
100% { |
||||||
|
opacity: 1; |
||||||
|
transform: scale(1); } } |
||||||
|
@keyframes sonarEffect { |
||||||
|
0% { |
||||||
|
opacity: 1; } |
||||||
|
40% { |
||||||
|
opacity: 0.5; |
||||||
|
box-shadow: 0 0 4px 2px rgba(0, 0, 0, 0.2); } |
||||||
|
100% { |
||||||
|
box-shadow: 0 0 4px 2px rgba(0, 0, 0, 0.2); |
||||||
|
transform: scale(1.5); |
||||||
|
opacity: 0; } } |
||||||
|
@keyframes fadeIn { |
||||||
|
0% { |
||||||
|
opacity: 0; |
||||||
|
transform: translateY(20px); } |
||||||
|
100% { |
||||||
|
opacity: 1; |
||||||
|
transform: translateY(0); } } |
||||||
|
.huh-launcher { |
||||||
|
animation: popIn 0.8s ease-in-out; |
||||||
|
bottom: 30px; |
||||||
|
position: fixed; |
||||||
|
right: 20px; |
||||||
|
z-index: 500001; } |
||||||
|
|
||||||
|
.huh-launcher--button { |
||||||
|
-webkit-appearance: none; |
||||||
|
background: #009688; |
||||||
|
border: none; |
||||||
|
border-radius: 50px; |
||||||
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); |
||||||
|
box-sizing: border-box; |
||||||
|
cursor: pointer; |
||||||
|
height: 50px; |
||||||
|
padding: 0; |
||||||
|
position: relative; |
||||||
|
transition: transform ease-out 0.1s; |
||||||
|
width: 50px; |
||||||
|
z-index: 1; } |
||||||
|
.huh-launcher--button svg { |
||||||
|
fill: #fff; |
||||||
|
float: right; |
||||||
|
height: 50px; |
||||||
|
left: 0; |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
transition: transform 0.2s; |
||||||
|
width: 50px; } |
||||||
|
.huh-launcher--button .huh-launcher--icon-close { |
||||||
|
height: 30px; |
||||||
|
opacity: 0; |
||||||
|
padding: 10px; |
||||||
|
transform: scale(0.2); |
||||||
|
width: 30px; } |
||||||
|
.huh-launcher--button.active .huh-launcher--icon-enable { |
||||||
|
opacity: 0; |
||||||
|
transform: scale(0.2); } |
||||||
|
.huh-launcher--button.active .huh-launcher--icon-close { |
||||||
|
opacity: 1; |
||||||
|
transform: scale(1); } |
||||||
|
.huh-launcher--button::after, .huh-launcher--button::before { |
||||||
|
border-radius: 50%; |
||||||
|
box-sizing: content-box; |
||||||
|
content: ''; |
||||||
|
left: 0; |
||||||
|
height: 100%; |
||||||
|
pointer-events: none; |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
transform: scale(0.9); |
||||||
|
width: 100%; } |
||||||
|
.huh-launcher--button:hover, .huh-launcher--button:focus { |
||||||
|
outline: none; |
||||||
|
transform: scale(0.9); } |
||||||
|
.huh-launcher--button:hover::after, .huh-launcher--button:focus::after { |
||||||
|
animation: sonarEffect 1.3s ease-out; } |
||||||
|
|
||||||
|
.huh-launcher--label { |
||||||
|
display: block; |
||||||
|
font-size: 0; |
||||||
|
height: 0; |
||||||
|
width: 0; } |
||||||
|
|
||||||
|
.huh-container { |
||||||
|
background: #fff; |
||||||
|
border-radius: 4px; |
||||||
|
bottom: 90px; |
||||||
|
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.15); |
||||||
|
display: none; |
||||||
|
height: calc( 100% - 150px ); |
||||||
|
max-height: 550px; |
||||||
|
max-width: 350px; |
||||||
|
position: fixed; |
||||||
|
right: 20px; |
||||||
|
width: 100%; |
||||||
|
z-index: 500001; } |
||||||
|
.huh-container.open { |
||||||
|
animation: fadeIn 0.3s ease-in-out; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; } |
||||||
|
@media screen and (max-width: 600px) { |
||||||
|
.huh-container { |
||||||
|
bottom: 0; |
||||||
|
border-radius: 0; |
||||||
|
height: 100%; |
||||||
|
max-width: none; |
||||||
|
right: 0; |
||||||
|
top: 46px; } } |
||||||
|
|
||||||
|
.huh-container--head { |
||||||
|
background: #009688; |
||||||
|
border-radius: 4px 4px 0 0; |
||||||
|
height: 60px; |
||||||
|
flex-shrink: 0; |
||||||
|
overflow: hidden; |
||||||
|
position: relative; |
||||||
|
transition: background 0.3s; } |
||||||
|
@media screen and (max-width: 600px) { |
||||||
|
.huh-container--head { |
||||||
|
border-radius: 0; } } |
||||||
|
.huh-container--head.with-content { |
||||||
|
background: #f5f5f5 !important; |
||||||
|
border-bottom: 1px solid #ddd; } |
||||||
|
.huh-container--head.with-content .huh-container--heading { |
||||||
|
transform: translateX(-100%); } |
||||||
|
.huh-container--head.with-content .huh-container--back { |
||||||
|
transform: translateX(0); } |
||||||
|
|
||||||
|
.huh-container--heading, |
||||||
|
.huh-container--back { |
||||||
|
box-sizing: border-box; |
||||||
|
font-size: 16px; |
||||||
|
left: 0; |
||||||
|
line-height: 60px; |
||||||
|
margin: 0; |
||||||
|
padding: 0 20px; |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
transition: transform 0.2s; |
||||||
|
width: 100%; } |
||||||
|
|
||||||
|
.huh-container--heading { |
||||||
|
color: #fff; |
||||||
|
font-weight: 400; |
||||||
|
text-align: center; |
||||||
|
transform: translateX(0); |
||||||
|
width: 100%; } |
||||||
|
@media all and (max-width: 600px) { |
||||||
|
.huh-container--heading { |
||||||
|
text-align: left; } } |
||||||
|
|
||||||
|
.huh-container--back { |
||||||
|
text-decoration: none; |
||||||
|
transform: translateX(100%); } |
||||||
|
.huh-container--back > svg { |
||||||
|
display: inline-block; |
||||||
|
fill: #444; |
||||||
|
height: 16px; |
||||||
|
position: relative; |
||||||
|
top: 2px; |
||||||
|
width: 16px; } |
||||||
|
|
||||||
|
.huh-container--content { |
||||||
|
overflow: scroll; |
||||||
|
padding: 0 20px 20px; } |
||||||
|
.huh-container--content::after { |
||||||
|
background: -moz-linear-gradient(top, rgba(255, 255, 255, 0) 0%, #fff 55%, #fff 100%); |
||||||
|
background: -webkit-linear-gradient(top, rgba(255, 255, 255, 0) 0%, #fff 55%, #fff 100%); |
||||||
|
background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, #fff 55%, #fff 100%); |
||||||
|
bottom: 0; |
||||||
|
content: ''; |
||||||
|
display: block; |
||||||
|
height: 20px; |
||||||
|
left: 0; |
||||||
|
position: absolute; |
||||||
|
width: 100%; } |
||||||
|
.huh-container--content p, |
||||||
|
.huh-container--content ul, |
||||||
|
.huh-container--content ol { |
||||||
|
font-size: 14px; } |
||||||
|
.huh-container--content img { |
||||||
|
max-width: 100%; } |
||||||
|
.huh-container--content code, |
||||||
|
.huh-container--content pre { |
||||||
|
max-width: 100%; |
||||||
|
overflow: scroll; |
||||||
|
white-space: pre-wrap; |
||||||
|
word-wrap: break-word; } |
||||||
|
|
||||||
|
.huh-container--close-mobile { |
||||||
|
cursor: pointer; |
||||||
|
display: none; |
||||||
|
fill: #fff; |
||||||
|
height: 24px; |
||||||
|
padding: 17px 10px; |
||||||
|
position: absolute; |
||||||
|
right: 0; |
||||||
|
top: 0; |
||||||
|
width: 24px; } |
||||||
|
@media all and (max-width: 600px) { |
||||||
|
.huh-container--close-mobile { |
||||||
|
display: block; } } |
||||||
|
|
||||||
|
.huh-toc--trigger { |
||||||
|
border-bottom: 1px solid #eee; |
||||||
|
cursor: pointer; |
||||||
|
display: block; |
||||||
|
font-size: 16px; |
||||||
|
font-weight: 600; |
||||||
|
margin: 0 -20px; |
||||||
|
padding: 20px; |
||||||
|
position: relative; |
||||||
|
transition: background 0.3s, box-shadow 0.1s; } |
||||||
|
.huh-toc--trigger > span { |
||||||
|
color: #666; |
||||||
|
float: right; |
||||||
|
opacity: 0; |
||||||
|
transform: translateX(10px); |
||||||
|
transition: opacity 0.3s, transform 0.3s; } |
||||||
|
.huh-toc--trigger:hover { |
||||||
|
background: #f9f9f9; } |
||||||
|
.huh-toc--trigger:hover > span { |
||||||
|
opacity: 1; |
||||||
|
transform: translateX(0); } |
||||||
|
.huh-toc--trigger.hidden { |
||||||
|
display: none; } |
||||||
|
.huh-toc--trigger.current { |
||||||
|
animation: fadeIn 0.3s ease-in-out; |
||||||
|
border: 0; |
||||||
|
color: #222; |
||||||
|
cursor: auto; |
||||||
|
display: block; |
||||||
|
font-size: 18px; |
||||||
|
padding-bottom: 0; } |
||||||
|
.huh-toc--trigger.current > span { |
||||||
|
display: none; } |
||||||
|
.huh-toc--trigger.current:hover { |
||||||
|
background: 0; |
||||||
|
box-shadow: none; } |
||||||
|
.huh-toc--trigger.show { |
||||||
|
animation: fadeIn 0.3s ease-in-out; } |
||||||
|
|
||||||
|
.huh-toc--content { |
||||||
|
display: none; } |
||||||
|
.huh-toc--content.open { |
||||||
|
animation: fadeIn 0.3s ease-in-out; |
||||||
|
display: block; } |
@ -0,0 +1 @@ |
|||||||
|
@keyframes popIn{0%,55%{opacity:0;transform:scale(0)}75%{opacity:1;transform:scale(1.1)}90%{opacity:1;transform:scale(.9)}100%{opacity:1;transform:scale(1)}}@keyframes sonarEffect{0%{opacity:1}40%{opacity:.5;box-shadow:0 0 4px 2px rgba(0,0,0,.2)}100%{box-shadow:0 0 4px 2px rgba(0,0,0,.2);transform:scale(1.5);opacity:0}}@keyframes fadeIn{0%{opacity:0;transform:translateY(20px)}100%{opacity:1;transform:translateY(0)}}.huh-launcher{animation:popIn .8s ease-in-out;bottom:30px;position:fixed;right:20px;z-index:500001}.huh-launcher--button{-webkit-appearance:none;background:#009688;border:none;border-radius:50px;box-shadow:0 2px 10px rgba(0,0,0,.2);box-sizing:border-box;cursor:pointer;height:50px;padding:0;position:relative;transition:transform ease-out .1s;width:50px;z-index:1}.huh-launcher--button svg{fill:#fff;float:right;height:50px;left:0;position:absolute;top:0;transition:transform .2s;width:50px}.huh-launcher--button .huh-launcher--icon-close{height:30px;opacity:0;padding:10px;transform:scale(.2);width:30px}.huh-launcher--button.active .huh-launcher--icon-enable{opacity:0;transform:scale(.2)}.huh-launcher--button.active .huh-launcher--icon-close{opacity:1;transform:scale(1)}.huh-launcher--button::after,.huh-launcher--button::before{border-radius:50%;box-sizing:content-box;content:'';left:0;height:100%;pointer-events:none;position:absolute;top:0;transform:scale(.9);width:100%}.huh-launcher--button:focus,.huh-launcher--button:hover{outline:0;transform:scale(.9)}.huh-launcher--button:focus::after,.huh-launcher--button:hover::after{animation:sonarEffect 1.3s ease-out}.huh-container.open,.huh-toc--content.open,.huh-toc--trigger.current,.huh-toc--trigger.show{animation:fadeIn .3s ease-in-out}.huh-launcher--label{display:block;font-size:0;height:0;width:0}.huh-container{background:#fff;border-radius:4px;bottom:90px;box-shadow:0 5px 20px rgba(0,0,0,.15);display:none;height:calc(100% - 150px);max-height:550px;max-width:350px;position:fixed;right:20px;width:100%;z-index:500001}.huh-container.open{display:flex;flex-direction:column}@media screen and (max-width:600px){.huh-container{bottom:0;border-radius:0;height:100%;max-width:none;right:0;top:46px}}.huh-container--head{background:#009688;border-radius:4px 4px 0 0;height:60px;flex-shrink:0;overflow:hidden;position:relative;transition:background .3s}@media screen and (max-width:600px){.huh-container--head{border-radius:0}}.huh-container--head.with-content{background:#f5f5f5!important;border-bottom:1px solid #ddd}.huh-container--head.with-content .huh-container--heading{transform:translateX(-100%)}.huh-container--head.with-content .huh-container--back,.huh-container--heading{transform:translateX(0)}.huh-container--back,.huh-container--heading{box-sizing:border-box;font-size:16px;left:0;line-height:60px;margin:0;padding:0 20px;position:absolute;top:0;transition:transform .2s;width:100%}.huh-container--heading{color:#fff;font-weight:400;text-align:center;width:100%}.huh-container--back{text-decoration:none;transform:translateX(100%)}.huh-container--back>svg{display:inline-block;fill:#444;height:16px;position:relative;top:2px;width:16px}.huh-container--content{overflow:scroll;padding:0 20px 20px}.huh-container--content::after{background:-moz-linear-gradient(top,rgba(255,255,255,0) 0,#fff 55%,#fff 100%);background:-webkit-linear-gradient(top,rgba(255,255,255,0) 0,#fff 55%,#fff 100%);background:linear-gradient(to bottom,rgba(255,255,255,0) 0,#fff 55%,#fff 100%);bottom:0;content:'';display:block;height:20px;left:0;position:absolute;width:100%}.huh-container--content ol,.huh-container--content p,.huh-container--content ul{font-size:14px}.huh-container--content img{max-width:100%}.huh-container--content code,.huh-container--content pre{max-width:100%;overflow:scroll;white-space:pre-wrap;word-wrap:break-word}.huh-container--close-mobile{cursor:pointer;display:none;fill:#fff;height:24px;padding:17px 10px;position:absolute;right:0;top:0;width:24px}@media all and (max-width:600px){.huh-container--heading{text-align:left}.huh-container--close-mobile{display:block}}.huh-toc--trigger{border-bottom:1px solid #eee;cursor:pointer;display:block;font-size:16px;font-weight:600;margin:0 -20px;padding:20px;position:relative;transition:background .3s,box-shadow .1s}.huh-toc--trigger>span{color:#666;float:right;opacity:0;transform:translateX(10px);transition:opacity .3s,transform .3s}.huh-toc--trigger:hover{background:#f9f9f9}.huh-toc--trigger:hover>span{opacity:1;transform:translateX(0)}.huh-toc--trigger.hidden{display:none}.huh-toc--trigger.current{border:0;color:#222;cursor:auto;display:block;font-size:18px;padding-bottom:0}.huh-toc--content,.huh-toc--trigger.current>span{display:none}.huh-toc--trigger.current:hover{background:0;box-shadow:none}.huh-toc--content.open{display:block} |
@ -0,0 +1,88 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) { |
||||||
|
exit; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Main huh class. |
||||||
|
*/ |
||||||
|
class WP_Huh { |
||||||
|
public $markdown_doc_url = null; |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructor. |
||||||
|
*/ |
||||||
|
public function __construct() {} |
||||||
|
|
||||||
|
/** |
||||||
|
* Initialize. |
||||||
|
* @param string $markdown_doc_url URL of the raw markdown file. |
||||||
|
*/ |
||||||
|
public function init( $markdown_doc_url ) { |
||||||
|
$this->markdown_doc_url = $markdown_doc_url; |
||||||
|
|
||||||
|
if ( is_admin() || is_customize_preview() ) { |
||||||
|
add_action( 'admin_enqueue_scripts', array( $this, 'huh_load_scripts' ) ); |
||||||
|
add_action( 'admin_footer', array( $this, 'display_huh' ) ); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Enqueue CSS and JS. |
||||||
|
*/ |
||||||
|
public function huh_load_scripts() { |
||||||
|
wp_register_style( 'huh_admin_css', get_theme_file_uri().'/lib/huh/huh.css', false ); |
||||||
|
wp_enqueue_style( 'huh_admin_css' ); |
||||||
|
|
||||||
|
wp_register_script( 'huh_admin_js', get_theme_file_uri().'/lib/huh/js/huh.js', false ); |
||||||
|
wp_enqueue_script( 'huh_admin_js' ); |
||||||
|
|
||||||
|
wp_register_script( 'huh_markdown_js', get_theme_file_uri().'/lib/huh/js/marked.js', false ); |
||||||
|
wp_enqueue_script( 'huh_markdown_js' ); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Get admin color scheme. |
||||||
|
*/ |
||||||
|
public function huh_get_admin_colors() { |
||||||
|
global $_wp_admin_css_colors; |
||||||
|
$current_color_scheme = get_user_meta( get_current_user_id(), 'admin_color', true ); |
||||||
|
$colors = $_wp_admin_css_colors[ $current_color_scheme ]->colors; |
||||||
|
|
||||||
|
return $colors; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Display the HTML. |
||||||
|
* @param $markdown_doc_url URL of the raw markdown file. |
||||||
|
*/ |
||||||
|
public function display_huh() { |
||||||
|
$colors = $this->huh_get_admin_colors(); |
||||||
|
$huh_accent_color = $colors[1]; |
||||||
|
|
||||||
|
?> |
||||||
|
<script type="text/javascript">var huhDocUrl = <?php echo json_encode( $this->markdown_doc_url ); ?>;</script>
|
||||||
|
<div class="huh-launcher"> |
||||||
|
<button class="huh-launcher--button" id="huh-launcher--button" data-accent-color="<?php echo esc_attr( $huh_accent_color ); ?>">
|
||||||
|
<svg class="huh-launcher--icon-enable" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve"><g><circle cx="50" cy="63.5" r="3"></circle><g><path d="M88.6,50c0-21.3-17.3-38.6-38.6-38.6S11.4,28.7,11.4,50S28.7,88.6,50,88.6S88.6,71.3,88.6,50z M15.6,50 c0-18.9,15.4-34.4,34.4-34.4S84.4,31.1,84.4,50S68.9,84.4,50,84.4S15.6,68.9,15.6,50z"></path><path d="M55.8,42.1c0.1,2.5-1.4,4.8-3.7,5.7c-2.6,1-4.3,3.6-4.3,6.5v1.4h4.2v-1.4c0-1.1,0.7-2.2,1.6-2.6c4-1.6,6.5-5.5,6.3-9.8 c-0.2-5.1-4.5-9.4-9.6-9.6C47.7,32.1,45,33.1,43,35c-2,1.9-3.1,4.5-3.1,7.3h4.2c0-1.6,0.6-3.1,1.8-4.2c1.2-1.1,2.7-1.7,4.3-1.6 C53.3,36.6,55.7,39.1,55.8,42.1z"></path></g></g></svg> |
||||||
|
<svg class="huh-launcher--icon-close" xmlns="https://www.w3.org/2000/svg" viewBox="0 0 24 24"><g id="plus"><path d="M18.36,19.78L12,13.41,5.64,19.78,4.22,18.36,10.59,12,4.22,5.64,5.64,4.22,12,10.59l6.36-6.36,1.41,1.41L13.41,12l6.36,6.36Z"/></g></svg> |
||||||
|
<span class="huh-launcher--label">Need help?</span> |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="huh-container" id="huh-container"> |
||||||
|
<div class="huh-container--head" id="huh-header"> |
||||||
|
<h4 class="huh-container--heading">Need help?</h4> |
||||||
|
<a href="javascript:;" class="huh-container--back" id="huh-back-to-toc"> |
||||||
|
<svg xmlns="https://www.w3.org/2000/svg" viewBox="0 0 24 24"><rect x="0" fill="none" width="24" height="24"/><g><path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"/></g></svg> |
||||||
|
Back |
||||||
|
</a> |
||||||
|
<svg class="huh-container--close-mobile" id="huh-mobile-close" xmlns="https://www.w3.org/2000/svg" viewBox="0 0 24 24"><g id="plus"><path d="M18.36,19.78L12,13.41,5.64,19.78,4.22,18.36,10.59,12,4.22,5.64,5.64,4.22,12,10.59l6.36-6.36,1.41,1.41L13.41,12l6.36,6.36Z"/></g></svg> |
||||||
|
</div> |
||||||
|
<div class="huh-container--content" id="huh-content"></div> |
||||||
|
</div> |
||||||
|
<?php |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,139 @@ |
|||||||
|
// const docUrl = 'https://raw.githubusercontent.com/secretpizzaparty/huh/master/README.md';
|
||||||
|
|
||||||
|
let huhLauncher = '', |
||||||
|
huhMobileClose = '', |
||||||
|
huhContainer = '', |
||||||
|
huhContent = '', |
||||||
|
huhHeader = '', |
||||||
|
huhBackButton = '', |
||||||
|
huhAccentColor = '', |
||||||
|
huhTocTriggers = ''; |
||||||
|
|
||||||
|
// init
|
||||||
|
function huhInit() { |
||||||
|
huhLauncher = document.querySelector( '#huh-launcher--button' ); |
||||||
|
huhMobileClose = document.querySelector( '#huh-mobile-close' ); |
||||||
|
huhContainer = document.querySelector( '#huh-container' ); |
||||||
|
huhContent = document.querySelector( '#huh-content' ); |
||||||
|
huhHeader = document.querySelector( '#huh-header'); |
||||||
|
huhBackButton = document.querySelector( '#huh-back-to-toc' ); |
||||||
|
huhAccentColor = huhLauncher.getAttribute( 'data-accent-color' ); |
||||||
|
|
||||||
|
// fetch the markdown file (set in huh.php)
|
||||||
|
// then load the content into the container
|
||||||
|
fetch( huhDocUrl ) |
||||||
|
.then( blob => blob.text() ) |
||||||
|
.then( data => loadContent( data ) ); |
||||||
|
} |
||||||
|
|
||||||
|
function loadContent( data ) { |
||||||
|
// first we format the content
|
||||||
|
const dataFormat = marked( data ); |
||||||
|
|
||||||
|
// then we create our custom content structure
|
||||||
|
const content = createContent( dataFormat ); |
||||||
|
|
||||||
|
// then we insert content into the content box
|
||||||
|
huhContent.innerHTML = content; |
||||||
|
|
||||||
|
// apply accent color
|
||||||
|
applyAccentColor( huhAccentColor ); |
||||||
|
|
||||||
|
// bind interaction events after all content is loaded
|
||||||
|
huhBindEvents(); |
||||||
|
} |
||||||
|
|
||||||
|
function createContent( data ) { |
||||||
|
let sections = data.split( '<h1' ); // split at h1
|
||||||
|
sections = sections.filter( ( n ) => { return n != '' } ); // remove empty elements
|
||||||
|
|
||||||
|
const content = sections.map( section => { |
||||||
|
const splitIndex = section.indexOf( '</h1>' ); // split into two blocks after <h1>
|
||||||
|
const headingSplit = section.slice( 0, splitIndex ); |
||||||
|
const heading = headingSplit.slice( headingSplit.indexOf( '>' ) + 1 ); // content after `id="*">``
|
||||||
|
const body = section.slice( splitIndex + 5 ); // content after closing `</h1>`
|
||||||
|
|
||||||
|
return { |
||||||
|
heading: heading, |
||||||
|
body: body |
||||||
|
}; |
||||||
|
} ); |
||||||
|
|
||||||
|
const contentHtml = formatContent( content ); |
||||||
|
|
||||||
|
return contentHtml; |
||||||
|
} |
||||||
|
|
||||||
|
function formatContent( content ) { |
||||||
|
const html = content.map( item => { |
||||||
|
return ` |
||||||
|
<a class="huh-toc--trigger">${ item.heading }<span>→</span></a> |
||||||
|
<div class="huh-toc--content"> |
||||||
|
${ item.body } |
||||||
|
</div> |
||||||
|
`;
|
||||||
|
} ).join( '' ); |
||||||
|
|
||||||
|
return html; |
||||||
|
} |
||||||
|
|
||||||
|
function showHideContainer( e ) { |
||||||
|
huhLauncher.classList.toggle( 'active' ); |
||||||
|
huhContainer.classList.toggle( 'open' ); |
||||||
|
} |
||||||
|
|
||||||
|
function showContent( e ) { |
||||||
|
// hide all triggers
|
||||||
|
for ( i = 0; i < huhTocTriggers.length; i++ ) { |
||||||
|
huhTocTriggers[i].classList.add( 'hidden' ); |
||||||
|
huhTocTriggers[i].classList.remove( 'show' ); |
||||||
|
} |
||||||
|
|
||||||
|
// add a class to indicate current selection
|
||||||
|
e.target.classList.add( 'current' ); |
||||||
|
|
||||||
|
// add a class to content block of the current selection
|
||||||
|
// so we can show just that one
|
||||||
|
const content = e.target.nextElementSibling; |
||||||
|
content.classList.add( 'open' ); |
||||||
|
|
||||||
|
// show back button
|
||||||
|
huhHeader.classList.add( 'with-content' ); |
||||||
|
} |
||||||
|
|
||||||
|
function backToToc() { |
||||||
|
// show all triggers
|
||||||
|
for ( i = 0; i < huhTocTriggers.length; i++ ) { |
||||||
|
huhTocTriggers[i].classList.remove( 'hidden', 'current' ); |
||||||
|
huhTocTriggers[i].classList.add( 'show' ); |
||||||
|
} |
||||||
|
|
||||||
|
// hide all content blocks
|
||||||
|
const contentBlocks = document.querySelectorAll( '.huh-toc--content' ); |
||||||
|
for ( i = 0; i < contentBlocks.length; i++ ) { |
||||||
|
contentBlocks[i].classList.remove( 'open' ); |
||||||
|
} |
||||||
|
|
||||||
|
// show main header
|
||||||
|
huhHeader.classList.remove( 'with-content' ); |
||||||
|
} |
||||||
|
|
||||||
|
function applyAccentColor( color ) { |
||||||
|
huhLauncher.setAttribute( 'style', 'background:' + color ); |
||||||
|
huhHeader.setAttribute( 'style', 'background:' + color ); |
||||||
|
} |
||||||
|
|
||||||
|
function huhBindEvents() { |
||||||
|
huhLauncher.addEventListener( 'click', showHideContainer ); |
||||||
|
huhMobileClose.addEventListener( 'click', showHideContainer ); |
||||||
|
huhBackButton.addEventListener( 'click', backToToc ); |
||||||
|
|
||||||
|
huhTocTriggers = document.querySelectorAll( '.huh-toc--trigger' ); |
||||||
|
for ( i = 0; i < huhTocTriggers.length; i++ ) { |
||||||
|
huhTocTriggers[i].addEventListener( 'click', showContent ); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// init after page has loaded to make sure
|
||||||
|
// we can find the DOM nodes to modify
|
||||||
|
window.addEventListener( 'load', huhInit ); |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,25 @@ |
|||||||
|
{ |
||||||
|
"name": "huh", |
||||||
|
"title": "huh", |
||||||
|
"version": "1.0.0", |
||||||
|
"repository": { |
||||||
|
"type": "git", |
||||||
|
"url": "https://github.com/secretpizzaparty/huh" |
||||||
|
}, |
||||||
|
"license": "GPL-2.0+", |
||||||
|
"main": "Gruntfile.js", |
||||||
|
"devDependencies": { |
||||||
|
"grunt": "~1.0.1", |
||||||
|
"grunt-checktextdomain": "~1.0.0", |
||||||
|
"grunt-contrib-clean": "~1.0.0", |
||||||
|
"grunt-contrib-cssmin": "~1.0.0", |
||||||
|
"grunt-contrib-sass": "~1.0.0", |
||||||
|
"grunt-contrib-watch": "~1.0.0", |
||||||
|
"grunt-wp-i18n": "~0.5.4", |
||||||
|
"node-bourbon": "~4.2.3" |
||||||
|
}, |
||||||
|
"engines": { |
||||||
|
"node": ">=0.8.0", |
||||||
|
"npm": ">=1.1.0" |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,51 @@ |
|||||||
|
// huh animations |
||||||
|
|
||||||
|
@keyframes popIn { |
||||||
|
0% { |
||||||
|
opacity: 0; |
||||||
|
transform: scale( 0 ); |
||||||
|
} |
||||||
|
55% { |
||||||
|
opacity: 0; |
||||||
|
transform: scale( 0 ); |
||||||
|
} |
||||||
|
75% { |
||||||
|
opacity: 1; |
||||||
|
transform: scale( 1.1 ); |
||||||
|
} |
||||||
|
90% { |
||||||
|
opacity: 1; |
||||||
|
transform: scale( 0.9 ); |
||||||
|
} |
||||||
|
100% { |
||||||
|
opacity: 1; |
||||||
|
transform: scale( 1 ); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@keyframes sonarEffect { |
||||||
|
0% { |
||||||
|
opacity: 1; |
||||||
|
} |
||||||
|
40% { |
||||||
|
opacity: 0.5; |
||||||
|
box-shadow: 0 0 4px 2px rgba( 0, 0, 0 , 0.2 ); |
||||||
|
} |
||||||
|
100% { |
||||||
|
box-shadow: 0 0 4px 2px rgba( 0, 0, 0 , 0.2 ); |
||||||
|
transform: scale(1.5); |
||||||
|
opacity: 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@keyframes fadeIn { |
||||||
|
0% { |
||||||
|
opacity: 0; |
||||||
|
transform: translateY( 20px ); |
||||||
|
} |
||||||
|
|
||||||
|
100% { |
||||||
|
opacity: 1; |
||||||
|
transform: translateY( 0 ); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,214 @@ |
|||||||
|
// huh content container |
||||||
|
.huh-container { |
||||||
|
background: #fff; |
||||||
|
border-radius: 4px; |
||||||
|
bottom: 90px; |
||||||
|
box-shadow: 0 5px 20px rgba( 0, 0, 0, 0.15 ); |
||||||
|
display: none; |
||||||
|
@include calc( 'height', '100% - 150px' ); |
||||||
|
max-height: 550px; |
||||||
|
max-width: 350px; |
||||||
|
position: fixed; |
||||||
|
right: 20px; |
||||||
|
width: 100%; |
||||||
|
z-index: 500001; |
||||||
|
|
||||||
|
&.open { |
||||||
|
animation: fadeIn 0.3s ease-in-out; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
} |
||||||
|
|
||||||
|
@media screen and ( max-width: 600px ) { |
||||||
|
bottom: 0; |
||||||
|
border-radius: 0; |
||||||
|
height: 100%; |
||||||
|
max-width: none; |
||||||
|
right: 0; |
||||||
|
top: 46px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.huh-container--head { |
||||||
|
background: $main-accent; |
||||||
|
border-radius: 4px 4px 0 0; |
||||||
|
height: 60px; |
||||||
|
flex-shrink: 0; |
||||||
|
overflow: hidden; |
||||||
|
position: relative; |
||||||
|
transition: background 0.3s; |
||||||
|
|
||||||
|
@media screen and ( max-width: 600px ) { |
||||||
|
border-radius: 0; |
||||||
|
} |
||||||
|
|
||||||
|
&.with-content { |
||||||
|
background: #f5f5f5 !important; |
||||||
|
border-bottom: 1px solid #ddd; |
||||||
|
|
||||||
|
.huh-container--heading { |
||||||
|
transform: translateX( -100% ); |
||||||
|
} |
||||||
|
|
||||||
|
.huh-container--back { |
||||||
|
transform: translateX( 0 ); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.huh-container--heading, |
||||||
|
.huh-container--back { |
||||||
|
box-sizing: border-box; |
||||||
|
font-size: 16px; |
||||||
|
left: 0; |
||||||
|
line-height: 60px; |
||||||
|
margin: 0; |
||||||
|
padding: 0 20px; |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
transition: transform 0.2s; |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
.huh-container--heading { |
||||||
|
color: #fff; |
||||||
|
font-weight: 400; |
||||||
|
text-align: center; |
||||||
|
transform: translateX( 0 ); |
||||||
|
width: 100%; |
||||||
|
|
||||||
|
@media all and ( max-width: 600px ) { |
||||||
|
text-align: left; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.huh-container--back { |
||||||
|
text-decoration: none; |
||||||
|
transform: translateX( 100% ); |
||||||
|
|
||||||
|
> svg { |
||||||
|
display: inline-block; |
||||||
|
fill: #444; |
||||||
|
height: 16px; |
||||||
|
position: relative; |
||||||
|
top: 2px; |
||||||
|
width: 16px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.huh-container--content { |
||||||
|
overflow: scroll; |
||||||
|
padding: 0 20px 20px; |
||||||
|
|
||||||
|
&::after { |
||||||
|
background: -moz-linear-gradient(top, rgba( #fff, 0 ) 0%, #fff 55%, #fff 100%); |
||||||
|
background: -webkit-linear-gradient(top, rgba( #fff, 0 ) 0%, #fff 55%, #fff 100%); |
||||||
|
background: linear-gradient(to bottom, rgba( #fff, 0 ) 0%, #fff 55%, #fff 100%); |
||||||
|
bottom: 0; |
||||||
|
content: ''; |
||||||
|
display: block; |
||||||
|
height: 20px; |
||||||
|
left: 0; |
||||||
|
position: absolute; |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
p, |
||||||
|
ul, |
||||||
|
ol { |
||||||
|
font-size: 14px; |
||||||
|
} |
||||||
|
|
||||||
|
img { |
||||||
|
max-width: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
code, |
||||||
|
pre { |
||||||
|
max-width: 100%; |
||||||
|
overflow: scroll; |
||||||
|
white-space: pre-wrap; |
||||||
|
word-wrap: break-word; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.huh-container--close-mobile { |
||||||
|
cursor: pointer; |
||||||
|
display: none; |
||||||
|
fill: #fff; |
||||||
|
height: 24px; |
||||||
|
padding: 17px 10px; |
||||||
|
position: absolute; |
||||||
|
right: 0; |
||||||
|
top: 0; |
||||||
|
width: 24px; |
||||||
|
|
||||||
|
@media all and ( max-width: 600px ) { |
||||||
|
display: block; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.huh-toc--trigger { |
||||||
|
border-bottom: 1px solid #eee; |
||||||
|
cursor: pointer; |
||||||
|
display: block; |
||||||
|
font-size: 16px; |
||||||
|
font-weight: 600; |
||||||
|
margin: 0 -20px; |
||||||
|
padding: 20px; |
||||||
|
position: relative; |
||||||
|
transition: background 0.3s, box-shadow 0.1s; |
||||||
|
|
||||||
|
> span { |
||||||
|
color: #666; |
||||||
|
float: right; |
||||||
|
opacity: 0; |
||||||
|
transform: translateX( 10px ); |
||||||
|
transition: opacity 0.3s, transform 0.3s; |
||||||
|
} |
||||||
|
|
||||||
|
&:hover { |
||||||
|
background: #f9f9f9; |
||||||
|
|
||||||
|
> span { |
||||||
|
opacity: 1; |
||||||
|
transform: translateX( 0 ); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
&.hidden { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
&.current { |
||||||
|
animation: fadeIn 0.3s ease-in-out; |
||||||
|
border: 0; |
||||||
|
color: #222; |
||||||
|
cursor: auto; |
||||||
|
display: block; |
||||||
|
font-size: 18px; |
||||||
|
padding-bottom: 0; |
||||||
|
|
||||||
|
> span { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
&:hover { |
||||||
|
background: 0; |
||||||
|
box-shadow: none; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
&.show { |
||||||
|
animation: fadeIn 0.3s ease-in-out; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.huh-toc--content { |
||||||
|
display: none; |
||||||
|
|
||||||
|
&.open { |
||||||
|
animation: fadeIn 0.3s ease-in-out; |
||||||
|
display: block; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,86 @@ |
|||||||
|
// huh launcher button |
||||||
|
.huh-launcher { |
||||||
|
animation: popIn 0.8s ease-in-out; |
||||||
|
bottom: 30px; |
||||||
|
position: fixed; |
||||||
|
right: 20px; |
||||||
|
z-index: 500001; |
||||||
|
} |
||||||
|
|
||||||
|
.huh-launcher--button { |
||||||
|
-webkit-appearance: none; |
||||||
|
background: $main-accent; |
||||||
|
border: none; |
||||||
|
border-radius: 50px; |
||||||
|
box-shadow: 0 2px 10px rgba( 0, 0, 0, 0.2 ); |
||||||
|
box-sizing: border-box; |
||||||
|
cursor: pointer; |
||||||
|
height: 50px; |
||||||
|
padding: 0; |
||||||
|
position: relative; |
||||||
|
transition: transform ease-out 0.1s; |
||||||
|
width: 50px; |
||||||
|
z-index: 1; |
||||||
|
|
||||||
|
svg { |
||||||
|
fill: #fff; |
||||||
|
float: right; |
||||||
|
height: 50px; |
||||||
|
left: 0; |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
transition: transform 0.2s; |
||||||
|
width: 50px; |
||||||
|
} |
||||||
|
|
||||||
|
.huh-launcher--icon-close { |
||||||
|
height: 30px; |
||||||
|
opacity: 0; |
||||||
|
padding: 10px; |
||||||
|
transform: scale( 0.2 ); |
||||||
|
width: 30px; |
||||||
|
} |
||||||
|
|
||||||
|
&.active { |
||||||
|
.huh-launcher--icon-enable { |
||||||
|
opacity: 0; |
||||||
|
transform: scale( 0.2 ); |
||||||
|
} |
||||||
|
|
||||||
|
.huh-launcher--icon-close { |
||||||
|
opacity: 1; |
||||||
|
transform: scale( 1); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
&::after, |
||||||
|
&::before { |
||||||
|
border-radius: 50%; |
||||||
|
box-sizing: content-box; |
||||||
|
content: ''; |
||||||
|
left: 0; |
||||||
|
height: 100%; |
||||||
|
pointer-events: none; |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
transform: scale( 0.9 ); |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
&:hover, |
||||||
|
&:focus { |
||||||
|
outline: none; |
||||||
|
transform: scale( 0.9 ); |
||||||
|
|
||||||
|
&::after { |
||||||
|
animation: sonarEffect 1.3s ease-out; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.huh-launcher--label { |
||||||
|
display: block; |
||||||
|
font-size: 0; |
||||||
|
height: 0; |
||||||
|
width: 0; |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
// huh mixins |
||||||
|
@mixin calc( $property, $expression ) { |
||||||
|
#{$property}: calc( #{$expression} ); |
||||||
|
} |
Loading…
Reference in new issue