Initial commit. State 04.2021.

This commit is contained in:
2021-04-22 17:57:16 +02:00
commit 82781cca41
2974 changed files with 975656 additions and 0 deletions

5
wp-content/plugins/wpclef/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
npm-debug.log
node_modules
release
sftp-config.json
build

View File

@@ -0,0 +1,42 @@
# Travis CI Configuration File
# Tell Travis CI we're using PHP
language: php
# PHP version used in first build configuration.
php:
- "5.5"
- "5.4"
- "5.3"
# WordPress version used in first build configuration.
env:
- WP_VERSION=master
- WP_VERSION=3.9.1
- WP_VERSION=3.8.3
# Clones WordPress and configures our testing environment.
before_script:
- export REPO_SLUG=$(basename $(pwd))
- export PLUGIN_SLUG=wpclef
# fix sendmail
- chmod +x tests/setup/fakesendmail.sh
- sudo mkdir -p /var/qmail/bin
- sudo cp tests/setup/fakesendmail.sh /var/qmail/bin/sendmail
- sudo cp tests/setup/fakesendmail.sh /usr/sbin/sendmail
- echo 'sendmail_path = "/usr/sbin/sendmail -t -i "' | sudo tee "/home/travis/.phpenv/versions/`php -r 'echo PHP_VERSION;'`/etc/conf.d/sendmail.ini"
# clone wordpress
- git clone --depth=50 --branch="$WP_VERSION" git://develop.git.wordpress.org/ /tmp/wordpress
- cd ..
- mv "$REPO_SLUG" "/tmp/wordpress/src/wp-content/plugins/$PLUGIN_SLUG"
- cd /tmp/wordpress
- mysql -e "CREATE DATABASE wordpress_tests;" -uroot
- cp wp-tests-config-sample.php wp-tests-config.php
- sed -i "s/youremptytestdbnamehere/wordpress_tests/" wp-tests-config.php
- sed -i "s/yourusernamehere/travis/" wp-tests-config.php
- sed -i "s/yourpasswordhere//" wp-tests-config.php
- cd "/tmp/wordpress/src/wp-content/plugins/$PLUGIN_SLUG"
script: phpunit

View File

@@ -0,0 +1,7 @@
[main]
host = https://www.transifex.com
[wpclef.wpclef]
file_filter = languages/clef-<lang>.po
source_file = languages/wpclef.pot
source_lang = en

View File

@@ -0,0 +1,490 @@
# Full Features Test Checklist
This file presents a master list of WP Clefs features to facilitate systematic testing before major releases. It is designed to utilize GitHubs MarkDown checklists. So, to run a full test, copy-n-paste the raw contents of this file into a [new GitHub Issue](https://github.com/clef/wordpress/issues/new). Then check the boxes as you complete the steps.
**Prerequisites**
1. Love.
1. Time.
1. Basic testing (~ 5-min. run time): requires a WordPress single-site install with at least one user account for [each role](http://codex.wordpress.org/Roles_and_Capabilities).
1. Whole-hog, full-boom testing (~ ∞-min. run time): requires bastic testing prereqs plus two WordPress multi-site installs, one for shared domain setups and one for custom domain setups. All super admin and sub-sites should have at least one active user account for [each role](http://codex.wordpress.org/Roles_and_Capabilities).
1. Cue theme music [track 1](http://www.youtube.com/watch?v=X5AfjAXcBXY), [track 2](http://www.youtube.com/watch?v=Gl83mI69nX4), [track 3](http://www.youtube.com/watch?v=Csy2XRlWMWE), and smile while pondering how fresh-n-clean Clef is. Awwww yeeeeah.
**General Legend:**
- SW: Setup Wizard
- WP: WordPress
- WPC: WP Clef (i.e., the Clef plugin for WordPress)
## Uninstall Process
1. Deactivate plugin.
- [ ] WPC is deactivated, and normal password log in form appears on wp-login.php.
- [ ] WPCs settings are saved in the database (can verify via re-activation: pre-deactivation settings should re-appear).
1. Remove previous version of WPC via WPs plugin uninstaller to ensure a clean install.
- [ ] WPCs files are deleted.
- [ ] WPCs database settings are deleted.
## Install Process
### Activation
1. Clone the repository and checkout the appropriate branch
1. `git clone git://github.com/clef/wordpress.git wpclef`
1. `cd wpclef`
1. `git checkout [INSERT TESTING BRANCH NAME]`
- [ ] Activate WPC via WPs Dashboard > Plugins > Installed Plugins
- [ ] SW loads automatically
### Setup Wizard
- [ ] "Skip setup" link takes you immediately to settings page
#### (A) SW State 1: Not logged in to Clef
- [ ] "Get started" takes you to Clef Wave screen
- [ ] Text Clef App link successfully.
- [ ] Sync Clef Wave and arrive at "One more click!" screen.
#### (B) SW State 2: Logged in to Clef
- [ ] "Get started" takes you to "One-click setup!" screen.
#### (C) SW Tests for Both States
- [ ] Execute "one-click setup" and arrive at "Invite" screen.
- [ ] Send invite e-mail to Everyone.
- [ ] Send invite e-mail to roles >= Contributor.
- [ ] Send invite e-mail to roles >= Author.
- [ ] Send invite e-mail to roles >= Editor.
- [ ] Send invite e-mail to roles >= Administrator.
- [ ] Send invite e-mail to roles >= Super Administrator.
- [ ] E-mail preview text matches actual e-mail.
- [ ] Arrive at "3 tips" screen after send invite or skip invite.
- [ ] Arrive at "Get Waltz" screen.
- [ ] "Try Waltz" loads http://getwaltz.com in new tab.
- [ ] "Go to Clef Settings" loads settings page with graceful slide up.
### Setup Wizard Multi-Site Iterations
#### State 1: Network-wide WPC install on shared domain name
- [ ] Run SW tests (A), (B), and (C) on Super Admin site.
- [ ] Run SW tests (A), (B), and (C) on one sub-site.
#### State 2: Network-wide WPC install with custom domain names
- [ ] Run SW tests (A), (B), and (C) on Super Admin site.
- [ ] Run SW tests (A), (B), and (C) on one sub-site.
#### State 3: Site-specific install on shared domain name
- [ ] Run SW tests (A), (B), and (C) on Super Admin site.
- [ ] Run SW tests (A), (B), and (C) on one sub-site.
#### State 4: Site-specific install on shared domain name
- [ ] Run SW tests (A), (B), and (C) on Super Admin site.
- [ ] Run SW tests (A), (B), and (C) on one sub-site.
## Connect Clef Account Actions
- [ ] Selecting “Disconnect Clef account”
- returns success notification
- loads SW automatically
- [ ] Selecting “Get Started” loads “Connect your Clef account” screen
- [ ] Text the download link to your phone.
- [ ] CB loads Clef Wave and syncs WP user account.
- [ ] Completing the SW sends you to the Dashboard.
## Password Settings and Login Actions
**WP-Login.php Legend**
- CA: Clef App
- CB: Clef button (i.e., “Log in w/ your phone”)
- LE: "Lost your password?" e-mail
- LF: "Lost your password?" form (i.e., wp-login.php?action=lostpassword)
- LL: "Lost your password?" link
- PF: Password form (i.e., the ordinary user/pass form displayed at wp-login.php)
**Settings Page Legend**
- P1: Disable passwords for Clef users
- P2: Disable passwords for all users with roles greater than or equal to
- P3: Disable passwords for all users and hide the password login form
- P4: Allow passwords for API
- O1: Override key
- O2: Generate secure override url link
- O3: Override url button
- O4: Override preview
- SS: "Setting saved" AJAX notification (appears then fades).
- XT: XML-RPC Test. Run this from command line (HT: Jesse): `curl --data '<?xml version="1.0"?><methodCall><methodName>wp.getOptions</methodName><params><param><value><i4>1</i4></value></param><param><value><string>USERNAME</string></value></param><param><value><string>PASSWORD</string></value></param></params></methodCall>' http://YOURWORDPRESSITE/xmlrpc.php`
Start the following tests from fresh install state (i.e., all settings except API keys should be null, false, or “disabled”).
### Disable passwords: P1 = true, P2P4 = null.
- [ ] SS fades.
- [ ] P4 appears.
- [ ] Override settings section appears.
- O1 = null.
- O4 = hidden.
- [ ] selecting 02
- shows SS,
- inserts key in O1,
- and shows O4.
1. Non-Clef user login
- [ ] wp-login.php displays PF + CB with LL.
- [ ] Log in via PF.
1. Non-Clef user reset password
- [ ] LF sends password reset e-mail.
- [ ] Set new password.
1. Clef user login
- [ ] wp-login.php displays PF + CB with LL.
- [ ] Log in via PF returns “passwords have been disabled....”
- [ ] Log in via override.
- [ ] Log in via CB.
- [ ] Log out via CA.
1. Clef user reset password via LF
- [ ] Disabled. Returns “password resets have been disabled....”
1. XML-RPC login
- [ ] Disabled. XT returns “passwords have been disabled....”
### Disable passwords: set P2 = not null, P3P4 = null.
- [ ] wp-login.php displays PF + CB with LL.
#### When any non-null P2 option is selected
- [ ] SS fades.
- [ ] P4 appears.
- [ ] Override settings section appears.
- O1 = null.
- O4 = hidden.
- [ ] selecting 02
- shows SS,
- inserts key in O1,
- and shows O4.
#### P2 = “Contributor”
1. Subscriber role login
- [ ] Log in via PF.
1. Subscriber role reset password
- [ ] LF sends password reset e-mail.
- [ ] Set new password.
1. Contributor role login
- [ ] Log in via PF returns “passwords have been disabled....”
- [ ] Log in via override.
- [ ] Log in via CB.
- [ ] Log out via CA.
1. Contributor role reset password via LF
- [ ] Disabled. Returns “password resets have been disabled....”
1. Author role login
- [ ] Log in via PF returns “passwords have been disabled....”
- [ ] Log in via override.
- [ ] Log in via CB.
- [ ] Log out via CA.
1. Author role reset password via LF
- [ ] Disabled. Returns “password resets have been disabled....”
1. Editor role login
- [ ] Log in via PF returns “passwords have been disabled....”
- [ ] Log in via override.
- [ ] Log in via CB.
- [ ] Log out via CA.
1. Editor role reset password via LF
- [ ] Disabled. Returns “password resets have been disabled....”
1. Administrator role login
- [ ] Log in via PF returns “passwords have been disabled....”
- [ ] Log in via override.
- [ ] Log in via CB.
- [ ] Log out via CA.
1. Administrator role reset password via LF
- [ ] Disabled. Returns “password resets have been disabled....”
1. Super Administrator role login
- [ ] Log in via PF returns “passwords have been disabled....”
- [ ] Log in via override.
- [ ] Log in via CB.
- [ ] Log out via CA.
1. Super Administrator role reset password via LF
- [ ] Disabled. Returns “password resets have been disabled....”
1. XML-RPC login
- [ ] Disabled. XT returns “passwords have been disabled....”
#### P2 = “Author”
1. Subscriber role login
- [ ] Log in via PF.
1. Subscriber role reset password
- [ ] LF sends password reset e-mail.
- [ ] Set new password.
1. Contributor role login
- [ ] Log in via PF.
1. Contributor role reset password
- [ ] LF sends password reset e-mail.
- [ ] Set new password.
1. Author role login
- [ ] Log in via PF returns “passwords have been disabled....”
- [ ] Log in via override.
- [ ] Log in via CB.
- [ ] Log out via CA.
1. Author role reset password via LF
- [ ] Disabled. Returns “password resets have been disabled....”
1. Editor role login
- [ ] Log in via PF returns “passwords have been disabled....”
- [ ] Log in via override.
- [ ] Log in via CB.
- [ ] Log out via CA.
1. Editor role reset password via LF
- [ ] Disabled. Returns “password resets have been disabled....”
1. Administrator role login
- [ ] Log in via PF returns “passwords have been disabled....”
- [ ] Log in via override.
- [ ] Log in via CB.
- [ ] Log out via CA.
1. Administrator role reset password via LF
- [ ] Disabled. Returns “password resets have been disabled....”
1. Super Administrator role login
- [ ] Log in via PF returns “passwords have been disabled....”
- [ ] Log in via override.
- [ ] Log in via CB.
- [ ] Log out via CA.
1. Super Administrator role reset password via LF
- [ ] Disabled. Returns “password resets have been disabled....”
1. XML-RPC login
- [ ] Disabled. XT returns “passwords have been disabled....”
#### P2 = “Editor”
1. Subscriber role login
- [ ] Log in via PF.
1. Subscriber role reset password
- [ ] LF sends password reset e-mail.
- [ ] Set new password.
1. Contributor role login
- [ ] Log in via PF.
1. Contributor role reset password
- [ ] LF sends password reset e-mail.
- [ ] Set new password.
1. Author role login
- [ ] Log in via PF.
1. Author role reset password
- [ ] LF sends password reset e-mail.
- [ ] Set new password.
1. Editor role login
- [ ] Log in via PF returns “passwords have been disabled....”
- [ ] Log in via override.
- [ ] Log in via CB.
- [ ] Log out via CA.
1. Editor role reset password via LF
- [ ] Disabled. Returns error notification.
1. Administrator role login
- [ ] Log in via PF returns “passwords have been disabled....”
- [ ] Log in via override.
- [ ] Log in via CB.
- [ ] Log out via CA.
1. Administrator role reset password via LF
- [ ] Disabled. Returns error notification.
1. Super Administrator role login
- [ ] Log in via PF returns “passwords have been disabled....”
- [ ] Log in via override.
- [ ] Log in via CB.
- [ ] Log out via CA.
1. Super Administrator role reset password via LF
- [ ] Disabled. Returns error notification.
1. XML-RPC login
- [ ] Disabled. XT returns “passwords have been disabled....”
#### P2 = “Administrator”
1. Subscriber role login
- [ ] Log in via PF.
1. Subscriber role reset password
- [ ] LF sends password reset e-mail.
- [ ] Set new password.
1. Contributor role login
- [ ] Log in via PF.
1. Contributor role reset password
- [ ] LF sends password reset e-mail.
- [ ] Set new password.
1. Author role login
- [ ] Log in via PF.
1. Author role reset password
- [ ] LF sends password reset e-mail.
- [ ] Set new password.
1. Editor role login
- [ ] Log in via PF.
1. Editor role reset password
- [ ] LF sends password reset e-mail.
- [ ] Set new password.
1. Administrator role login
- [ ] Log in via PF returns “passwords have been disabled....”
- [ ] Log in via override.
- [ ] Log in via CB.
- [ ] Log out via CA.
1. Administrator role reset password via LF
- [ ] Disabled. Returns error notification.
1. Super Administrator role login
- [ ] Log in via PF returns “passwords have been disabled....”
- [ ] Log in via override.
- [ ] Log in via CB.
- [ ] Log out via CA.
1. Super Administrator role reset password via LF
- [ ] Disabled. Returns error notification.
1. XML-RPC login
- [ ] Disabled. XT returns “passwords have been disabled....”
#### P2 = “Super Administrator”
1. Subscriber role login
- [ ] Log in via PF.
1. Subscriber role reset password
- [ ] LF sends password reset e-mail.
- [ ] Set new password.
1. Contributor role login
- [ ] Log in via PF.
1. Contributor role reset password
- [ ] LF sends password reset e-mail.
- [ ] Set new password.
1. Author role login
- [ ] Log in via PF.
1. Author role reset password
- [ ] LF sends password reset e-mail.
- [ ] Set new password.
1. Editor role login
- [ ] Log in via PF.
1. Editor role reset password
- [ ] LF sends password reset e-mail.
- [ ] Set new password.
1. Administrator role login
- [ ] Log in via PF.
1. Administrator role reset password
- [ ] LF sends password reset e-mail.
- [ ] Set new password.
1. Super Administrator role login
- [ ] Log in via PF returns “passwords have been disabled....”
- [ ] Log in via override.
- [ ] Log in via CB.
- [ ] Log out via CA.
1. Super Administrator role reset password via LF
- [ ] Disabled. Returns error notification.
1. XML-RPC login
- [ ] Disabled. XT returns “passwords have been disabled....”
### Disable passwords: set P3 = true, P4 = null.
- [ ] SS fades.
- [ ] P4 appears.
- [ ] Override settings section appears.
- O1 = null.
- O4 = hidden.
- [ ] selecting 02
- shows SS,
- inserts key in O1,
- and shows O4.
- [ ] wp-login.php displays CB only (no PF and no LL).
- [ ] LF disabled for all users. Returns error notification.
- [ ] Log in via override.
- [ ] Log in via CB.
- [ ] Log out via CA.
### Disable passwords: set P4 = true (assumes P1, P2, and/or P3 are not null).
- [ ] SS fades.
- [ ] Log in via XML-RPC. XT returns success notification.
## Support Clef settings
- [ ] Set to “Badge”
- flashes SS
- and prints `img` and functioning `a` in site footer.
- [ ] Set to “Link”
- Flashes SS
- Prints functioning `a` in site footer.
- [ ] Set to “Disabled”
- Flashes SS
- Removes `img` and/or `a` from site footer.
### Support Clef timed pop ups
1. State 1a: after first login via CB.
- [ ] Selecting “Badge” prints `img` and functioning `a` in site footer and saves the setting (verify on setting page).
1. State 1b: after first login via CB.
- [ ] Selecting “Link” prints functioning `a` in site footer and saves the setting (verify on setting page).
1. State 2: Waltz not installed.
- [ ] After 3 successful logins, show numbered badge in Clef settings menu title.
- [ ] After 3 successful logins, show dismissible Waltz notification on Clef settings page.
- [ ] After 15 successful logins, if Clef settings Waltz notification hasn't been dismissed, show a one-time notification on the Dashboard.
1. State 3: Waltz installed.
- [ ] No Waltz notifications after 3 successful logins.
- [ ] No Waltz notification on Dashboard after 15 successful logins.
## Browser Iterations
### Setup Wizard
- [ ] Successful run through in Chrome.
- [ ] Successful run through in FireFox.
- [ ] Successful run through in Safari.
- [ ] Successful run through in IE.
### AJAX-Powered Settings Page
- [ ] Functioning in Chrome.
- [ ] Functioning in FireFox.
- [ ] Functioning in Safari.
- [ ] Functioning in IE.
## Translations
- [ ] All new translatable text blocks placed in appropriate wrapper functions.
## BruteProtect
- [ ] One-click install & activate successful.
## The End
- [ ] To the precious few who make it this far: [treat yo self](http://www.youtube.com/watch?v=-K4if6QkDbo) to a :boom:.

View File

@@ -0,0 +1,77 @@
# [Clef for WordPress](http://wordpress.org/plugins/wpclef/) [![Build Status](https://travis-ci.org/clef/wordpress.svg?branch=master)](https://travis-ci.org/clef/wordpress)
Welcome to the Clef for WordPress development repository!
Clef is the easy, and secure, way to log in to your WordPress sites. With Clef, you get the benefits of single sign on across all of your WordPress sites with the security of 2-factor authentication and public key cryptography — it's the best of both worlds. Replacing passwords, Clef identifies you with your phone — simply wave it in front of your computer and you're instantly logged in.
## Installation
To install the latest stable build of Clef for WordPress, we recommend you download Clef for WordPress directly from the [WordPress plugin repository](http://wordpress.org/plugins/wpclef/).
To install, contribute to, and test the developer build, you should clone this repository.
## Support
For support, we recommend emailing us directly at [support@getclef.com](mailto:support@getclef.com) or joining our [support chat room](http://www.hipchat.com/go5kUkq90).
## Bugs
If you find an issue, let us know in the issues section!
## Translation
If you're interested in contributing to the Clef plugin for WordPress, translating is an easy way to get started. The easiest way to get involved is to [join the Clef organization on Transifex](https://www.transifex.com/projects/p/wpclef/) and choose a new language to translate for. There's an easy online translation manager and you'll be done in no time!
The following users have contributed to translating Clef (if you've contributed and you're not on this list, let us know):
* @music47ell
* @thobu
* @yeltsin
* Andrew Kurtis @ [WebHostingHub](http://www.webhostinghub.com/)
## Contribution Guidelines
From the [Rubinius](http://rubini.us/) contribution page:
> Writing code and participating should be fun, not an exercise in
> perseverance. Stringent commit polices, for whatever their other
> qualities may bring, also mean longer turnaround times.
Submit a patch and once its accepted, youll get commit access to the
repository. Feel free to fork the repository and send a pull request,
once its merged in youll get added. If not, feel free to bug
[jessepollak](http://github.com/jessepollak) about it.
Also, if youre hacking away, hop in the [Clef support room](https://www.hipchat.com/go5kUkq90). Chances are someone else will be around to answer
questions or bounce ideas off of.
How To Contribute
-----------------
* Clone: `git clone git://github.com/clef/wordpress.git`
* Create a topic branch: `git checkout -b awesome_feature`
* Commit away.
* Keep up to date: `git fetch && git rebase origin/master`.
Once youre ready:
* Fork the project on GitHub
* Add your repository as a remote: `git remote add your_remote your_repo`
* Push up your branch: `git push your_remote awesome_feature`
* Create a Pull Request for the topic branch, asking for review.
Once its accepted:
* If you want access to the core repository feel free to ask! Then you
can change origin to point to the Read+Write URL:
```
git remote set-url origin git@github.com:clef/wordpress.git
```
Otherwise, you can continue to hack away in your own fork.
If youre looking for things to hack on, please check
[GitHub Issues](http://github.com/clef/wordpress/issues).
*thanks to [rubygems](https://github.com/rubygems/rubygems.org) for inspiration of our guidelines*

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,207 @@
/******************************
Styles
*********************************/
.clef-badge-prompt {
position: relative;
min-height: 170px; }
.clef-badge-prompt * {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box; }
.clef-badge-prompt .link-fade {
display: none; }
.clef-badge-prompt .dismiss {
position: absolute;
top: 5px;
right: 10px;
font-weight: bold;
color: #AAA;
font-size: 20px; }
.clef-badge-prompt .dismiss:hover {
color: #888; }
.clef-badge {
width: 100%;
text-align: center;
display: inline-block;
margin: 10px auto; }
.clef-badge * {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box; }
.clef-badge.pretty {
display: block;
overflow: hidden;
text-indent: -579px;
height: 50px;
width: 140px;
background: url("https://bit.ly/clef-wordpress-badge");
background-size: 100% 100%;
opacity: .8; }
.clef-badge.pretty:hover {
opacity: 1; }
.clef-login-form .clef-button-container {
width: 188px;
height: 35px;
margin: auto; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword) .clef-login-container .clef-button-container {
margin-bottom: 30px; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword) .clef-login-container .close-overlay, .clef-login-form:not(.login-action-register):not(.login-action-lostpassword) .clef-login-container .overlay-info, .clef-login-form:not(.login-action-register):not(.login-action-lostpassword) .clef-login-container .open-overlay {
display: none; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-hidden:not(.clef-login-form-embed):not(.clef-override-or-invite) #login form#loginform {
padding: 40px 20px; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-hidden:not(.clef-login-form-embed):not(.clef-override-or-invite) #login form#loginform input, .clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-hidden:not(.clef-login-form-embed):not(.clef-override-or-invite) #login form#loginform label {
display: none; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password):not(.interim-login) #login {
padding-top: 50px; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) #login {
width: 400px;
max-width: 100%;
margin: auto; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) #login input, .clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) #login label {
visibility: hidden; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) #login form {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
height: 520px;
position: relative !important; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) #login .clef-embed-wrapper {
margin: auto !important; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) .clef-login-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: white;
overflow: visible; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) .clef-login-container .clef-button-container {
padding-top: 5px; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password):not(.clef-closed) p#nav {
display: none; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password).clef-closed #login {
width: 320px; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password).clef-closed #login input, .clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password).clef-closed #login label {
visibility: visible; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password).clef-closed #login form {
height: auto; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password).clef-closed .clef-login-container {
height: 25px;
top: auto;
bottom: 0; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password).clef-closed .clef-button-container {
display: none; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password).clef-closed .overlay-info, .clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password).clef-closed .close-overlay {
display: none; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password).clef-closed .open-overlay {
display: block;
margin: 0; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) .clef-button-container {
margin: 0 auto;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) .clef-button-container .spinner-container {
display: none;
text-align: center;
position: absolute;
top: 175px;
left: 0;
width: 100%;
height: 100%; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) .clef-button-container .spinner-container .spinner {
margin-top: 25px;
display: inline-block;
float: none;
width: 50px;
height: 50px;
background-image: url(../img/loading.gif);
background-size: 100%;
background-position: center;
background-repeat: no-repeat; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) .overlay-text {
position: absolute;
width: 100%;
bottom: 12px;
margin-top: 5px;
text-align: center;
display: block;
color: #aaa;
cursor: pointer;
text-decoration: none; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) .overlay-text:hover {
color: #999; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) .overlay-text:active {
outline: none; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) .or-container, .clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) .open-overlay {
display: none; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) .overlay-info {
display: block;
position: absolute;
bottom: 10px;
left: 0; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) .overlay-info .info {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 90%;
margin: auto;
border: 1px solid #eee;
padding: 10px;
background: white;
color: #999; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) .overlay-info .info p {
font-size: 11px;
line-height: 15px; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) .overlay-info .info p a {
color: #999; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) .overlay-info .info p:not(:last-child) {
margin-bottom: 5px !important; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) .overlay-info .open {
height: 15px;
width: 15px;
font-size: 10px;
text-align: center;
line-height: 15px;
border-radius: 15px;
color: #ccc;
border: 1px solid #ccc;
cursor: pointer;
margin-left: 10px;
display: none; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) .overlay-info .open:hover {
color: #b3b3b3;
border-color: #b3b3b3; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) .overlay-info.closed .info {
display: none; }
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite):not(.clef-auto-connect-account):not(.clef-show-username-password) .overlay-info.closed .open {
display: block; }
@media screen and (max-width: 400px) {
.clef-login-form:not(.login-action-register):not(.login-action-lostpassword).clef-login-form-embed:not(.clef-override-or-invite) #login {
width: 320px;
padding: 0; } }
.login-action-register.clef-login-form .clef-register-container {
padding-top: 20px; }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 915 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View File

@@ -0,0 +1,42 @@
(function($) {
return $(document).ready(function() {
var $prompt, ajaxData, sending;
$prompt = $(".clef-badge-prompt");
ajaxData = {
action: "clef_badge_prompt"
};
sending = false;
$prompt.find(".add-badge").click(function(e) {
var data;
e.preventDefault();
if (sending) {
return;
}
sending = true;
data = {};
$prompt.find('input').each(function() {
return data[$(this).attr('name')] = $(this).val();
});
data.enable = 'badge';
$.extend(data, ajaxData);
$prompt.slideUp();
return $.post(ajaxurl, data, (function() {}), "json");
});
return $prompt.find(".no-badge, .dismiss").click(function(e) {
var data;
e.preventDefault();
if (sending) {
return;
}
sending = true;
data = {};
$prompt.find('input').each(function() {
return data[$(this).attr('name')] = $(this).val();
});
data.disable = true;
$.extend(data, ajaxData);
$.post(ajaxurl, data, (function() {}), "json");
return $prompt.slideUp();
});
});
}).call(this, jQuery);

View File

@@ -0,0 +1,4 @@
/*! Clef for WordPress - v2.3.0
* http://getclef.com
* Licensed GPLv2+ */
(function(n){return n(document).ready(function(){var t,e,i;return t=n(".clef-badge-prompt"),e={action:"clef_badge_prompt"},i=!1,t.find(".add-badge").click(function(a){var r;return a.preventDefault(),i?void 0:(i=!0,r={},t.find("input").each(function(){return r[n(this).attr("name")]=n(this).val()}),r.enable="badge",n.extend(r,e),t.slideUp(),n.post(ajaxurl,r,function(){},"json"))}),t.find(".no-badge, .dismiss").click(function(a){var r;return a.preventDefault(),i?void 0:(i=!0,r={},t.find("input").each(function(){return r[n(this).attr("name")]=n(this).val()}),r.disable=!0,n.extend(r,e),n.post(ajaxurl,r,function(){},"json"),t.slideUp())})})}).call(this,jQuery);

View File

@@ -0,0 +1,9 @@
jQuery(document).ready(function() {
if (wp.heartbeat) {
wp.heartbeat.interval("fast");
wp.heartbeat.enqueue("clef", "cleflogout", true);
return jQuery(document).on("heartbeat-tick", function(e, data) {
return wp.heartbeat.enqueue("clef", "cleflogout", true);
});
}
});

View File

@@ -0,0 +1,4 @@
/*! Clef for WordPress - v2.3.0
* http://getclef.com
* Licensed GPLv2+ */
jQuery(document).ready(function(){return wp.heartbeat?(wp.heartbeat.interval("fast"),wp.heartbeat.enqueue("clef","cleflogout",!0),jQuery(document).on("heartbeat-tick",function(e,t){return wp.heartbeat.enqueue("clef","cleflogout",!0)})):void 0});

View File

@@ -0,0 +1,367 @@
(function($, Backbone) {
var Utils;
Utils = (function() {
function Utils() {}
Utils.getErrorMessage = function(data) {
if (data.error) {
return data.error;
} else if (data.data && data.data.error) {
return data.data.error;
}
return data;
};
Utils.getURLParams = function() {
var key, params, query, raw_vars, v, val, _i, _len, _ref;
query = window.location.search.substring(1);
raw_vars = query.split("&");
params = {};
for (_i = 0, _len = raw_vars.length; _i < _len; _i++) {
v = raw_vars[_i];
_ref = v.split("="), key = _ref[0], val = _ref[1];
params[key] = decodeURIComponent(val);
}
return params;
};
return Utils;
})();
return window.ClefUtils = Utils;
}).call(this, jQuery, Backbone);
(function($, Backbone) {
var ConnectTutorialView, SetupTutorialView, SubTutorialView, TutorialView;
TutorialView = Backbone.View.extend({
el: $('#clef-tutorial'),
messageTemplate: _.template("<div class='<%=type%> tutorial-message'><%=message%></div>"),
events: {
"click .next": "next",
"click .previous": "previous",
"click .done": "done"
},
slideClass: 'sub',
initialize: function(opts) {
var potentialSubs, sub, _i, _len;
this.opts = opts;
if (window.chrome && !window.waltzIsInstalled) {
this.$el.find('.waltz').addClass(this.slideClass);
this.$el.addClass('.no-waltz');
}
this.subs = [];
potentialSubs = this.$el.find("." + this.slideClass).filter(this.opts.slideFilterSelector);
for (_i = 0, _len = potentialSubs.length; _i < _len; _i++) {
sub = potentialSubs[_i];
this.subs.push(new SubTutorialView({
el: sub
}));
}
this.currentSub = this.subs[0];
$(window).on('message', this.handleMessages.bind(this));
this.hide();
return this.render();
},
slideUp: function(cb) {
return this.$el.slideUp(cb);
},
hide: function(cb) {
return this.$el.hide(cb);
},
show: function() {
return this.$el.fadeIn();
},
render: function() {
return this.currentSub.render();
},
done: function() {
return this.trigger("done");
},
next: function() {
var newSub;
newSub = this.subs[_.indexOf(this.subs, this.currentSub) + 1];
if (newSub) {
if (newSub.isLogin() && this.loggedIn) {
newSub = this.subs[_.indexOf(this.subs, this.newSub) + 1];
}
this.currentSub.hide();
newSub.render();
this.currentSub = newSub;
return this.trigger("next");
} else {
return this.done();
}
},
previous: function() {
var newSub;
newSub = this.subs[_.indexOf(this.subs, this.currentSub) - 1];
if (newSub) {
this.currentSub.hide();
newSub.render();
return this.currentSub = newSub;
}
},
handleMessages: function(e) {
var data;
if (!(e.originalEvent.origin.indexOf(this.opts.clefBase) >= 0)) {
return;
}
data = e.originalEvent.data;
if (typeof data === "string") {
data = JSON.parse(data);
}
return data;
},
connectClefAccount: function(data, cb) {
var connectData, failure;
connectData = {
_wpnonce: this.opts.nonces.connectClef,
identifier: data.identifier,
state: data.state
};
failure = (function(_this) {
return function(msg) {
return _this.showMessage({
message: _.template(clefTranslations.messages.error.connect)({
error: msg
}),
type: "error"
});
};
})(this);
return $.post(this.connectClefAction, connectData).success(function(data) {
if (data.success) {
if (typeof cb === "function") {
return cb(data);
}
} else {
return failure(ClefUtils.getErrorMessage(data));
}
}).fail(function(res) {
return failure(res.responseText);
});
},
showMessage: function(opts) {
if (this.$currentMessage) {
this.$currentMessage.remove();
}
this.$currentMessage = $(this.messageTemplate(opts)).hide().prependTo(this.$el).slideDown();
if (opts.removeNext) {
return this.listenToOnce(this, "next", function() {
return this.$currentMessage.slideUp();
});
}
}
}, {
extend: Backbone.View.extend
});
SubTutorialView = Backbone.View.extend({
initialize: function(opts) {
this.opts = opts;
return this.setElement($(this.opts.el));
},
render: function() {
return this.$el.show();
},
hide: function() {
return this.$el.hide();
},
remove: function() {
return this.$el.remove();
},
find: function(query) {
return this.$el.find(query);
},
isLogin: function() {
return this.$el.find('iframe.setup').length;
},
isSync: function() {
return this.$el.hasClass('sync') && this.$el.find('iframe').length;
}
});
SetupTutorialView = TutorialView.extend({
connectClefAction: ajaxurl + "?action=connect_clef_account_clef_id",
iframePath: '/iframes/application/create/v2',
initialize: function(opts) {
opts.slideFilterSelector = '.setup';
this.inviter = new InviteUsersView(_.extend({
el: this.$el.find('.invite-users-container')
}, opts));
this.listenTo(this.inviter, "invited", this.usersInvited);
this.constructor.__super__.initialize.call(this, opts);
return this.on('next', this.shouldLoadIFrame);
},
render: function() {
this.inviter.render();
return this.constructor.__super__.render.call(this);
},
shouldLoadIFrame: function() {
if (this.currentSub.isSync()) {
return this.loadIFrame((function(_this) {
return function() {
_this.currentSub.find('.spinner-container').hide();
return _this.iframe.fadeIn();
};
})(this));
}
},
loadIFrame: function(cb) {
var affiliates, src;
if (this.iframe) {
return;
}
this.iframe = this.$el.find("iframe.setup");
affiliates = encodeURIComponent(this.opts.setup.affiliates.join(','));
src = "" + this.opts.clefBase + this.iframePath + "?source=" + (encodeURIComponent(this.opts.setup.source)) + "&domain=" + (encodeURIComponent(this.opts.setup.siteDomain)) + "&logout_hook=" + (encodeURIComponent(this.opts.setup.logoutHook)) + "&name=" + (encodeURIComponent(this.opts.setup.siteName)) + "&affiliates=" + affiliates;
this.iframe.attr('src', src);
return this.iframe.on('load', cb);
},
handleMessages: function(data) {
data = this.constructor.__super__.handleMessages.call(this, data);
if (!data) {
return;
}
if (data.type === "keys") {
return this.connectClefAccount({
identifier: data.clefID
}, (function(_this) {
return function() {
_this.trigger('applicationCreated', data);
_this.next();
return _this.showMessage({
message: clefTranslations.messages.success.connect,
type: "updated",
removeNext: true
});
};
})(this));
} else if (data.type === "error") {
return this.showMessage({
message: _.template(clefTranslations.messages.error.create)({
error: data.message
}),
type: 'error'
});
}
},
onConfigured: function() {
return setTimeout((function() {
return $(".logout-hook-error").slideDown();
}), 20000);
},
usersInvited: function() {
this.inviter.hideButton();
return setTimeout(((function(_this) {
return function() {
if (_this.currentSub.$el.hasClass('invite')) {
return _this.currentSub.$el.find('.button').addClass('button-primary');
}
};
})(this)), 1000);
}
});
ConnectTutorialView = TutorialView.extend({
connectClefAction: ajaxurl + "?action=connect_clef_account_oauth_code",
render: function() {
this.addButton();
return this.constructor.__super__.render.call(this);
},
addButton: function() {
var redirectURL, target;
if (this.button) {
return;
}
redirectURL = window.location.href;
if (/\?/.test(redirectURL)) {
redirectURL += "&connect_clef_account=1";
} else {
redirectURL += "?connect_clef_account=1";
}
target = $('#clef-button-target').attr('data-app-id', this.opts.appID).attr('data-redirect-url', redirectURL).attr('data-state', this.opts.state);
this.button = new ClefButton({
el: $('#clef-button-target')[0]
});
return this.button.render();
}
});
this.TutorialView = TutorialView;
this.SetupTutorialView = SetupTutorialView;
return this.ConnectTutorialView = ConnectTutorialView;
}).call(this, jQuery, Backbone);
(function($, Backbone) {
var ConnectView;
ConnectView = Backbone.View.extend({
el: "#connect-clef-account",
events: {
"click #disconnect": "disconnectClefAccount"
},
disconnectURL: ajaxurl + "?action=disconnect_clef_account",
messageTemplate: _.template("<div class='<%=type%> connect-clef-message'><%=message%></div>"),
initialize: function(opts) {
this.opts = opts;
this.tutorial = new ConnectTutorialView(_.clone(this.opts));
this.disconnect = this.$el.find('.disconnect-clef');
this.listenTo(this.tutorial, 'done', this.finishTutorial);
return this.render();
},
show: function() {
return this.$el.fadeIn();
},
render: function() {
this.tutorial.render();
if (!this.opts.connected) {
this.disconnect.hide();
return this.tutorial.show();
} else {
this.tutorial.slideUp();
return this.disconnect.show();
}
},
disconnectClefAccount: function(e) {
var failure;
e.preventDefault();
failure = (function(_this) {
return function(msg) {
return _this.showMessage({
message: _.template(clefTranslations.messages.error.disconnect)({
error: msg
}),
type: "error"
});
};
})(this);
return $.post(this.disconnectURL, {
_wpnonce: this.opts.nonces.disconnectClef
}).success((function(_this) {
return function(data) {
var msg;
if (data.success) {
_this.opts.connected = false;
_this.render();
msg = clefTranslations.messages.success.disconnect;
return _this.showMessage({
message: msg,
type: "updated"
});
} else {
return failure(ClefUtils.getErrorMessage(data));
}
};
})(this)).fail(function(res) {
return failure(res.responseText);
});
},
showMessage: function(data) {
if (this.message) {
this.message.remove();
}
this.message = $(this.messageTemplate(data)).hide();
return this.message.prependTo(this.$el).slideDown();
},
finishTutorial: function() {
return window.location = '';
}
});
return window.ConnectView = ConnectView;
}).call(this, jQuery, Backbone);

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,34 @@
(function($) {
var closeOverlay, openOverlay;
closeOverlay = function() {
$('.clef-login-form.clef-login-form-embed').addClass('clef-closed');
return false;
};
openOverlay = function(e) {
$('.clef-login-form.clef-login-form-embed').removeClass('clef-closed');
return false;
};
return $(function() {
var $embedContainer, $iframe, $spinnerContainer;
$embedContainer = $('.clef-embed-container');
$('.close-overlay').click(closeOverlay);
$('.open-overlay').click(openOverlay);
$('.overlay-info .open').click(function() {
return $('.overlay-info').removeClass('closed');
});
if ($embedContainer.length) {
$spinnerContainer = $('.spinner-container');
$iframe = $embedContainer.find('iframe');
$iframe.load(function() {
$spinnerContainer.hide();
return setTimeout(function() {
return $embedContainer.slideDown();
});
});
if (!$iframe.attr('data-loaded')) {
$embedContainer.hide();
return $spinnerContainer.show();
}
}
});
}).call(this, jQuery);

View File

@@ -0,0 +1,4 @@
/*! Clef for WordPress - v2.3.0
* http://getclef.com
* Licensed GPLv2+ */
(function(e){var n,o;return n=function(){return e(".clef-login-form.clef-login-form-embed").addClass("clef-closed"),!1},o=function(n){return e(".clef-login-form.clef-login-form-embed").removeClass("clef-closed"),!1},e(function(){var r,l,c;return r=e(".clef-embed-container"),e(".close-overlay").click(n),e(".open-overlay").click(o),e(".overlay-info .open").click(function(){return e(".overlay-info").removeClass("closed")}),r.length&&(c=e(".spinner-container"),l=r.find("iframe"),l.load(function(){return c.hide(),setTimeout(function(){return r.slideDown()})}),!l.attr("data-loaded"))?(r.hide(),c.show()):void 0})}).call(this,jQuery);

View File

@@ -0,0 +1,808 @@
(function($, Backbone) {
var Utils;
Utils = (function() {
function Utils() {}
Utils.getErrorMessage = function(data) {
if (data.error) {
return data.error;
} else if (data.data && data.data.error) {
return data.data.error;
}
return data;
};
Utils.getURLParams = function() {
var key, params, query, raw_vars, v, val, _i, _len, _ref;
query = window.location.search.substring(1);
raw_vars = query.split("&");
params = {};
for (_i = 0, _len = raw_vars.length; _i < _len; _i++) {
v = raw_vars[_i];
_ref = v.split("="), key = _ref[0], val = _ref[1];
params[key] = decodeURIComponent(val);
}
return params;
};
return Utils;
})();
return window.ClefUtils = Utils;
}).call(this, jQuery, Backbone);
(function($, Backbone) {
var InviteUsersView;
InviteUsersView = Backbone.View.extend({
el: '#invite-users-settings',
events: {
"click a[name='invite-users-button']": 'inviteUsers'
},
messageTemplate: _.template("<div class='<%=type%> invite-users-message'><%=message%></div>"),
showMessage: function(data) {
var $messageEl;
$messageEl = this.$el.find('.invite-users-message');
if ($messageEl.length) {
$messageEl.remove();
}
return this.$el.find('.button').first().before(this.messageTemplate(data));
},
template: function() {
return _.template($('#invite-users-template').html());
},
initialize: function(opts) {
this.opts = opts;
if (this.opts.el) {
return this.setElement(this.opts.el);
}
},
inviteUsersAction: ajaxurl + "?action=clef_invite_users",
inviteUsers: function(e) {
var data, failure;
e.preventDefault();
data = {
_wpnonce: this.opts.nonces.inviteUsers,
roles: $("select[name='invite-users-role']").val(),
networkAdmin: this.opts.isNetworkSettings
};
failure = (function(_this) {
return function(msg) {
return _this.showMessage({
message: _.template(clefTranslations.messages.error.invite)({
error: msg
}),
type: "error"
});
};
})(this);
return $.post(this.inviteUsersAction, data).success((function(_this) {
return function(data) {
if (data.success) {
_this.trigger("invited");
return _this.showMessage({
message: clefTranslations.messages.success.invite,
type: "updated"
});
} else {
return failure(ClefUtils.getErrorMessage(data));
}
};
})(this)).fail(function(res) {
return failure(res.responseText);
});
},
hideButton: function() {
return this.$el.find('.button').hide();
},
render: function() {
return this.$el.html(this.template);
}
});
return this.InviteUsersView = InviteUsersView;
}).call(this, jQuery, Backbone);
(function($) {
var MultisiteOptionsModel, MultisiteOptionsView;
MultisiteOptionsView = AjaxSettingsView.extend({
el: '#multisite-settings',
initialize: function(opts) {
this.modelClass = MultisiteOptionsModel;
return MultisiteOptionsView.__super__.initialize.call(this, opts);
}
});
MultisiteOptionsModel = AjaxSettingsModel.extend({
parse: function(data, options) {
options.url = ajaxurl + '?action=clef_multisite_settings';
return MultisiteOptionsModel.__super__.parse.call(this, data, options);
}
});
this.MultisiteOptionsModel = MultisiteOptionsModel;
return this.MultisiteOptionsView = MultisiteOptionsView;
}).call(this, jQuery);
(function($, Backbone) {
var ConnectTutorialView, SetupTutorialView, SubTutorialView, TutorialView;
TutorialView = Backbone.View.extend({
el: $('#clef-tutorial'),
messageTemplate: _.template("<div class='<%=type%> tutorial-message'><%=message%></div>"),
events: {
"click .next": "next",
"click .previous": "previous",
"click .done": "done"
},
slideClass: 'sub',
initialize: function(opts) {
var potentialSubs, sub, _i, _len;
this.opts = opts;
if (window.chrome && !window.waltzIsInstalled) {
this.$el.find('.waltz').addClass(this.slideClass);
this.$el.addClass('.no-waltz');
}
this.subs = [];
potentialSubs = this.$el.find("." + this.slideClass).filter(this.opts.slideFilterSelector);
for (_i = 0, _len = potentialSubs.length; _i < _len; _i++) {
sub = potentialSubs[_i];
this.subs.push(new SubTutorialView({
el: sub
}));
}
this.currentSub = this.subs[0];
$(window).on('message', this.handleMessages.bind(this));
this.hide();
return this.render();
},
slideUp: function(cb) {
return this.$el.slideUp(cb);
},
hide: function(cb) {
return this.$el.hide(cb);
},
show: function() {
return this.$el.fadeIn();
},
render: function() {
return this.currentSub.render();
},
done: function() {
return this.trigger("done");
},
next: function() {
var newSub;
newSub = this.subs[_.indexOf(this.subs, this.currentSub) + 1];
if (newSub) {
if (newSub.isLogin() && this.loggedIn) {
newSub = this.subs[_.indexOf(this.subs, this.newSub) + 1];
}
this.currentSub.hide();
newSub.render();
this.currentSub = newSub;
return this.trigger("next");
} else {
return this.done();
}
},
previous: function() {
var newSub;
newSub = this.subs[_.indexOf(this.subs, this.currentSub) - 1];
if (newSub) {
this.currentSub.hide();
newSub.render();
return this.currentSub = newSub;
}
},
handleMessages: function(e) {
var data;
if (!(e.originalEvent.origin.indexOf(this.opts.clefBase) >= 0)) {
return;
}
data = e.originalEvent.data;
if (typeof data === "string") {
data = JSON.parse(data);
}
return data;
},
connectClefAccount: function(data, cb) {
var connectData, failure;
connectData = {
_wpnonce: this.opts.nonces.connectClef,
identifier: data.identifier,
state: data.state
};
failure = (function(_this) {
return function(msg) {
return _this.showMessage({
message: _.template(clefTranslations.messages.error.connect)({
error: msg
}),
type: "error"
});
};
})(this);
return $.post(this.connectClefAction, connectData).success(function(data) {
if (data.success) {
if (typeof cb === "function") {
return cb(data);
}
} else {
return failure(ClefUtils.getErrorMessage(data));
}
}).fail(function(res) {
return failure(res.responseText);
});
},
showMessage: function(opts) {
if (this.$currentMessage) {
this.$currentMessage.remove();
}
this.$currentMessage = $(this.messageTemplate(opts)).hide().prependTo(this.$el).slideDown();
if (opts.removeNext) {
return this.listenToOnce(this, "next", function() {
return this.$currentMessage.slideUp();
});
}
}
}, {
extend: Backbone.View.extend
});
SubTutorialView = Backbone.View.extend({
initialize: function(opts) {
this.opts = opts;
return this.setElement($(this.opts.el));
},
render: function() {
return this.$el.show();
},
hide: function() {
return this.$el.hide();
},
remove: function() {
return this.$el.remove();
},
find: function(query) {
return this.$el.find(query);
},
isLogin: function() {
return this.$el.find('iframe.setup').length;
},
isSync: function() {
return this.$el.hasClass('sync') && this.$el.find('iframe').length;
}
});
SetupTutorialView = TutorialView.extend({
connectClefAction: ajaxurl + "?action=connect_clef_account_clef_id",
iframePath: '/iframes/application/create/v2',
initialize: function(opts) {
opts.slideFilterSelector = '.setup';
this.inviter = new InviteUsersView(_.extend({
el: this.$el.find('.invite-users-container')
}, opts));
this.listenTo(this.inviter, "invited", this.usersInvited);
this.constructor.__super__.initialize.call(this, opts);
return this.on('next', this.shouldLoadIFrame);
},
render: function() {
this.inviter.render();
return this.constructor.__super__.render.call(this);
},
shouldLoadIFrame: function() {
if (this.currentSub.isSync()) {
return this.loadIFrame((function(_this) {
return function() {
_this.currentSub.find('.spinner-container').hide();
return _this.iframe.fadeIn();
};
})(this));
}
},
loadIFrame: function(cb) {
var affiliates, src;
if (this.iframe) {
return;
}
this.iframe = this.$el.find("iframe.setup");
affiliates = encodeURIComponent(this.opts.setup.affiliates.join(','));
src = "" + this.opts.clefBase + this.iframePath + "?source=" + (encodeURIComponent(this.opts.setup.source)) + "&domain=" + (encodeURIComponent(this.opts.setup.siteDomain)) + "&logout_hook=" + (encodeURIComponent(this.opts.setup.logoutHook)) + "&name=" + (encodeURIComponent(this.opts.setup.siteName)) + "&affiliates=" + affiliates;
this.iframe.attr('src', src);
return this.iframe.on('load', cb);
},
handleMessages: function(data) {
data = this.constructor.__super__.handleMessages.call(this, data);
if (!data) {
return;
}
if (data.type === "keys") {
return this.connectClefAccount({
identifier: data.clefID
}, (function(_this) {
return function() {
_this.trigger('applicationCreated', data);
_this.next();
return _this.showMessage({
message: clefTranslations.messages.success.connect,
type: "updated",
removeNext: true
});
};
})(this));
} else if (data.type === "error") {
return this.showMessage({
message: _.template(clefTranslations.messages.error.create)({
error: data.message
}),
type: 'error'
});
}
},
onConfigured: function() {
return setTimeout((function() {
return $(".logout-hook-error").slideDown();
}), 20000);
},
usersInvited: function() {
this.inviter.hideButton();
return setTimeout(((function(_this) {
return function() {
if (_this.currentSub.$el.hasClass('invite')) {
return _this.currentSub.$el.find('.button').addClass('button-primary');
}
};
})(this)), 1000);
}
});
ConnectTutorialView = TutorialView.extend({
connectClefAction: ajaxurl + "?action=connect_clef_account_oauth_code",
render: function() {
this.addButton();
return this.constructor.__super__.render.call(this);
},
addButton: function() {
var redirectURL, target;
if (this.button) {
return;
}
redirectURL = window.location.href;
if (/\?/.test(redirectURL)) {
redirectURL += "&connect_clef_account=1";
} else {
redirectURL += "?connect_clef_account=1";
}
target = $('#clef-button-target').attr('data-app-id', this.opts.appID).attr('data-redirect-url', redirectURL).attr('data-state', this.opts.state);
this.button = new ClefButton({
el: $('#clef-button-target')[0]
});
return this.button.render();
}
});
this.TutorialView = TutorialView;
this.SetupTutorialView = SetupTutorialView;
return this.ConnectTutorialView = ConnectTutorialView;
}).call(this, jQuery, Backbone);
(function($) {
var AppView, FormVisualization, SettingsModel, SettingsView;
AppView = Backbone.View.extend({
el: $('#clef-settings-container'),
initialize: function(opts) {
this.opts = opts;
this.$msgContainer = this.$el.find('.message');
this.settings = new SettingsView(_.extend({
options_name: "wpclef"
}, this.opts));
this.settings.hide();
if (!this.settings.isConfigured()) {
this.tutorial = new SetupTutorialView(_.extend({}, this.opts));
this.tutorial.hide();
this.listenTo(this.tutorial, 'message', this.displayMessage);
}
if (this.opts.isNetworkSettings) {
delete this.opts['formSelector'];
this.multisiteOptionsView = new MultisiteOptionsView(this.opts);
}
this.listenTo(this.settings, 'message', this.displayMessage);
return this.render();
},
render: function() {
if (this.opts.isUsingIndividualSettings || (this.opts.isNetworkSettings && this.opts.isNetworkSettingsEnabled)) {
if (this.multisiteOptionsView) {
this.multisiteOptionsView.show();
}
if (this.settings.isConfigured()) {
this.settings.show();
} else {
this.tutorial.show();
this.listenToOnce(this.tutorial, 'applicationCreated', this.configure);
this.listenToOnce(this.tutorial, 'done', this.hideTutorial);
}
}
return this.$el.fadeIn();
},
configure: function(data) {
this.settings.model.configure(data);
return this.settings.render();
},
displayMessage: function(opts) {
this.$msgContainer.find('p').text(opts.message);
this.$msgContainer.addClass(opts.type).slideDown();
if (opts.fade) {
return setTimeout((function() {
return this.$msgContainer.slideUp();
}), 3000);
}
},
hideTutorial: function() {
if (this.settings.isConfigured()) {
this.displayMessage(clefTranslations.messages.success.configured);
({
type: "updated"
});
}
this.tutorial.slideUp();
return this.settings.show();
}
});
SettingsView = AjaxSettingsView.extend({
errorTemplate: _.template("<div class='error form-error'><%=message%></div>"),
genericErrorMessage: clefTranslations.messages.error.generic,
addEvents: {
"click .generate-override": "generateOverride",
"click input[type='submit']:not(.ajax-ignore)": "saveForm",
"click a.show-support-html": "showSupportHTML"
},
constructor: function(opts) {
this.events = _.extend(this.events, this.addEvents);
return SettingsView.__super__.constructor.call(this, opts);
},
initialize: function(opts) {
this.opts = opts;
this.modelClass = SettingsModel;
SettingsView.__super__.initialize.call(this, opts);
this.pro = new ClefProView(opts, this.model);
this.inviteUsersView = new InviteUsersView(opts);
this.formView = new FormVisualization({
model: this.model
});
this.xmlEl = this.model.cFindInput('clef_password_settings_xml_allowed').parents('.input-container');
this.overrideContainer = this.$el.find('.override-settings');
this.setOverrideLink();
this.badgePreviewContainer = this.$el.find('.support-settings .ftr-preview');
this.listenTo(this.model, "change", this.clearErrors);
this.listenTo(this.model, "error", this.error);
window.onbeforeunload = (function(_this) {
return function(e) {
if (_this.isSaving()) {
return clefTranslations.messages.saving;
}
};
})(this);
return this.render();
},
updated: function(obj, data) {
SettingsView.__super__.updated.call(this, obj, data);
return this.setOverrideLink();
},
render: function() {
var passwordsDisabled;
SettingsView.__super__.render.call(this);
passwordsDisabled = this.model.passwordsDisabled();
$('#clef-settings-header').show();
this.xmlEl.toggle(passwordsDisabled);
this.toggleOverrideContainer(passwordsDisabled);
this.overrideContainer.toggleClass('set', this.model.overrideIsSet());
this.inviteUsersView.render();
return this.renderSupportBadge();
},
toggleInputs: function(e) {
return this.formView.toggleForm(!!parseInt(e.currentTarget.value));
},
toggleOverrideContainer: function(show) {
return this.overrideContainer.toggle(show);
},
generateOverride: function() {
var rnd;
rnd = Math.random().toString(36).slice(2);
return this.model.save({
'wpclef[clef_override_settings_key]': rnd
});
},
setOverrideLink: function() {
var button, key;
key = this.model.overrideKey();
if (!key) {
return;
}
if (!this.overrideBase) {
this.overrideBase = this.overrideContainer.find('label').text();
}
button = this.overrideContainer.find('a.button');
button.on('click', function(e) {
return e.preventDefault();
});
return button.attr('href', this.overrideBase + key);
},
isSaving: function() {
return this.model.saving;
},
renderSupportBadge: function() {
var setting;
setting = this.model.badgeSetting();
this.badgePreviewContainer.toggle(setting !== "disabled");
return this.badgePreviewContainer.find('a').toggleClass('pretty', setting === "badge");
},
isConfigured: function() {
return this.model.isConfigured();
},
saveForm: function(e) {
e.preventDefault();
return this.model.save({}, {
success: (function(_this) {
return function() {
_this.trigger('message', {
message: "Settings saved.",
type: 'updated'
});
return $('html, body').animate({
scrollTop: 0
}, "slow");
};
})(this),
error: this.model.saveError.bind(this.model)
});
},
showSupportHTML: function(e) {
e.preventDefault();
return $('.support-html-container').slideDown();
}
});
SettingsModel = AjaxSettingsModel.extend({
cFindInput: function(name) {
return this.findInput("wpclef[" + name + "]");
},
cget: function(key) {
return this.get("wpclef[" + key + "]");
},
passwordsDisabled: function() {
return !!parseInt(this.cget('clef_password_settings_disable_passwords')) || this.cget('clef_password_settings_disable_certain_passwords') !== "" || this.passwordsFullyDisabled();
},
passwordsFullyDisabled: function() {
return !!parseInt(this.cget('clef_password_settings_force'));
},
loginIsEmbedded: function() {
return !!parseInt(this.cget('clef_form_settings_embed_clef'));
},
overrideIsSet: function() {
return !!this.overrideKey();
},
overrideKey: function() {
return this.cget('clef_override_settings_key');
},
badgeSetting: function() {
return this.cget('support_clef_badge').toLowerCase();
},
isConfigured: function() {
return !!(this.cget('clef_settings_app_id') && this.cget('clef_settings_app_secret'));
},
configure: function(data) {
var k, toSave, v, _ref;
toSave = {
'wpclef[clef_settings_app_id]': data.appID,
'wpclef[clef_settings_app_secret]': data.appSecret
};
if (data.configuration) {
_ref = data.configuration;
for (k in _ref) {
v = _ref[k];
toSave["wpclef[" + k + "]"] = v;
}
}
return this.save(toSave);
}
});
FormVisualization = Backbone.View.extend({
el: $("#login-form-view"),
template: function() {
return _.template($('#form-template').html());
},
initialize: function(opts) {
this.opts = opts;
this.model = this.opts.model;
this.listenTo(this.model, 'change', this.toggleForm);
return this.render();
},
render: function() {
this.$el.html(this.template);
this.$el.find('input[type="submit"]').on('click', function(e) {
return e.preventDefault();
});
return this.toggleForm();
},
toggleForm: function(e) {
this.$el.toggleClass('only-clef', this.model.passwordsFullyDisabled());
return this.$el.toggleClass('embed-clef', this.model.loginIsEmbedded());
}
});
this.AppView = AppView;
return $.fn.serializeObject = function(form) {
var obj, serialized, _i, _len, _ref;
serialized = {};
_ref = $(this).serializeArray();
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
obj = _ref[_i];
serialized[obj.name] = obj.value;
}
return serialized;
};
}).call(this, jQuery);
(function($, Backbone) {
var ConnectView;
ConnectView = Backbone.View.extend({
el: "#connect-clef-account",
events: {
"click #disconnect": "disconnectClefAccount"
},
disconnectURL: ajaxurl + "?action=disconnect_clef_account",
messageTemplate: _.template("<div class='<%=type%> connect-clef-message'><%=message%></div>"),
initialize: function(opts) {
this.opts = opts;
this.tutorial = new ConnectTutorialView(_.clone(this.opts));
this.disconnect = this.$el.find('.disconnect-clef');
this.listenTo(this.tutorial, 'done', this.finishTutorial);
return this.render();
},
show: function() {
return this.$el.fadeIn();
},
render: function() {
this.tutorial.render();
if (!this.opts.connected) {
this.disconnect.hide();
return this.tutorial.show();
} else {
this.tutorial.slideUp();
return this.disconnect.show();
}
},
disconnectClefAccount: function(e) {
var failure;
e.preventDefault();
failure = (function(_this) {
return function(msg) {
return _this.showMessage({
message: _.template(clefTranslations.messages.error.disconnect)({
error: msg
}),
type: "error"
});
};
})(this);
return $.post(this.disconnectURL, {
_wpnonce: this.opts.nonces.disconnectClef
}).success((function(_this) {
return function(data) {
var msg;
if (data.success) {
_this.opts.connected = false;
_this.render();
msg = clefTranslations.messages.success.disconnect;
return _this.showMessage({
message: msg,
type: "updated"
});
} else {
return failure(ClefUtils.getErrorMessage(data));
}
};
})(this)).fail(function(res) {
return failure(res.responseText);
});
},
showMessage: function(data) {
if (this.message) {
this.message.remove();
}
this.message = $(this.messageTemplate(data)).hide();
return this.message.prependTo(this.$el).slideDown();
},
finishTutorial: function() {
return window.location = '';
}
});
return window.ConnectView = ConnectView;
}).call(this, jQuery, Backbone);
var __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
(function($, Backbone) {
var CustomizationView, ProView;
ProView = Backbone.View.extend({
el: '#clef-pro-section',
getServicesURL: ajaxurl + '?action=clef_get_pro_services',
subViews: [],
initialize: function(opts, model) {
this.opts = opts;
this.model = model;
return $.getJSON(this.getServicesURL, {
_wpnonce: this.opts.nonces.getProServices
}).success((function(_this) {
return function(data) {
_this.servicesAvailable = data;
if (__indexOf.call(_this.servicesAvailable, 'customize') >= 0) {
_this.customizer = new CustomizationView(_this.opts, _this.model);
_this.subViews.push(_this.customizer);
}
return _this.render();
};
})(this)).fail(function(res) {
return console.log(res.responseText);
});
},
render: function() {
var view, _i, _len, _ref;
_ref = this.subViews;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
view = _ref[_i];
view.render();
}
return this.$el.show();
}
});
CustomizationView = Backbone.View.extend({
el: '#clef-pro-customization',
events: {
'click #clef-custom-logo-upload': 'openMediaUploader',
'click #clef-custom-logo-clear': 'clearLogo',
'change input, change textarea': 'render',
'keyup textarea': 'render'
},
initialize: function(opts, model) {
this.opts = opts;
this.model = model;
return this.preview = _.template($('#clef-customization-template').html());
},
render: function() {
this.$el.find('#custom-login-view').html(this.preview({
image: this.image(),
message: this.message()
}));
this.$el.find('#clef-custom-logo-clear').toggle(!!this.image());
return this.$el.show();
},
openMediaUploader: function() {
if (this.uploader) {
this.uploader.open();
return;
}
this.uploader = wp.media.frames.file_frame = wp.media({
title: 'Choose an image',
button: {
text: 'Choose an image'
},
multiple: false
});
this.uploader.on('select', (function(_this) {
return function() {
var attachment;
attachment = _this.uploader.state().get('selection').first().toJSON();
_this.model.save({
'wpclef[customization_logo]': attachment.url
});
return _this.render();
};
})(this));
return this.uploader.open();
},
clearLogo: function() {
this.model.save({
'wpclef[customization_logo]': ''
});
return this.render();
},
image: function() {
return this.model.cget('customization_logo');
},
message: function() {
return this.$el.find('textarea').val();
}
});
return window.ClefProView = ProView;
}).call(this, jQuery, Backbone);

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,24 @@
(function($) {
var dismissWaltzNotification;
dismissWaltzNotification = function(e) {
var $el, data;
if (e) {
e.preventDefault();
}
$el = $('.waltz-notification');
data = {};
$el.find('input').each(function() {
return data[$(this).attr('name')] = $(this).val();
});
$el.remove();
return $.post(ajaxurl + '?action=clef_dismiss_waltz', data);
};
return $(document).ready(function() {
setTimeout(function() {
if (window.waltzIsInstalled) {
return dismissWaltzNotification();
}
}, 1000);
return $('.waltz-notification .next').click(dismissWaltzNotification);
});
}).call(this, jQuery);

View File

@@ -0,0 +1,4 @@
/*! Clef for WordPress - v2.3.0
* http://getclef.com
* Licensed GPLv2+ */
(function(t){var n;return n=function(n){var i,e;return n&&n.preventDefault(),i=t(".waltz-notification"),e={},i.find("input").each(function(){return e[t(this).attr("name")]=t(this).val()}),i.remove(),t.post(ajaxurl+"?action=clef_dismiss_waltz",e)},t(document).ready(function(){return setTimeout(function(){return window.waltzIsInstalled?n():void 0},1e3),t(".waltz-notification .next").click(n)})}).call(this,jQuery);

View File

@@ -0,0 +1,38 @@
(($) ->
$(document).ready ->
$prompt = $(".clef-badge-prompt")
ajaxData = action: "clef_badge_prompt"
sending = false
$prompt.find(".add-badge").click (e) ->
e.preventDefault()
return if sending
sending = true
data = {}
$prompt.find('input').each ->
data[$(this).attr('name')] = $(this).val()
data.enable = 'badge'
$.extend data, ajaxData
$prompt.slideUp()
$.post ajaxurl, data, (() ->), "json"
$prompt.find(".no-badge, .dismiss").click (e) ->
e.preventDefault()
return if sending
sending = true
data = {}
$prompt.find('input').each ->
data[$(this).attr('name')] = $(this).val()
data.disable = true
$.extend data, ajaxData
$.post ajaxurl, data, (() ->), "json"
$prompt.slideUp()
).call this, jQuery

View File

@@ -0,0 +1,8 @@
jQuery(document).ready ->
if wp.heartbeat
wp.heartbeat.interval "fast"
wp.heartbeat.enqueue "clef", "cleflogout", true
jQuery(document).on "heartbeat-tick", (e, data) ->
wp.heartbeat.enqueue "clef", "cleflogout", true

View File

@@ -0,0 +1,28 @@
(($) ->
closeOverlay = ->
$('.clef-login-form.clef-login-form-embed').addClass 'clef-closed'
false
openOverlay = (e) ->
$('.clef-login-form.clef-login-form-embed').removeClass 'clef-closed'
false
$ ->
$embedContainer = $('.clef-embed-container')
$('.close-overlay').click closeOverlay
$('.open-overlay').click openOverlay
$('.overlay-info .open').click ->
$('.overlay-info').removeClass 'closed'
if $embedContainer.length
$spinnerContainer = $('.spinner-container')
$iframe = $embedContainer.find('iframe')
$iframe.load ->
$spinnerContainer.hide()
setTimeout -> $embedContainer.slideDown()
if not $iframe.attr 'data-loaded'
$embedContainer.hide()
$spinnerContainer.show()
).call this, jQuery

View File

@@ -0,0 +1,61 @@
(($, Backbone) ->
ConnectView = Backbone.View.extend
el: "#connect-clef-account"
events:
"click #disconnect": "disconnectClefAccount"
disconnectURL: ajaxurl + "?action=disconnect_clef_account"
messageTemplate:
_.template "<div class='<%=type%> connect-clef-message'>\
<%=message%>\
</div>"
initialize: (@opts) ->
@tutorial = new ConnectTutorialView _.clone(@opts)
@disconnect = @$el.find '.disconnect-clef'
@listenTo @tutorial, 'done', @finishTutorial
@render()
show: ->
@$el.fadeIn()
render: ->
@tutorial.render()
if not @opts.connected
@disconnect.hide()
@tutorial.show()
else
@tutorial.slideUp()
@disconnect.show()
disconnectClefAccount: (e) ->
e.preventDefault()
failure = (msg) =>
@showMessage
message: _.template(
clefTranslations.messages.error.disconnect
)(error: msg)
type: "error"
$.post @disconnectURL, { _wpnonce: @opts.nonces.disconnectClef }
.success (data) =>
if data.success
@opts.connected = false
@render()
msg = clefTranslations.messages.success.disconnect
@showMessage
message: msg
type: "updated"
else
failure ClefUtils.getErrorMessage(data)
.fail (res) -> failure res.responseText
showMessage: (data) ->
@message.remove() if @message
@message = $(@messageTemplate data).hide()
@message.prependTo(@$el).slideDown()
finishTutorial: ->
window.location = ''
window.ConnectView = ConnectView
).call(this, jQuery, Backbone)

View File

@@ -0,0 +1,54 @@
(($, Backbone) ->
InviteUsersView = Backbone.View.extend
el: '#invite-users-settings'
events:
"click a[name='invite-users-button']": 'inviteUsers'
messageTemplate:
_.template "<div class='<%=type%> invite-users-message'>\
<%=message%>\
</div>"
showMessage: (data) ->
$messageEl = @$el.find('.invite-users-message')
$messageEl.remove() if $messageEl.length
@$el.find('.button').first().before(@messageTemplate(data))
template: -> _.template($('#invite-users-template').html())
initialize: (@opts) ->
if @opts.el
@setElement(@opts.el)
inviteUsersAction: ajaxurl + "?action=clef_invite_users"
inviteUsers: (e) ->
e.preventDefault()
data =
_wpnonce: @opts.nonces.inviteUsers
roles: $("select[name='invite-users-role']").val()
networkAdmin: @opts.isNetworkSettings
failure = (msg) =>
@showMessage
message: _.template(
clefTranslations.messages.error.invite
)(error: msg)
type: "error"
$.post @inviteUsersAction, data
.success (data) =>
if data.success
@trigger "invited"
@showMessage
message: clefTranslations.messages.success.invite
type:"updated"
else
failure ClefUtils.getErrorMessage data
.fail (res) -> failure res.responseText
hideButton: () ->
@$el.find('.button').hide()
render: () ->
@$el.html(@template)
this.InviteUsersView = InviteUsersView
).call(this, jQuery, Backbone)

View File

@@ -0,0 +1,19 @@
(($) ->
MultisiteOptionsView = AjaxSettingsView.extend
el: '#multisite-settings'
initialize: (opts) ->
@modelClass = MultisiteOptionsModel
MultisiteOptionsView.__super__.initialize.call(this, opts)
MultisiteOptionsModel = AjaxSettingsModel.extend
parse: (data, options)->
options.url = ajaxurl + '?action=clef_multisite_settings'
MultisiteOptionsModel.__super__.parse.call(this, data, options)
this.MultisiteOptionsModel = MultisiteOptionsModel
this.MultisiteOptionsView = MultisiteOptionsView
).call(this, jQuery)

View File

@@ -0,0 +1,68 @@
(($, Backbone) ->
ProView = Backbone.View.extend
el: '#clef-pro-section'
getServicesURL: ajaxurl + '?action=clef_get_pro_services'
subViews: []
initialize: (@opts, @model) ->
$.getJSON @getServicesURL, { _wpnonce: @opts.nonces.getProServices }
.success (data) =>
@servicesAvailable = data
if 'customize' in @servicesAvailable
@customizer = new CustomizationView(@opts, @model)
@subViews.push @customizer
@render()
.fail (res) -> console.log res.responseText
render: ->
for view in @subViews
view.render()
@$el.show()
CustomizationView = Backbone.View.extend
el: '#clef-pro-customization'
events:
'click #clef-custom-logo-upload': 'openMediaUploader'
'click #clef-custom-logo-clear': 'clearLogo'
'change input, change textarea': 'render'
'keyup textarea': 'render'
initialize: (@opts, @model) ->
@preview = _.template($('#clef-customization-template').html())
render: ->
@$el.find('#custom-login-view')
.html @preview
image: @image()
message: @message()
@$el.find('#clef-custom-logo-clear').toggle !!@image()
@$el.show()
openMediaUploader: ->
if @uploader
@uploader.open()
return
@uploader = wp.media.frames.file_frame = wp.media
title: 'Choose an image'
button:
text: 'Choose an image'
multiple: false
@uploader.on 'select', =>
attachment = @uploader.state().get('selection').first().toJSON()
@model.save
'wpclef[customization_logo]': attachment.url
@render()
@uploader.open()
clearLogo: ->
@model.save
'wpclef[customization_logo]': ''
@render()
image: ->
@model.cget 'customization_logo'
message: ->
@$el.find('textarea').val()
window.ClefProView = ProView
).call(this, jQuery, Backbone)

View File

@@ -0,0 +1,242 @@
(($) ->
AppView = Backbone.View.extend
el: $('#clef-settings-container')
initialize: (@opts) ->
@$msgContainer = @$el.find('.message')
@settings = new SettingsView (
_.extend { options_name: "wpclef" }, @opts
)
@settings.hide()
if !@settings.isConfigured()
@tutorial = new SetupTutorialView _.extend {}, @opts
@tutorial.hide()
@listenTo @tutorial, 'message', @displayMessage
if @opts.isNetworkSettings
delete @opts['formSelector']
@multisiteOptionsView = new MultisiteOptionsView(@opts)
@listenTo @settings, 'message', @displayMessage
@render()
render: ->
if @opts.isUsingIndividualSettings or
(@opts.isNetworkSettings && @opts.isNetworkSettingsEnabled)
@multisiteOptionsView.show() if @multisiteOptionsView
if @settings.isConfigured()
@settings.show()
else
@tutorial.show()
@listenToOnce @tutorial, 'applicationCreated', @configure
@listenToOnce @tutorial, 'done', @hideTutorial
@$el.fadeIn()
configure: (data) ->
@settings.model.configure(data)
@settings.render()
displayMessage: (opts) ->
@$msgContainer.find('p').text(opts.message)
@$msgContainer.addClass(opts.type).slideDown()
if opts.fade
setTimeout (() -> @$msgContainer.slideUp()), 3000
hideTutorial: () ->
if @settings.isConfigured()
@displayMessage clefTranslations.messages.success.configured
type: "updated"
@tutorial.slideUp()
@settings.show()
SettingsView = AjaxSettingsView.extend
errorTemplate: _.template "<div class='error form-error'>\
<%=message%>\
</div>"
genericErrorMessage: clefTranslations.messages.error.generic
addEvents:
"click .generate-override": "generateOverride"
"click input[type='submit']:not(.ajax-ignore)": "saveForm"
"click a.show-support-html": "showSupportHTML"
constructor: (opts) ->
@events = _.extend @events, @addEvents
SettingsView.__super__.constructor.call(this, opts)
initialize: (@opts) ->
@modelClass = SettingsModel
SettingsView.__super__.initialize.call(this, opts)
@pro = new ClefProView(opts, @model)
@inviteUsersView = new InviteUsersView(opts)
@formView = new FormVisualization( model: @model )
@xmlEl = @model
.cFindInput('clef_password_settings_xml_allowed')
.parents('.input-container')
@overrideContainer = @$el.find '.override-settings'
@setOverrideLink()
@badgePreviewContainer = @$el.find '.support-settings .ftr-preview'
@listenTo @model, "change", @clearErrors
@listenTo @model, "error", @error
window.onbeforeunload = (e) =>
if @isSaving()
clefTranslations.messages.saving
@render()
updated: (obj, data) ->
SettingsView.__super__.updated.call(this, obj, data)
@setOverrideLink()
render: () ->
SettingsView.__super__.render.call this
passwordsDisabled = @model.passwordsDisabled()
$('#clef-settings-header').show()
@xmlEl.toggle passwordsDisabled
@toggleOverrideContainer passwordsDisabled
@overrideContainer.toggleClass 'set', @model.overrideIsSet()
@inviteUsersView.render()
@renderSupportBadge()
toggleInputs: (e) ->
@formView.toggleForm(!!parseInt(e.currentTarget.value))
toggleOverrideContainer: (show) ->
@overrideContainer.toggle show
generateOverride: () ->
rnd = Math.random().toString(36).slice(2)
@model.save 'wpclef[clef_override_settings_key]': rnd
setOverrideLink: () ->
key = @model.overrideKey()
return if !key
if !@overrideBase
@overrideBase = @overrideContainer.find('label').text()
button = @overrideContainer.find('a.button')
button.on 'click', (e) -> e.preventDefault()
button.attr(
'href',
@overrideBase + key
)
isSaving: () ->
@model.saving
renderSupportBadge: () ->
setting = @model.badgeSetting()
@badgePreviewContainer.toggle(
setting != "disabled"
)
@badgePreviewContainer.find('a').toggleClass(
'pretty',
setting == "badge"
)
isConfigured: () ->
@model.isConfigured()
saveForm: (e) ->
e.preventDefault()
@model.save {},
success: () =>
@trigger 'message',
message: "Settings saved.",
type: 'updated'
$('html, body').animate scrollTop: 0, "slow"
error: @model.saveError.bind(@model)
showSupportHTML: (e) ->
e.preventDefault()
$('.support-html-container').slideDown()
SettingsModel = AjaxSettingsModel.extend
cFindInput: (name) ->
@findInput "wpclef[#{name}]"
cget: (key) ->
@get "wpclef[#{key}]"
passwordsDisabled: () ->
!!parseInt(@cget('clef_password_settings_disable_passwords')) ||
@cget('clef_password_settings_disable_certain_passwords') != "" ||
@passwordsFullyDisabled()
passwordsFullyDisabled: () ->
!!parseInt @cget('clef_password_settings_force')
loginIsEmbedded: ->
!!parseInt @cget('clef_form_settings_embed_clef')
overrideIsSet: () ->
!!@overrideKey()
overrideKey: () ->
@cget('clef_override_settings_key')
badgeSetting: () ->
@cget('support_clef_badge').toLowerCase()
isConfigured: () ->
!!(@cget('clef_settings_app_id') &&
@cget('clef_settings_app_secret'))
configure: (data) ->
toSave = {
'wpclef[clef_settings_app_id]': data.appID
'wpclef[clef_settings_app_secret]': data.appSecret
}
if data.configuration
for k, v of data.configuration
toSave["wpclef[#{k}]"] = v
@save toSave
FormVisualization = Backbone.View.extend
el: $("#login-form-view")
template: () -> _.template($('#form-template').html())
initialize: (@opts) ->
@model = @opts.model
@listenTo @model, 'change', @toggleForm
@render()
render: () ->
@$el.html(@template)
@$el.find('input[type="submit"]').on 'click',
(e) -> e.preventDefault()
@toggleForm()
toggleForm: (e) ->
@$el.toggleClass('only-clef', @model.passwordsFullyDisabled())
@$el.toggleClass('embed-clef', @model.loginIsEmbedded())
this.AppView = AppView
$.fn.serializeObject = (form) ->
serialized = {}
for obj in $(this).serializeArray()
serialized[obj.name] = obj.value
serialized
).call(this, jQuery)

View File

@@ -0,0 +1,227 @@
(($, Backbone) ->
TutorialView = Backbone.View.extend
el: $('#clef-tutorial')
messageTemplate:
_.template "<div class='<%=type%> tutorial-message'>\
<%=message%>\
</div>"
events:
"click .next": "next"
"click .previous": "previous"
"click .done": "done"
slideClass: 'sub'
initialize: (@opts) ->
if window.chrome and not window.waltzIsInstalled
@$el.find('.waltz').addClass @slideClass
@$el.addClass '.no-waltz'
@subs = []
potentialSubs = @$el.find(".#{@slideClass}")
.filter(@opts.slideFilterSelector)
for sub in potentialSubs
@subs.push new SubTutorialView { el: sub }
@currentSub = @subs[0]
$(window).on 'message', @handleMessages.bind(this)
@hide()
@render()
slideUp: (cb) ->
@$el.slideUp(cb)
hide: (cb) ->
@$el.hide(cb)
show: ->
@$el.fadeIn()
render: ()->
@currentSub.render()
done: () ->
@trigger "done"
next: () ->
newSub = @subs[_.indexOf(@subs, @currentSub) + 1]
if newSub
if newSub.isLogin() && @loggedIn
newSub = @subs[_.indexOf(@subs, @newSub) + 1]
@currentSub.hide()
newSub.render()
@currentSub = newSub
@trigger "next"
else
@done()
previous: ()->
newSub = @subs[_.indexOf(@subs, @currentSub) - 1]
if newSub
@currentSub.hide()
newSub.render()
@currentSub = newSub
handleMessages: (e) ->
return unless e.originalEvent.origin.indexOf(@opts.clefBase) >= 0
data = e.originalEvent.data
data = JSON.parse(data) if typeof(data) == "string"
data
connectClefAccount: (data, cb) ->
connectData =
_wpnonce: @opts.nonces.connectClef
identifier: data.identifier
state: data.state
failure = (msg) =>
@showMessage
message: _.template(
clefTranslations.messages.error.connect
)(error: msg),
type: "error"
$.post @connectClefAction, connectData
.success (data) ->
if data.success
cb(data) if typeof(cb) == "function"
else
failure ClefUtils.getErrorMessage(data)
.fail (res) -> failure res.responseText
showMessage: (opts) ->
@$currentMessage.remove() if @$currentMessage
@$currentMessage = $(@messageTemplate(opts))
.hide()
.prependTo(@$el)
.slideDown()
if opts.removeNext
@listenToOnce this, "next", -> @$currentMessage.slideUp()
,
extend: Backbone.View.extend
SubTutorialView = Backbone.View.extend
initialize: (@opts) ->
@setElement($(@opts.el))
render: () ->
@$el.show()
hide: () ->
@$el.hide()
remove: () ->
@$el.remove()
find: (query) ->
@$el.find(query)
isLogin: () ->
@$el.find('iframe.setup').length
isSync: ->
@$el.hasClass('sync') && @$el.find('iframe').length
SetupTutorialView = TutorialView.extend
connectClefAction: ajaxurl + "?action=connect_clef_account_clef_id"
iframePath: '/iframes/application/create/v2'
initialize: (opts) ->
opts.slideFilterSelector = '.setup'
@inviter = new InviteUsersView _.extend {
el: @$el.find '.invite-users-container'
}, opts
@listenTo @inviter, "invited", @usersInvited
@constructor.__super__.initialize.call this, opts
@on 'next', @shouldLoadIFrame
render: ()->
@inviter.render()
@constructor.__super__.render.call this
shouldLoadIFrame: ->
if @currentSub.isSync()
@loadIFrame =>
@currentSub.find('.spinner-container').hide()
@iframe.fadeIn()
loadIFrame: (cb) ->
return if @iframe
@iframe = @$el.find("iframe.setup")
affiliates = encodeURIComponent(@opts.setup.affiliates.join(','))
src = "#{@opts.clefBase}#{@iframePath}?\
source=#{encodeURIComponent(@opts.setup.source)}\
&domain=#{encodeURIComponent(@opts.setup.siteDomain)}\
&logout_hook=#{encodeURIComponent(@opts.setup.logoutHook)}\
&name=#{encodeURIComponent(@opts.setup.siteName)}\
&affiliates=#{affiliates}"
@iframe.attr('src', src)
@iframe.on 'load', cb
handleMessages: (data) ->
data = @constructor.__super__.handleMessages.call this, data
return if !data
if data.type == "keys"
@connectClefAccount identifier: data.clefID,
() =>
@trigger 'applicationCreated', data
@next()
@showMessage
message: clefTranslations.messages.success.connect
type: "updated"
removeNext: true
else if data.type == "error"
@showMessage
message: _.template(
clefTranslations.messages.error.create
)(error: data.message)
type: 'error'
onConfigured: () ->
setTimeout (()->
# show logout error message after an amount of time
$(".logout-hook-error").slideDown()
), 20000
usersInvited: () ->
@inviter.hideButton()
setTimeout (() =>
if @currentSub.$el.hasClass 'invite'
@currentSub.$el
.find('.button').addClass 'button-primary'
), 1000
ConnectTutorialView = TutorialView.extend
connectClefAction: ajaxurl + "?action=connect_clef_account_oauth_code"
render: ->
@addButton()
@constructor.__super__.render.call this
addButton: ->
return if @button
redirectURL = window.location.href
if /\?/.test redirectURL
redirectURL += "&connect_clef_account=1"
else
redirectURL += "?connect_clef_account=1"
target = $('#clef-button-target')
.attr('data-app-id', @opts.appID)
.attr('data-redirect-url', redirectURL)
.attr('data-state', @opts.state)
@button = new ClefButton el: $('#clef-button-target')[0]
@button.render()
this.TutorialView = TutorialView
this.SetupTutorialView = SetupTutorialView
this.ConnectTutorialView = ConnectTutorialView
).call(this, jQuery, Backbone)

View File

@@ -0,0 +1,26 @@
(($, Backbone) ->
class Utils
@getErrorMessage: (data) ->
if data.error
return data.error
else if data.data && data.data.error
return data.data.error
return data
@getURLParams: ->
query = window.location.search.substring(1)
raw_vars = query.split("&")
params = {}
for v in raw_vars
[key, val] = v.split("=")
params[key] = decodeURIComponent(val)
params
window.ClefUtils = Utils
).call(this, jQuery, Backbone)

View File

@@ -0,0 +1,24 @@
(($) ->
dismissWaltzNotification = (e) ->
e.preventDefault() if e
$el = $('.waltz-notification')
data = {}
$el.find('input').each ->
data[$(this).attr('name')] = $(this).val()
$el.remove()
$.post(ajaxurl + '?action=clef_dismiss_waltz', data)
$(document).ready ->
setTimeout () ->
if window.waltzIsInstalled
dismissWaltzNotification()
, 1000
$('.waltz-notification .next').click(dismissWaltzNotification)
).call(this, jQuery)

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

View File

@@ -0,0 +1,55 @@
/******************************
Styles
*********************************/
$width: 140px;
$height: 50px;
.clef-badge-prompt {
* {
box-sizing: border-box;
}
position: relative;
min-height: 170px;
.link-fade {
display: none;
}
.dismiss {
position: absolute;
top: 5px;
right: 10px;
font-weight: bold;
color: #AAA;
font-size: 20px;
&:hover {
color: #888;
}
}
}
.clef-badge {
* {
box-sizing: border-box;
}
width: 100%;
text-align: center;
display: inline-block;
margin: 10px auto;
&.pretty {
display: block;
overflow: hidden;
text-indent: -579px;
height: $height;
width: $width;
background: url("https://bit.ly/clef-wordpress-badge");
background-size: 100% 100%;
opacity: .8;
&:hover {
opacity: 1;
}
}
}

View File

@@ -0,0 +1,330 @@
#clef-settings-form {
* {
box-sizing: border-box;
}
.twitter-follow-button {
position: relative;
top: 4px;
}
.settings-section {
&.pro-section {
position: relative;
display: none;
&:before {
$height: 30px;
width: 80px;
height: $height;
line-height: $height;
background: $green;
display: block;
content: "PRO";
position: absolute;
top: 0;
right: 0;
color: white;
font-weight: bold;
text-align: center;
opacity: .7;
}
}
&.override-settings {
.inputs-container {
.input-container {
background: none;
padding: 0;
margin: 0;
clear: both;
}
label {
width: auto;
margin: 0;
line-height: 25px;
font-weight: bold;
padding-left: 10px;
background: #DDD;
padding: 1px 5px;
font-size: 9px;
@include media($tablet) {
width: 100%;
font-size: 12px;
}
}
input {
float: left;
}
.generate-override {
float: left;
width: auto;
clear: both;
cursor: pointer;
color: #BBB;
&:hover {
text-decoration: underline;
}
}
.override-buttons {
margin-top: 10px;
clear: both;
.button {
display: inline-block;
text-align: center;
margin-top: 30px;
}
}
}
.preview-container {
@include span-columns(4);
display: none;
img {
margin-top: 15px;
width: 100%;
}
}
&.set {
.preview-container {
display: block;
}
.override-buttons {
display: block;
}
}
}
&.support-settings {
.preview-container {
padding-top: 10px;
@include span-columns(4);
@include media($tablet) {
display: none;
}
.ftr-preview {
background: #fff;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.13);
padding: 20px;
font-weight: 400;
overflow: hidden;
margin-top: 5px;
a {
margin-top: 20px;
}
}
}
.support-html-container {
margin-top: 20px;
textarea {
width: 400px;
padding: 10px;
margin-bottom: 10px;
}
}
}
&.clef-settings {
.inputs-container {
label {
@include span-columns(3);
}
input[type="text"],
textarea {
@include span-columns(7);
@include media($tablet) {
@include span-columns(10 of 10);
}
}
}
}
}
.password-settings {
min-height: 400px;
.input-container.custom-roles {
.title {
display: block;
width: 100%;
margin-bottom: 10px;
}
.custom-role {
label { clear: both; }
}
}
#login-form-view {
$button-height: 34px;
$button-width: 187px;
@include span-columns(4);
@include media($tablet) {
display: none;
}
&.only-clef:not(.embed-clef) {
#loginform {
padding: 40px;
& > *:not(.clef-button) {
display: none;
}
.clef-button {
margin-bottom: 0;
}
}
}
&.embed-clef {
#loginform {
position: relative;
height: 425px;
.clef-button {
display: none;
}
.clef-overlay {
display: block;
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
background: white;
img {
position: absolute;
top: 10px;
left: 10%;
width: 80%;
display: block;
}
div {
display: block;
}
}
.or-container {
display: none;
}
.overlay-text {
position: absolute;
width: 100%;
bottom: 10px;
left: 0;
color: #aaa;
text-align: center;
}
}
&.only-clef {
#loginform .overlay-text { display: none; }
}
}
#loginform {
background: #fff;
box-shadow: 0 1px 3px rgba(0,0,0,.13);
padding: 26px 24px 46px;
font-weight: 400;
overflow: hidden;
margin-top: 5px;
label {
color: #777;
font-size: 14px;
}
.input {
font-size: 24px;
line-height: 1;
width: 100%;
padding: 3px;
margin: 2px 6px 16px 0;
}
.submit {
float: right;
margin-top: 0;
}
.forgetmenot {
font-weight: 400;
float: left;
margin-bottom: 0;
}
.clef-button {
margin-bottom: 27px;
img {
height: $button-height;
width: $button-width;
margin: auto;
display: block;
}
div {
position: absolute;
width: 100%;
top: 50%;
margin-top: 5px;
text-align: center;
display: block;
color: #aaa;
cursor: pointer;
display: none;
&:hover {
color: #999;
}
}
}
.clef-overlay {
display: none;
}
}
}
}
#clef-pro-section {
display: none;
#clef-pro-customization {
.preview-container {
@include span-columns(4);
}
.button {
float: right;
margin-left: 10px;
}
#custom-login-view {
img {
max-height: 50px;
margin: auto;
margin-top: 20px;
display: block;
}
p {
border: 1px solid #eee;
margin: 20px;
padding: 10px;
}
}
}
}
.setting-info {
font-weight: normal;
font-size: 12px;
color: #aaa;
text-decoration: none;
margin-left: 5px;
&:hover {
color: #888;
}
}
}

View File

@@ -0,0 +1,13 @@
@import "neat/neat-helpers"; // or "neat-helpers" when in Rails
// Change the grid settings
$column: 90px;
$gutter: 20px;
$grid-columns: 10;
$max-width: em(1200);
// Define your breakpoints
$tablet: new-breakpoint(max-width 768px 8);
$mobile: new-breakpoint(max-width 480px 4);
$border-box-sizing: false;

View File

@@ -0,0 +1,34 @@
@mixin clef-button($color) {
text-align: center;
display: inline-block;
margin: 40px auto;
background: $color;
border: none;
box-shadow: 3px 3px darken($color, 20%);
border-radius: 0;
font-weight: bold;
font-size: 18px;
&:hover {
background: darken($color, 5%);
}
}
@mixin highlight($color, $trans:0.4) {
color: white;
font-weight: bold;
background: transparentize($color, $trans);
&:hover {
background: $color;
}
}
@mixin widget-border() {
box-shadow: 0 1px 1px rgba(0,0,0,.04);
border: 1px solid #e5e5e5;
}
@mixin widget() {
@include widget-border();
background: white;
padding: 20px 25px;
}

View File

@@ -0,0 +1,121 @@
#clef-settings-container, #connect-clef-account {
width: 100%;
height: 100%;
position: relative;
* {
box-sizing: border-box;
}
.message {
margin-top: 20px;
margin-left: 0;
display: none;
}
#clef-settings {
position: aboslute;
top: 0;
left: 0;
}
.settings-section {
background: white;
padding: 20px;
margin: 20px 0;
h3, h4 {
margin: 0;
}
margin-left: 0 !important;
@include outer-container();
.error.form-error {
float: left;
}
.inputs-container {
@include span-columns(6);
@include media($tablet) {
@include span-columns(10 of 10);
}
.input-container {
background: #EEE;
padding: 10px;
margin: 10px 0;
@include span-columns(10 of 10);
label {
@include span-columns(5);
@include media($tablet) {
@include span-columns(10 of 10);
}
margin-right: 0 !important;
}
input, select {
float: right;
@include media($tablet) {
clear: both;
float: none;
margin: 10px 0;
}
width: auto;
margin: 0;
margin-bottom: 5px;
}
input[type="checkbox"] {
@include media($tablet) {
width: 25px;
}
}
}
.ajax-settings-msg {
clear: both;
margin:0; margin-bottom: 20px;
position: relative; top: 10px;
}
}
&.multisite {
.inputs-container {
@include span-columns(5);
.input-container {
@include span-columns(5 of 5);
}
}
}
}
.sync {
.spinner-container {
text-align: center;
position: absolute;
top: 100px;
left: 0;
width: 100%;
height: 100%;
.spinner {
display: inline-block;
float: none;
}
}
iframe {
display: none;
}
}
.invite-users {
.invite-users-message {
margin: 10px 0 0 0;
clear: both;
}
.header {
h3, h4 {
margin-top: 0;
margin-bottom: 5px;
}
}
.button {
margin-top: 20px;
}
}
}

View File

@@ -0,0 +1,7 @@
$cblue: #3399CC;
$orange: #FF9940;
$blue: #0D9DDB;
$yellow: #FFC700;
$green: #00BA6E;
$gray: #7A7D81;
$red: #F65058;

View File

@@ -0,0 +1,237 @@
#clef-tutorial {
width: 100%;
height: 100%;
display: none;
margin-top: 40px;
@include outer-container();
* {
box-sizing: border-box;
}
.clef-tutorial-container {
@include span-columns(6);
@include shift(2);
min-width: 460px;
}
.tutorial-message {
@include span-columns(6);
@include shift(2);
padding: 10px;
margin-top: 20px;
margin-bottom: 20px;
}
.sub {
display: none;
h1 {
line-height: 1.3em;
font-size: 20px;
padding-bottom: 5px;
border-bottom: 1px solid #EEE;
margin-bottom: 20px;
}
}
.intro {
text-align: center;
h1 {
text-align: center;
font-size: 22px;
margin-bottom: 0;
font-weight: 500;
}
.button {
@include clef-button($blue);
}
.quotes {
background: #DDD;
padding: 5px;
blockquote {
color: #333;
text-align: left;
font-weight: 700;
font-size: 17px;
line-height: 1.2em;
margin-bottom: 70px;
.highlight {
background: none;
border: none;
text-decoration: underline;
}
cite {
font-weight: 300;
float: right;
clear: both;
margin-top: 30px;
}
.highlight {
padding: 3px 5px;
text-decoration: none;
display: inline-block;
transform: skewX(-3deg);
color: white;
&.red {
@include highlight($red);
}
&.orange {
@include highlight($orange);
}
&.green {
@include highlight($green);
}
}
}
}
.skip {
float: right;
color: #AAA;
text-decoration: none;
margin-top: 5px;
&:hover {
color: #999;
text-decoration: underline;
}
}
}
.sync {
@include widget();
iframe {
margin: auto;
display: block;
width: 400px;
height: 500px;
}
}
.invite {
h1 {
margin-bottom: 10px;
}
.invite-users {
@include widget();
.header {
h3 {
display: none;
}
h4 {
font-size: 16px;
}
}
.already-disabled {
display: none;
}
.preview-container {
margin-top: 30px;
float: none;
width: 100%;
h4 {
margin-top: 0;
}
}
}
.next {
display: inline-block !important;
}
}
.login {
@include widget();
.button-wrapper {
margin: 60px auto;
width: 190px;
}
iframe {
margin-top: 10px;
width: 100%;
height: 180px;
}
}
.using-clef {
@include widget();
h1 {
border-bottom: 1px solid #EEE;
padding-bottom: 5px;
display: inline-block;
}
h3 {
color: #333;
}
.next {
margin: 20px 0;
}
}
.waltz {
display: none;
margin-top: 80px;
padding: 10px;
img {
@include span-columns(2);
margin-top: 20px;
}
.text {
@include span-columns(8);
margin-right: 0;
h1, p {
margin: 5px;
border: 0;
}
}
.buttons {
clear: both;
margin-bottom: 40px;
position: relative;
top: 30px;
.button {
width: 44%;
text-align: center;
margin: 0;
&:first-child {
margin-right: 3%;
margin-left: 4%;
}
}
}
}
.user, .no-sync {
h1 {
text-align: left;
}
text-align: left;
}
&.user, &.no-sync {
.no-user {
display: none;
}
}
&.user {
.user {
display: block;
opacity: 1;
}
}
&.no-sync {
.no-sync {
display: block;
opacity: 1;
}
}
}
#connect-clef-account {
.skip {
display: none;
}
}

View File

@@ -0,0 +1,55 @@
.waltz {
@include outer-container;
@include widget;
margin: 10px 20px 10px 0;
* {
box-sizing: border-box;
}
&.settings {
padding: 10px;
margin-top: 40px;
img {
@include span-columns(1);
margin-top: 7px;
@include media($tablet) {
@include span-columns(1 of 10);
}
}
.text {
@include span-columns(5);
@include media($tablet) {
@include span-columns(8 of 10);
}
h1 {
font-size: 12px;
margin: 0;
}
p {
margin: 0;
font-size: 12px;
}
}
.buttons {
@include span-columns(4);
@include media($tablet) {
@include span-columns(10 of 10);
}
margin-right: 0;
margin-top: 15px;
.button {
float: none;
margin: 0;
text-align: center;
font-size: 12px;
width: 45%;
padding: 0;
&:first-child {
// margin-right: 5%;
}
}
}
}
}

View File

@@ -0,0 +1,87 @@
@import "settings";
@import "main";
@import "mixins";
@import "bourbon/_bourbon";
@import "grid-settings";
@import "neat/_neat";
@import "_settings-page";
@import "_tutorial";
@import "_form";
@import "_waltz";
.bruteprotect-install {
background: #515953;
padding: 40px;
margin-top: 20px;
p {
color: white;
font-size: 16px;
line-height: 1.2em;
font-family: "Helvetica Neue", "Helvetica", sans-serif;
}
}
.multisite-settings {
input[type="checkbox"] {
position: relative;
left: 30px;
top: 1px;
}
}
.logout-hook-error {
display: none;
}
.invite-users {
.preview-container {
@include span-columns(4);
.email {
width: 95%;
margin: auto;
margin-top: 15px;
font-style: italic;
border: 1px solid #EEE;
padding: 10px;
p {
font-size: 11px;
&:first-child {
margin-top: 0;
}
}
}
}
}
#connect-clef-account {
.connect-clef-message {
padding: 10px;
margin: 20px 0 10px 0;
}
}
.clef-flash.updated {
padding: 10px;
img {
float: left;
margin-right: 10px;
animation-name: spin;
animation-duration: 1s;
animation-timing-function: ease;
animation-iteration-count: 1;
}
}
@keyframes spin {
0% { transform: rotateY(0deg); }
100% { transform: rotateY(360deg); }
}
body #wp-auth-check-wrap #wp-auth-check {
width: 90%;
margin-left: 0;
left: 5%;
max-height: none !important;
height: 90%;
}

View File

@@ -0,0 +1,13 @@
//************************************************************************//
// These mixins/functions are deprecated
// They will be removed in the next MAJOR version release
//************************************************************************//
@mixin box-shadow ($shadows...) {
@include prefixer(box-shadow, $shadows, spec);
@warn "box-shadow is deprecated and will be removed in the next major version release";
}
@mixin background-size ($lengths...) {
@include prefixer(background-size, $lengths, spec);
@warn "background-size is deprecated and will be removed in the next major version release";
}

View File

@@ -0,0 +1,59 @@
// Custom Helpers
@import "helpers/deprecated-webkit-gradient";
@import "helpers/gradient-positions-parser";
@import "helpers/linear-positions-parser";
@import "helpers/radial-arg-parser";
@import "helpers/radial-positions-parser";
@import "helpers/render-gradients";
@import "helpers/shape-size-stripper";
// Custom Functions
@import "functions/compact";
@import "functions/flex-grid";
@import "functions/grid-width";
@import "functions/linear-gradient";
@import "functions/modular-scale";
@import "functions/px-to-em";
@import "functions/radial-gradient";
@import "functions/tint-shade";
@import "functions/transition-property-name";
// CSS3 Mixins
@import "css3/animation";
@import "css3/appearance";
@import "css3/backface-visibility";
@import "css3/background";
@import "css3/background-image";
@import "css3/border-image";
@import "css3/border-radius";
@import "css3/box-sizing";
@import "css3/columns";
@import "css3/flex-box";
@import "css3/font-face";
@import "css3/hidpi-media-query";
@import "css3/image-rendering";
@import "css3/inline-block";
@import "css3/keyframes";
@import "css3/linear-gradient";
@import "css3/perspective";
@import "css3/radial-gradient";
@import "css3/transform";
@import "css3/transition";
@import "css3/user-select";
@import "css3/placeholder";
// Addons & other mixins
@import "addons/button";
@import "addons/clearfix";
@import "addons/font-family";
@import "addons/hide-text";
@import "addons/html5-input-types";
@import "addons/position";
@import "addons/prefixer";
@import "addons/retina-image";
@import "addons/size";
@import "addons/timing-functions";
@import "addons/triangle";
// Soon to be deprecated Mixins
@import "bourbon-deprecated-upcoming";

View File

@@ -0,0 +1,273 @@
@mixin button ($style: simple, $base-color: #4294f0) {
@if type-of($style) == color {
$base-color: $style;
$style: simple;
}
// Grayscale button
@if $base-color == grayscale($base-color) {
@if $style == simple {
@include simple($base-color, $grayscale: true);
}
@else if $style == shiny {
@include shiny($base-color, $grayscale: true);
}
@else if $style == pill {
@include pill($base-color, $grayscale: true);
}
}
// Colored button
@else {
@if $style == simple {
@include simple($base-color);
}
@else if $style == shiny {
@include shiny($base-color);
}
@else if $style == pill {
@include pill($base-color);
}
}
&:disabled {
opacity: 0.5;
cursor: not-allowed;
}
}
// Simple Button
//************************************************************************//
@mixin simple($base-color, $grayscale: false) {
$color: hsl(0, 0, 100%);
$border: adjust-color($base-color, $saturation: 9%, $lightness: -14%);
$inset-shadow: adjust-color($base-color, $saturation: -8%, $lightness: 15%);
$stop-gradient: adjust-color($base-color, $saturation: 9%, $lightness: -11%);
$text-shadow: adjust-color($base-color, $saturation: 15%, $lightness: -18%);
@if lightness($base-color) > 70% {
$color: hsl(0, 0, 20%);
$text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%);
}
@if $grayscale == true {
$border: grayscale($border);
$inset-shadow: grayscale($inset-shadow);
$stop-gradient: grayscale($stop-gradient);
$text-shadow: grayscale($text-shadow);
}
border: 1px solid $border;
border-radius: 3px;
box-shadow: inset 0 1px 0 0 $inset-shadow;
color: $color;
display: inline-block;
font-size: 11px;
font-weight: bold;
@include linear-gradient ($base-color, $stop-gradient);
padding: 7px 18px;
text-decoration: none;
text-shadow: 0 1px 0 $text-shadow;
background-clip: padding-box;
&:hover:not(:disabled) {
$base-color-hover: adjust-color($base-color, $saturation: -4%, $lightness: -5%);
$inset-shadow-hover: adjust-color($base-color, $saturation: -7%, $lightness: 5%);
$stop-gradient-hover: adjust-color($base-color, $saturation: 8%, $lightness: -14%);
@if $grayscale == true {
$base-color-hover: grayscale($base-color-hover);
$inset-shadow-hover: grayscale($inset-shadow-hover);
$stop-gradient-hover: grayscale($stop-gradient-hover);
}
box-shadow: inset 0 1px 0 0 $inset-shadow-hover;
cursor: pointer;
@include linear-gradient ($base-color-hover, $stop-gradient-hover);
}
&:active:not(:disabled) {
$border-active: adjust-color($base-color, $saturation: 9%, $lightness: -14%);
$inset-shadow-active: adjust-color($base-color, $saturation: 7%, $lightness: -17%);
@if $grayscale == true {
$border-active: grayscale($border-active);
$inset-shadow-active: grayscale($inset-shadow-active);
}
border: 1px solid $border-active;
box-shadow: inset 0 0 8px 4px $inset-shadow-active, inset 0 0 8px 4px $inset-shadow-active, 0 1px 1px 0 #eee;
}
}
// Shiny Button
//************************************************************************//
@mixin shiny($base-color, $grayscale: false) {
$color: hsl(0, 0, 100%);
$border: adjust-color($base-color, $red: -117, $green: -111, $blue: -81);
$border-bottom: adjust-color($base-color, $red: -126, $green: -127, $blue: -122);
$fourth-stop: adjust-color($base-color, $red: -79, $green: -70, $blue: -46);
$inset-shadow: adjust-color($base-color, $red: 37, $green: 29, $blue: 12);
$second-stop: adjust-color($base-color, $red: -56, $green: -50, $blue: -33);
$text-shadow: adjust-color($base-color, $red: -140, $green: -141, $blue: -114);
$third-stop: adjust-color($base-color, $red: -86, $green: -75, $blue: -48);
@if lightness($base-color) > 70% {
$color: hsl(0, 0, 20%);
$text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%);
}
@if $grayscale == true {
$border: grayscale($border);
$border-bottom: grayscale($border-bottom);
$fourth-stop: grayscale($fourth-stop);
$inset-shadow: grayscale($inset-shadow);
$second-stop: grayscale($second-stop);
$text-shadow: grayscale($text-shadow);
$third-stop: grayscale($third-stop);
}
border: 1px solid $border;
border-bottom: 1px solid $border-bottom;
border-radius: 5px;
box-shadow: inset 0 1px 0 0 $inset-shadow;
color: $color;
display: inline-block;
font-size: 14px;
font-weight: bold;
@include linear-gradient(top, $base-color 0%, $second-stop 50%, $third-stop 50%, $fourth-stop 100%);
padding: 8px 20px;
text-align: center;
text-decoration: none;
text-shadow: 0 -1px 1px $text-shadow;
&:hover:not(:disabled) {
$first-stop-hover: adjust-color($base-color, $red: -13, $green: -15, $blue: -18);
$second-stop-hover: adjust-color($base-color, $red: -66, $green: -62, $blue: -51);
$third-stop-hover: adjust-color($base-color, $red: -93, $green: -85, $blue: -66);
$fourth-stop-hover: adjust-color($base-color, $red: -86, $green: -80, $blue: -63);
@if $grayscale == true {
$first-stop-hover: grayscale($first-stop-hover);
$second-stop-hover: grayscale($second-stop-hover);
$third-stop-hover: grayscale($third-stop-hover);
$fourth-stop-hover: grayscale($fourth-stop-hover);
}
cursor: pointer;
@include linear-gradient(top, $first-stop-hover 0%,
$second-stop-hover 50%,
$third-stop-hover 50%,
$fourth-stop-hover 100%);
}
&:active:not(:disabled) {
$inset-shadow-active: adjust-color($base-color, $red: -111, $green: -116, $blue: -122);
@if $grayscale == true {
$inset-shadow-active: grayscale($inset-shadow-active);
}
box-shadow: inset 0 0 20px 0 $inset-shadow-active, 0 1px 0 #fff;
}
}
// Pill Button
//************************************************************************//
@mixin pill($base-color, $grayscale: false) {
$color: hsl(0, 0, 100%);
$border-bottom: adjust-color($base-color, $hue: 8, $saturation: -11%, $lightness: -26%);
$border-sides: adjust-color($base-color, $hue: 4, $saturation: -21%, $lightness: -21%);
$border-top: adjust-color($base-color, $hue: -1, $saturation: -30%, $lightness: -15%);
$inset-shadow: adjust-color($base-color, $hue: -1, $saturation: -1%, $lightness: 7%);
$stop-gradient: adjust-color($base-color, $hue: 8, $saturation: 14%, $lightness: -10%);
$text-shadow: adjust-color($base-color, $hue: 5, $saturation: -19%, $lightness: -15%);
@if lightness($base-color) > 70% {
$color: hsl(0, 0, 20%);
$text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%);
}
@if $grayscale == true {
$border-bottom: grayscale($border-bottom);
$border-sides: grayscale($border-sides);
$border-top: grayscale($border-top);
$inset-shadow: grayscale($inset-shadow);
$stop-gradient: grayscale($stop-gradient);
$text-shadow: grayscale($text-shadow);
}
border: 1px solid $border-top;
border-color: $border-top $border-sides $border-bottom;
border-radius: 16px;
box-shadow: inset 0 1px 0 0 $inset-shadow, 0 1px 2px 0 #b3b3b3;
color: $color;
display: inline-block;
font-size: 11px;
font-weight: normal;
line-height: 1;
@include linear-gradient ($base-color, $stop-gradient);
padding: 5px 16px;
text-align: center;
text-decoration: none;
text-shadow: 0 -1px 1px $text-shadow;
background-clip: padding-box;
&:hover:not(:disabled) {
$base-color-hover: adjust-color($base-color, $lightness: -4.5%);
$border-bottom: adjust-color($base-color, $hue: 8, $saturation: 13.5%, $lightness: -32%);
$border-sides: adjust-color($base-color, $hue: 4, $saturation: -2%, $lightness: -27%);
$border-top: adjust-color($base-color, $hue: -1, $saturation: -17%, $lightness: -21%);
$inset-shadow-hover: adjust-color($base-color, $saturation: -1%, $lightness: 3%);
$stop-gradient-hover: adjust-color($base-color, $hue: 8, $saturation: -4%, $lightness: -15.5%);
$text-shadow-hover: adjust-color($base-color, $hue: 5, $saturation: -5%, $lightness: -22%);
@if $grayscale == true {
$base-color-hover: grayscale($base-color-hover);
$border-bottom: grayscale($border-bottom);
$border-sides: grayscale($border-sides);
$border-top: grayscale($border-top);
$inset-shadow-hover: grayscale($inset-shadow-hover);
$stop-gradient-hover: grayscale($stop-gradient-hover);
$text-shadow-hover: grayscale($text-shadow-hover);
}
border: 1px solid $border-top;
border-color: $border-top $border-sides $border-bottom;
box-shadow: inset 0 1px 0 0 $inset-shadow-hover;
cursor: pointer;
@include linear-gradient ($base-color-hover, $stop-gradient-hover);
text-shadow: 0 -1px 1px $text-shadow-hover;
background-clip: padding-box;
}
&:active:not(:disabled) {
$active-color: adjust-color($base-color, $hue: 4, $saturation: -12%, $lightness: -10%);
$border-active: adjust-color($base-color, $hue: 6, $saturation: -2.5%, $lightness: -30%);
$border-bottom-active: adjust-color($base-color, $hue: 11, $saturation: 6%, $lightness: -31%);
$inset-shadow-active: adjust-color($base-color, $hue: 9, $saturation: 2%, $lightness: -21.5%);
$text-shadow-active: adjust-color($base-color, $hue: 5, $saturation: -12%, $lightness: -21.5%);
@if $grayscale == true {
$active-color: grayscale($active-color);
$border-active: grayscale($border-active);
$border-bottom-active: grayscale($border-bottom-active);
$inset-shadow-active: grayscale($inset-shadow-active);
$text-shadow-active: grayscale($text-shadow-active);
}
background: $active-color;
border: 1px solid $border-active;
border-bottom: 1px solid $border-bottom-active;
box-shadow: inset 0 0 6px 3px $inset-shadow-active, 0 1px 0 0 #fff;
text-shadow: 0 -1px 1px $text-shadow-active;
}
}

View File

@@ -0,0 +1,29 @@
// Micro clearfix provides an easy way to contain floats without adding additional markup
//
// Example usage:
//
// // Contain all floats within .wrapper
// .wrapper {
// @include clearfix;
// .content,
// .sidebar {
// float : left;
// }
// }
@mixin clearfix {
*zoom: 1;
&:before,
&:after {
content: " ";
display: table;
}
&:after {
clear: both;
}
}
// Acknowledgements
// Micro clearfix: [Nicolas Gallagher](http://nicolasgallagher.com/micro-clearfix-hack/)

View File

@@ -0,0 +1,5 @@
$georgia: Georgia, Cambria, "Times New Roman", Times, serif;
$helvetica: "Helvetica Neue", Helvetica, Arial, sans-serif;
$lucida-grande: "Lucida Grande", Tahoma, Verdana, Arial, sans-serif;
$monospace: "Bitstream Vera Sans Mono", Consolas, Courier, monospace;
$verdana: Verdana, Geneva, sans-serif;

View File

@@ -0,0 +1,5 @@
@mixin hide-text {
color: transparent;
font: 0/0 a;
text-shadow: none;
}

View File

@@ -0,0 +1,56 @@
//************************************************************************//
// Generate a variable ($all-text-inputs) with a list of all html5
// input types that have a text-based input, excluding textarea.
// http://diveintohtml5.org/forms.html
//************************************************************************//
$inputs-list: 'input[type="email"]',
'input[type="number"]',
'input[type="password"]',
'input[type="search"]',
'input[type="tel"]',
'input[type="text"]',
'input[type="url"]',
// Webkit & Gecko may change the display of these in the future
'input[type="color"]',
'input[type="date"]',
'input[type="datetime"]',
'input[type="datetime-local"]',
'input[type="month"]',
'input[type="time"]',
'input[type="week"]';
$unquoted-inputs-list: ();
@each $input-type in $inputs-list {
$unquoted-inputs-list: append($unquoted-inputs-list, unquote($input-type), comma);
}
$all-text-inputs: $unquoted-inputs-list;
// Hover Pseudo-class
//************************************************************************//
$all-text-inputs-hover: ();
@each $input-type in $unquoted-inputs-list {
$input-type-hover: $input-type + ":hover";
$all-text-inputs-hover: append($all-text-inputs-hover, $input-type-hover, comma);
}
// Focus Pseudo-class
//************************************************************************//
$all-text-inputs-focus: ();
@each $input-type in $unquoted-inputs-list {
$input-type-focus: $input-type + ":focus";
$all-text-inputs-focus: append($all-text-inputs-focus, $input-type-focus, comma);
}
// You must use interpolation on the variable:
// #{$all-text-inputs}
// #{$all-text-inputs-hover}
// #{$all-text-inputs-focus}
// Example
//************************************************************************//
// #{$all-text-inputs}, textarea {
// border: 1px solid red;
// }

View File

@@ -0,0 +1,42 @@
@mixin position ($position: relative, $coordinates: 0 0 0 0) {
@if type-of($position) == list {
$coordinates: $position;
$position: relative;
}
$top: nth($coordinates, 1);
$right: nth($coordinates, 2);
$bottom: nth($coordinates, 3);
$left: nth($coordinates, 4);
position: $position;
@if $top == auto {
top: $top;
}
@else if not(unitless($top)) {
top: $top;
}
@if $right == auto {
right: $right;
}
@else if not(unitless($right)) {
right: $right;
}
@if $bottom == auto {
bottom: $bottom;
}
@else if not(unitless($bottom)) {
bottom: $bottom;
}
@if $left == auto {
left: $left;
}
@else if not(unitless($left)) {
left: $left;
}
}

View File

@@ -0,0 +1,49 @@
//************************************************************************//
// Example: @include prefixer(border-radius, $radii, webkit ms spec);
//************************************************************************//
$prefix-for-webkit: true !default;
$prefix-for-mozilla: true !default;
$prefix-for-microsoft: true !default;
$prefix-for-opera: true !default;
$prefix-for-spec: true !default; // required for keyframe mixin
@mixin prefixer ($property, $value, $prefixes) {
@each $prefix in $prefixes {
@if $prefix == webkit {
@if $prefix-for-webkit {
-webkit-#{$property}: $value;
}
}
@else if $prefix == moz {
@if $prefix-for-mozilla {
-moz-#{$property}: $value;
}
}
@else if $prefix == ms {
@if $prefix-for-microsoft {
-ms-#{$property}: $value;
}
}
@else if $prefix == o {
@if $prefix-for-opera {
-o-#{$property}: $value;
}
}
@else if $prefix == spec {
@if $prefix-for-spec {
#{$property}: $value;
}
}
@else {
@warn "Unrecognized prefix: #{$prefix}";
}
}
}
@mixin disable-prefix-for-all() {
$prefix-for-webkit: false;
$prefix-for-mozilla: false;
$prefix-for-microsoft: false;
$prefix-for-opera: false;
$prefix-for-spec: false;
}

View File

@@ -0,0 +1,32 @@
@mixin retina-image($filename, $background-size, $extension: png, $retina-filename: null, $asset-pipeline: false) {
@if $asset-pipeline {
background-image: image-url("#{$filename}.#{$extension}");
}
@else {
background-image: url("#{$filename}.#{$extension}");
}
@include hidpi {
@if $asset-pipeline {
@if $retina-filename {
background-image: image-url("#{$retina-filename}.#{$extension}");
}
@else {
background-image: image-url("#{$filename}@2x.#{$extension}");
}
}
@else {
@if $retina-filename {
background-image: url("#{$retina-filename}.#{$extension}");
}
@else {
background-image: url("#{$filename}@2x.#{$extension}");
}
}
background-size: $background-size;
}
}

View File

@@ -0,0 +1,44 @@
@mixin size($size) {
@if length($size) == 1 {
@if $size == auto {
width: $size;
height: $size;
}
@else if unitless($size) {
width: $size + px;
height: $size + px;
}
@else if not(unitless($size)) {
width: $size;
height: $size;
}
}
// Width x Height
@if length($size) == 2 {
$width: nth($size, 1);
$height: nth($size, 2);
@if $width == auto {
width: $width;
}
@else if not(unitless($width)) {
width: $width;
}
@else if unitless($width) {
width: $width + px;
}
@if $height == auto {
height: $height;
}
@else if not(unitless($height)) {
height: $height;
}
@else if unitless($height) {
height: $height + px;
}
}
}

View File

@@ -0,0 +1,32 @@
// CSS cubic-bezier timing functions. Timing functions courtesy of jquery.easie (github.com/jaukia/easie)
// Timing functions are the same as demo'ed here: http://jqueryui.com/demos/effect/easing.html
// EASE IN
$ease-in-quad: cubic-bezier(0.550, 0.085, 0.680, 0.530);
$ease-in-cubic: cubic-bezier(0.550, 0.055, 0.675, 0.190);
$ease-in-quart: cubic-bezier(0.895, 0.030, 0.685, 0.220);
$ease-in-quint: cubic-bezier(0.755, 0.050, 0.855, 0.060);
$ease-in-sine: cubic-bezier(0.470, 0.000, 0.745, 0.715);
$ease-in-expo: cubic-bezier(0.950, 0.050, 0.795, 0.035);
$ease-in-circ: cubic-bezier(0.600, 0.040, 0.980, 0.335);
$ease-in-back: cubic-bezier(0.600, -0.280, 0.735, 0.045);
// EASE OUT
$ease-out-quad: cubic-bezier(0.250, 0.460, 0.450, 0.940);
$ease-out-cubic: cubic-bezier(0.215, 0.610, 0.355, 1.000);
$ease-out-quart: cubic-bezier(0.165, 0.840, 0.440, 1.000);
$ease-out-quint: cubic-bezier(0.230, 1.000, 0.320, 1.000);
$ease-out-sine: cubic-bezier(0.390, 0.575, 0.565, 1.000);
$ease-out-expo: cubic-bezier(0.190, 1.000, 0.220, 1.000);
$ease-out-circ: cubic-bezier(0.075, 0.820, 0.165, 1.000);
$ease-out-back: cubic-bezier(0.175, 0.885, 0.320, 1.275);
// EASE IN OUT
$ease-in-out-quad: cubic-bezier(0.455, 0.030, 0.515, 0.955);
$ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1.000);
$ease-in-out-quart: cubic-bezier(0.770, 0.000, 0.175, 1.000);
$ease-in-out-quint: cubic-bezier(0.860, 0.000, 0.070, 1.000);
$ease-in-out-sine: cubic-bezier(0.445, 0.050, 0.550, 0.950);
$ease-in-out-expo: cubic-bezier(1.000, 0.000, 0.000, 1.000);
$ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.150, 0.860);
$ease-in-out-back: cubic-bezier(0.680, -0.550, 0.265, 1.550);

View File

@@ -0,0 +1,45 @@
@mixin triangle ($size, $color, $direction) {
height: 0;
width: 0;
@if ($direction == up) or ($direction == down) or ($direction == right) or ($direction == left) {
border-color: transparent;
border-style: solid;
border-width: $size / 2;
@if $direction == up {
border-bottom-color: $color;
} @else if $direction == right {
border-left-color: $color;
} @else if $direction == down {
border-top-color: $color;
} @else if $direction == left {
border-right-color: $color;
}
}
@else if ($direction == up-right) or ($direction == up-left) {
border-top: $size solid $color;
@if $direction == up-right {
border-left: $size solid transparent;
} @else if $direction == up-left {
border-right: $size solid transparent;
}
}
@else if ($direction == down-right) or ($direction == down-left) {
border-bottom: $size solid $color;
@if $direction == down-right {
border-left: $size solid transparent;
} @else if $direction == down-left {
border-right: $size solid transparent;
}
}
}

View File

@@ -0,0 +1,52 @@
// http://www.w3.org/TR/css3-animations/#the-animation-name-property-
// Each of these mixins support comma separated lists of values, which allows different transitions for individual properties to be described in a single style rule. Each value in the list corresponds to the value at that same position in the other properties.
// Official animation shorthand property.
@mixin animation ($animations...) {
@include prefixer(animation, $animations, webkit moz spec);
}
// Individual Animation Properties
@mixin animation-name ($names...) {
@include prefixer(animation-name, $names, webkit moz spec);
}
@mixin animation-duration ($times...) {
@include prefixer(animation-duration, $times, webkit moz spec);
}
@mixin animation-timing-function ($motions...) {
// ease | linear | ease-in | ease-out | ease-in-out
@include prefixer(animation-timing-function, $motions, webkit moz spec);
}
@mixin animation-iteration-count ($values...) {
// infinite | <number>
@include prefixer(animation-iteration-count, $values, webkit moz spec);
}
@mixin animation-direction ($directions...) {
// normal | alternate
@include prefixer(animation-direction, $directions, webkit moz spec);
}
@mixin animation-play-state ($states...) {
// running | paused
@include prefixer(animation-play-state, $states, webkit moz spec);
}
@mixin animation-delay ($times...) {
@include prefixer(animation-delay, $times, webkit moz spec);
}
@mixin animation-fill-mode ($modes...) {
// none | forwards | backwards | both
@include prefixer(animation-fill-mode, $modes, webkit moz spec);
}

View File

@@ -0,0 +1,3 @@
@mixin appearance ($value) {
@include prefixer(appearance, $value, webkit moz ms o spec);
}

View File

@@ -0,0 +1,6 @@
//************************************************************************//
// Backface-visibility mixin
//************************************************************************//
@mixin backface-visibility($visibility) {
@include prefixer(backface-visibility, $visibility, webkit spec);
}

View File

@@ -0,0 +1,48 @@
//************************************************************************//
// Background-image property for adding multiple background images with
// gradients, or for stringing multiple gradients together.
//************************************************************************//
@mixin background-image($images...) {
background-image: _add-prefix($images, webkit);
background-image: _add-prefix($images);
}
@function _add-prefix($images, $vendor: false) {
$images-prefixed: ();
$gradient-positions: false;
@for $i from 1 through length($images) {
$type: type-of(nth($images, $i)); // Get type of variable - List or String
// If variable is a list - Gradient
@if $type == list {
$gradient-type: nth(nth($images, $i), 1); // linear or radial
$gradient-pos: null;
$gradient-args: null;
@if ($gradient-type == linear) or ($gradient-type == radial) {
$gradient-pos: nth(nth($images, $i), 2); // Get gradient position
$gradient-args: nth(nth($images, $i), 3); // Get actual gradient (red, blue)
}
@else {
$gradient-args: nth(nth($images, $i), 2); // Get actual gradient (red, blue)
}
$gradient-positions: _gradient-positions-parser($gradient-type, $gradient-pos);
$gradient: _render-gradients($gradient-positions, $gradient-args, $gradient-type, $vendor);
$images-prefixed: append($images-prefixed, $gradient, comma);
}
// If variable is a string - Image
@else if $type == string {
$images-prefixed: join($images-prefixed, nth($images, $i), comma);
}
}
@return $images-prefixed;
}
//Examples:
//@include background-image(linear-gradient(top, orange, red));
//@include background-image(radial-gradient(50% 50%, cover circle, orange, red));
//@include background-image(url("/images/a.png"), linear-gradient(orange, red));
//@include background-image(url("image.png"), linear-gradient(orange, red), url("image.png"));
//@include background-image(linear-gradient(hsla(0, 100%, 100%, 0.25) 0%, hsla(0, 100%, 100%, 0.08) 50%, transparent 50%), linear-gradient(orange, red));

View File

@@ -0,0 +1,103 @@
//************************************************************************//
// Background property for adding multiple backgrounds using shorthand
// notation.
//************************************************************************//
@mixin background(
$background-1 , $background-2: false,
$background-3: false, $background-4: false,
$background-5: false, $background-6: false,
$background-7: false, $background-8: false,
$background-9: false, $background-10: false,
$fallback: false
) {
$backgrounds: compact($background-1, $background-2,
$background-3, $background-4,
$background-5, $background-6,
$background-7, $background-8,
$background-9, $background-10);
$fallback-color: false;
@if (type-of($fallback) == color) or ($fallback == "transparent") {
$fallback-color: $fallback;
}
@else {
$fallback-color: _extract-background-color($backgrounds);
}
@if $fallback-color {
background-color: $fallback-color;
}
background: _background-add-prefix($backgrounds, webkit);
background: _background-add-prefix($backgrounds);
}
@function _extract-background-color($backgrounds) {
$final-bg-layer: nth($backgrounds, length($backgrounds));
@if type-of($final-bg-layer) == list {
@for $i from 1 through length($final-bg-layer) {
$value: nth($final-bg-layer, $i);
@if type-of($value) == color {
@return $value;
}
}
}
@return false;
}
@function _background-add-prefix($backgrounds, $vendor: false) {
$backgrounds-prefixed: ();
@for $i from 1 through length($backgrounds) {
$shorthand: nth($backgrounds, $i); // Get member for current index
$type: type-of($shorthand); // Get type of variable - List (gradient) or String (image)
// If shorthand is a list (gradient)
@if $type == list {
$first-member: nth($shorthand, 1); // Get first member of shorthand
// Linear Gradient
@if index(linear radial, nth($first-member, 1)) {
$gradient-type: nth($first-member, 1); // linear || radial
$gradient-args: false;
$gradient-positions: false;
$shorthand-start: false;
@if type-of($first-member) == list { // Linear gradient plus additional shorthand values - lg(red,orange)repeat,...
$gradient-positions: nth($first-member, 2);
$gradient-args: nth($first-member, 3);
$shorthand-start: 2;
}
@else { // Linear gradient only - lg(red,orange),...
$gradient-positions: nth($shorthand, 2);
$gradient-args: nth($shorthand, 3); // Get gradient (red, blue)
}
$gradient-positions: _gradient-positions-parser($gradient-type, $gradient-positions);
$gradient: _render-gradients($gradient-positions, $gradient-args, $gradient-type, $vendor);
// Append any additional shorthand args to gradient
@if $shorthand-start {
@for $j from $shorthand-start through length($shorthand) {
$gradient: join($gradient, nth($shorthand, $j), space);
}
}
$backgrounds-prefixed: append($backgrounds-prefixed, $gradient, comma);
}
// Image with additional properties
@else {
$backgrounds-prefixed: append($backgrounds-prefixed, $shorthand, comma);
}
}
// If shorthand is a simple string (color or image)
@else if $type == string {
$backgrounds-prefixed: join($backgrounds-prefixed, $shorthand, comma);
}
}
@return $backgrounds-prefixed;
}
//Examples:
//@include background(linear-gradient(top, orange, red));
//@include background(radial-gradient(circle at 40% 40%, orange, red));
//@include background(url("/images/a.png") no-repeat, linear-gradient(orange, red));
//@include background(url("image.png") center center, linear-gradient(orange, red), url("image.png"));

View File

@@ -0,0 +1,55 @@
@mixin border-image($images) {
-webkit-border-image: _border-add-prefix($images, webkit);
-moz-border-image: _border-add-prefix($images, moz);
-o-border-image: _border-add-prefix($images, o);
border-image: _border-add-prefix($images);
}
@function _border-add-prefix($images, $vendor: false) {
$border-image: null;
$images-type: type-of(nth($images, 1));
$first-var: nth(nth($images, 1), 1); // Get type of Gradient (Linear || radial)
// If input is a gradient
@if $images-type == string {
@if ($first-var == "linear") or ($first-var == "radial") {
$gradient-type: nth($images, 1); // Get type of gradient (linear || radial)
$gradient-pos: nth($images, 2); // Get gradient position
$gradient-args: nth($images, 3); // Get actual gradient (red, blue)
$gradient-positions: _gradient-positions-parser($gradient-type, $gradient-pos);
$border-image: _render-gradients($gradient-positions, $gradient-args, $gradient-type, $vendor);
}
// If input is a URL
@else {
$border-image: $images;
}
}
// If input is gradient or url + additional args
@else if $images-type == list {
$type: type-of(nth($images, 1)); // Get type of variable - List or String
// If variable is a list - Gradient
@if $type == list {
$gradient: nth($images, 1);
$gradient-type: nth($gradient, 1); // Get type of gradient (linear || radial)
$gradient-pos: nth($gradient, 2); // Get gradient position
$gradient-args: nth($gradient, 3); // Get actual gradient (red, blue)
$gradient-positions: _gradient-positions-parser($gradient-type, $gradient-pos);
$border-image: _render-gradients($gradient-positions, $gradient-args, $gradient-type, $vendor);
@for $i from 2 through length($images) {
$border-image: append($border-image, nth($images, $i));
}
}
}
@return $border-image;
}
//Examples:
// @include border-image(url("image.png"));
// @include border-image(url("image.png") 20 stretch);
// @include border-image(linear-gradient(45deg, orange, yellow));
// @include border-image(linear-gradient(45deg, orange, yellow) stretch);
// @include border-image(linear-gradient(45deg, orange, yellow) 20 30 40 50 stretch round);
// @include border-image(radial-gradient(top, cover, orange, yellow, orange));

View File

@@ -0,0 +1,22 @@
//************************************************************************//
// Shorthand Border-radius mixins
//************************************************************************//
@mixin border-top-radius($radii) {
@include prefixer(border-top-left-radius, $radii, spec);
@include prefixer(border-top-right-radius, $radii, spec);
}
@mixin border-bottom-radius($radii) {
@include prefixer(border-bottom-left-radius, $radii, spec);
@include prefixer(border-bottom-right-radius, $radii, spec);
}
@mixin border-left-radius($radii) {
@include prefixer(border-top-left-radius, $radii, spec);
@include prefixer(border-bottom-left-radius, $radii, spec);
}
@mixin border-right-radius($radii) {
@include prefixer(border-top-right-radius, $radii, spec);
@include prefixer(border-bottom-right-radius, $radii, spec);
}

View File

@@ -0,0 +1,4 @@
@mixin box-sizing ($box) {
// content-box | border-box | inherit
@include prefixer(box-sizing, $box, webkit moz spec);
}

View File

@@ -0,0 +1,47 @@
@mixin columns($arg: auto) {
// <column-count> || <column-width>
@include prefixer(columns, $arg, webkit moz spec);
}
@mixin column-count($int: auto) {
// auto || integer
@include prefixer(column-count, $int, webkit moz spec);
}
@mixin column-gap($length: normal) {
// normal || length
@include prefixer(column-gap, $length, webkit moz spec);
}
@mixin column-fill($arg: auto) {
// auto || length
@include prefixer(columns-fill, $arg, webkit moz spec);
}
@mixin column-rule($arg) {
// <border-width> || <border-style> || <color>
@include prefixer(column-rule, $arg, webkit moz spec);
}
@mixin column-rule-color($color) {
@include prefixer(column-rule-color, $color, webkit moz spec);
}
@mixin column-rule-style($style: none) {
// none | hidden | dashed | dotted | double | groove | inset | inset | outset | ridge | solid
@include prefixer(column-rule-style, $style, webkit moz spec);
}
@mixin column-rule-width ($width: none) {
@include prefixer(column-rule-width, $width, webkit moz spec);
}
@mixin column-span($arg: none) {
// none || all
@include prefixer(column-span, $arg, webkit moz spec);
}
@mixin column-width($length: auto) {
// auto || length
@include prefixer(column-width, $length, webkit moz spec);
}

View File

@@ -0,0 +1,52 @@
// CSS3 Flexible Box Model and property defaults
// Custom shorthand notation for flexbox
@mixin box($orient: inline-axis, $pack: start, $align: stretch) {
@include display-box;
@include box-orient($orient);
@include box-pack($pack);
@include box-align($align);
}
@mixin display-box {
display: -webkit-box;
display: -moz-box;
display: box;
}
@mixin box-orient($orient: inline-axis) {
// horizontal|vertical|inline-axis|block-axis|inherit
@include prefixer(box-orient, $orient, webkit moz spec);
}
@mixin box-pack($pack: start) {
// start|end|center|justify
@include prefixer(box-pack, $pack, webkit moz spec);
}
@mixin box-align($align: stretch) {
// start|end|center|baseline|stretch
@include prefixer(box-align, $align, webkit moz spec);
}
@mixin box-direction($direction: normal) {
// normal|reverse|inherit
@include prefixer(box-direction, $direction, webkit moz spec);
}
@mixin box-lines($lines: single) {
// single|multiple
@include prefixer(box-lines, $lines, webkit moz spec);
}
@mixin box-ordinal-group($int: 1) {
@include prefixer(box-ordinal-group, $int, webkit moz spec);
}
@mixin box-flex($value: 0.0) {
@include prefixer(box-flex, $value, webkit moz spec);
}
@mixin box-flex-group($int: 1) {
@include prefixer(box-flex-group, $int, webkit moz spec);
}

View File

@@ -0,0 +1,23 @@
// Order of the includes matters, and it is: normal, bold, italic, bold+italic.
@mixin font-face($font-family, $file-path, $weight: normal, $style: normal, $asset-pipeline: false ) {
@font-face {
font-family: $font-family;
font-weight: $weight;
font-style: $style;
@if $asset-pipeline == true {
src: font-url('#{$file-path}.eot');
src: font-url('#{$file-path}.eot?#iefix') format('embedded-opentype'),
font-url('#{$file-path}.woff') format('woff'),
font-url('#{$file-path}.ttf') format('truetype'),
font-url('#{$file-path}.svg##{$font-family}') format('svg');
} @else {
src: url('#{$file-path}.eot');
src: url('#{$file-path}.eot?#iefix') format('embedded-opentype'),
url('#{$file-path}.woff') format('woff'),
url('#{$file-path}.ttf') format('truetype'),
url('#{$file-path}.svg##{$font-family}') format('svg');
}
}
}

View File

@@ -0,0 +1,10 @@
// HiDPI mixin. Default value set to 1.3 to target Google Nexus 7 (http://bjango.com/articles/min-device-pixel-ratio/)
@mixin hidpi($ratio: 1.3) {
@media only screen and (-webkit-min-device-pixel-ratio: $ratio),
only screen and (min--moz-device-pixel-ratio: $ratio),
only screen and (-o-min-device-pixel-ratio: #{$ratio}/1),
only screen and (min-resolution: #{round($ratio*96)}dpi),
only screen and (min-resolution: #{$ratio}dppx) {
@content;
}
}

View File

@@ -0,0 +1,13 @@
@mixin image-rendering ($mode:optimizeQuality) {
@if ($mode == optimize-contrast) {
image-rendering: -moz-crisp-edges;
image-rendering: -o-crisp-edges;
image-rendering: -webkit-optimize-contrast;
image-rendering: optimize-contrast;
}
@else {
image-rendering: $mode;
}
}

View File

@@ -0,0 +1,8 @@
// Legacy support for inline-block in IE7 (maybe IE6)
@mixin inline-block {
display: inline-block;
vertical-align: baseline;
zoom: 1;
*display: inline;
*vertical-align: auto;
}

View File

@@ -0,0 +1,43 @@
// Adds keyframes blocks for supported prefixes, removing redundant prefixes in the block's content
@mixin keyframes($name) {
$original-prefix-for-webkit: $prefix-for-webkit;
$original-prefix-for-mozilla: $prefix-for-mozilla;
$original-prefix-for-microsoft: $prefix-for-microsoft;
$original-prefix-for-opera: $prefix-for-opera;
$original-prefix-for-spec: $prefix-for-spec;
@if $original-prefix-for-webkit {
@include disable-prefix-for-all();
$prefix-for-webkit: true;
@-webkit-keyframes #{$name} {
@content;
}
}
@if $original-prefix-for-mozilla {
@include disable-prefix-for-all();
$prefix-for-mozilla: true;
@-moz-keyframes #{$name} {
@content;
}
}
@if $original-prefix-for-opera {
@include disable-prefix-for-all();
$prefix-for-opera: true;
@-o-keyframes #{$name} {
@content;
}
}
@if $original-prefix-for-spec {
@include disable-prefix-for-all();
$prefix-for-spec: true;
@keyframes #{$name} {
@content;
}
}
$prefix-for-webkit: $original-prefix-for-webkit;
$prefix-for-mozilla: $original-prefix-for-mozilla;
$prefix-for-microsoft: $original-prefix-for-microsoft;
$prefix-for-opera: $original-prefix-for-opera;
$prefix-for-spec: $original-prefix-for-spec;
}

View File

@@ -0,0 +1,41 @@
@mixin linear-gradient($pos, $G1, $G2: false,
$G3: false, $G4: false,
$G5: false, $G6: false,
$G7: false, $G8: false,
$G9: false, $G10: false,
$deprecated-pos1: left top,
$deprecated-pos2: left bottom,
$fallback: false) {
// Detect what type of value exists in $pos
$pos-type: type-of(nth($pos, 1));
$pos-spec: null;
$pos-degree: null;
// If $pos is missing from mixin, reassign vars and add default position
@if ($pos-type == color) or (nth($pos, 1) == "transparent") {
$G10: $G9; $G9: $G8; $G8: $G7; $G7: $G6; $G6: $G5;
$G5: $G4; $G4: $G3; $G3: $G2; $G2: $G1; $G1: $pos;
$pos: null;
}
@if $pos {
$positions: _linear-positions-parser($pos);
$pos-degree: nth($positions, 1);
$pos-spec: nth($positions, 2);
}
$full: compact($G1, $G2, $G3, $G4, $G5, $G6, $G7, $G8, $G9, $G10);
// Set $G1 as the default fallback color
$fallback-color: nth($G1, 1);
// If $fallback is a color use that color as the fallback color
@if (type-of($fallback) == color) or ($fallback == "transparent") {
$fallback-color: $fallback;
}
background-color: $fallback-color;
background-image: _deprecated-webkit-gradient(linear, $deprecated-pos1, $deprecated-pos2, $full); // Safari <= 5.0
background-image: -webkit-linear-gradient($pos-degree $full); // Safari 5.1+, Chrome
background-image: unquote("linear-gradient(#{$pos-spec}#{$full})");
}

View File

@@ -0,0 +1,8 @@
@mixin perspective($depth: none) {
// none | <length>
@include prefixer(perspective, $depth, webkit moz spec);
}
@mixin perspective-origin($value: 50% 50%) {
@include prefixer(perspective-origin, $value, webkit moz spec);
}

View File

@@ -0,0 +1,29 @@
$placeholders: '-webkit-input-placeholder',
'-moz-placeholder',
'-ms-input-placeholder';
@mixin placeholder {
@each $placeholder in $placeholders {
@if $placeholder == "-webkit-input-placeholder" {
&::#{$placeholder} {
@content;
}
}
@else if $placeholder == "-moz-placeholder" {
// FF 18-
&:#{$placeholder} {
@content;
}
// FF 19+
&::#{$placeholder} {
@content;
}
}
@else {
&:#{$placeholder} {
@content;
}
}
}
}

View File

@@ -0,0 +1,44 @@
// Requires Sass 3.1+
@mixin radial-gradient($G1, $G2,
$G3: false, $G4: false,
$G5: false, $G6: false,
$G7: false, $G8: false,
$G9: false, $G10: false,
$pos: null,
$shape-size: null,
$deprecated-pos1: center center,
$deprecated-pos2: center center,
$deprecated-radius1: 0,
$deprecated-radius2: 460,
$fallback: false) {
$data: _radial-arg-parser($G1, $G2, $pos, $shape-size);
$G1: nth($data, 1);
$G2: nth($data, 2);
$pos: nth($data, 3);
$shape-size: nth($data, 4);
$full: compact($G1, $G2, $G3, $G4, $G5, $G6, $G7, $G8, $G9, $G10);
// Strip deprecated cover/contain for spec
$shape-size-spec: _shape-size-stripper($shape-size);
// Set $G1 as the default fallback color
$first-color: nth($full, 1);
$fallback-color: nth($first-color, 1);
@if (type-of($fallback) == color) or ($fallback == "transparent") {
$fallback-color: $fallback;
}
// Add Commas and spaces
$shape-size: if($shape-size, '#{$shape-size}, ', null);
$pos: if($pos, '#{$pos}, ', null);
$pos-spec: if($pos, 'at #{$pos}', null);
$shape-size-spec: if(($shape-size-spec != ' ') and ($pos == null), '#{$shape-size-spec}, ', '#{$shape-size-spec} ');
background-color: $fallback-color;
background-image: _deprecated-webkit-gradient(radial, $deprecated-pos1, $deprecated-pos2, $full, $deprecated-radius1, $deprecated-radius2); // Safari <= 5.0 && IOS 4
background-image: -webkit-radial-gradient(unquote(#{$pos}#{$shape-size}#{$full}));
background-image: unquote("radial-gradient(#{$shape-size-spec}#{$pos-spec}#{$full})");
}

View File

@@ -0,0 +1,15 @@
@mixin transform($property: none) {
// none | <transform-function>
@include prefixer(transform, $property, webkit moz ms o spec);
}
@mixin transform-origin($axes: 50%) {
// x-axis - left | center | right | length | %
// y-axis - top | center | bottom | length | %
// z-axis - length
@include prefixer(transform-origin, $axes, webkit moz ms o spec);
}
@mixin transform-style ($style: flat) {
@include prefixer(transform-style, $style, webkit moz ms o spec);
}

View File

@@ -0,0 +1,34 @@
// Shorthand mixin. Supports multiple parentheses-deliminated values for each variable.
// Example: @include transition (all, 2.0s, ease-in-out);
// @include transition ((opacity, width), (1.0s, 2.0s), ease-in, (0, 2s));
// @include transition ($property:(opacity, width), $delay: (1.5s, 2.5s));
@mixin transition ($properties...) {
@if length($properties) >= 1 {
@include prefixer(transition, $properties, webkit moz spec);
}
@else {
$properties: all 0.15s ease-out 0;
@include prefixer(transition, $properties, webkit moz spec);
}
}
@mixin transition-property ($properties...) {
-webkit-transition-property: transition-property-names($properties, 'webkit');
-moz-transition-property: transition-property-names($properties, 'moz');
transition-property: transition-property-names($properties, false);
}
@mixin transition-duration ($times...) {
@include prefixer(transition-duration, $times, webkit moz spec);
}
@mixin transition-timing-function ($motions...) {
// ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier()
@include prefixer(transition-timing-function, $motions, webkit moz spec);
}
@mixin transition-delay ($times...) {
@include prefixer(transition-delay, $times, webkit moz spec);
}

View File

@@ -0,0 +1,3 @@
@mixin user-select($arg: none) {
@include prefixer(user-select, $arg, webkit moz ms spec);
}

View File

@@ -0,0 +1,11 @@
// Remove `false` values from a list
@function compact($vars...) {
$list: ();
@each $var in $vars {
@if $var {
$list: append($list, $var, comma);
}
}
@return $list;
}

View File

@@ -0,0 +1,39 @@
// Flexible grid
@function flex-grid($columns, $container-columns: $fg-max-columns) {
$width: $columns * $fg-column + ($columns - 1) * $fg-gutter;
$container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter;
@return percentage($width / $container-width);
}
// Flexible gutter
@function flex-gutter($container-columns: $fg-max-columns, $gutter: $fg-gutter) {
$container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter;
@return percentage($gutter / $container-width);
}
// The $fg-column, $fg-gutter and $fg-max-columns variables must be defined in your base stylesheet to properly use the flex-grid function.
// This function takes the fluid grid equation (target / context = result) and uses columns to help define each.
//
// The calculation presumes that your column structure will be missing the last gutter:
//
// -- column -- gutter -- column -- gutter -- column
//
// $fg-column: 60px; // Column Width
// $fg-gutter: 25px; // Gutter Width
// $fg-max-columns: 12; // Total Columns For Main Container
//
// div {
// width: flex-grid(4); // returns (315px / 995px) = 31.65829%;
// margin-left: flex-gutter(); // returns (25px / 995px) = 2.51256%;
//
// p {
// width: flex-grid(2, 4); // returns (145px / 315px) = 46.031746%;
// float: left;
// margin: flex-gutter(4); // returns (25px / 315px) = 7.936508%;
// }
//
// blockquote {
// float: left;
// width: flex-grid(2, 4); // returns (145px / 315px) = 46.031746%;
// }
// }

View File

@@ -0,0 +1,13 @@
@function grid-width($n) {
@return $n * $gw-column + ($n - 1) * $gw-gutter;
}
// The $gw-column and $gw-gutter variables must be defined in your base stylesheet to properly use the grid-width function.
//
// $gw-column: 100px; // Column Width
// $gw-gutter: 40px; // Gutter Width
//
// div {
// width: grid-width(4); // returns 520px;
// margin-left: $gw-gutter; // returns 40px;
// }

View File

@@ -0,0 +1,13 @@
@function linear-gradient($pos, $gradients...) {
$type: linear;
$pos-type: type-of(nth($pos, 1));
// if $pos doesn't exist, fix $gradient
@if ($pos-type == color) or (nth($pos, 1) == "transparent") {
$gradients: zip($pos $gradients);
$pos: false;
}
$type-gradient: $type, $pos, $gradients;
@return $type-gradient;
}

View File

@@ -0,0 +1,40 @@
@function modular-scale($value, $increment, $ratio) {
@if $increment > 0 {
@for $i from 1 through $increment {
$value: ($value * $ratio);
}
}
@if $increment < 0 {
$increment: abs($increment);
@for $i from 1 through $increment {
$value: ($value / $ratio);
}
}
@return $value;
}
// div {
// Increment Up GR with positive value
// font-size: modular-scale(14px, 1, 1.618); // returns: 22.652px
//
// Increment Down GR with negative value
// font-size: modular-scale(14px, -1, 1.618); // returns: 8.653px
//
// Can be used with ceil(round up) or floor(round down)
// font-size: floor( modular-scale(14px, 1, 1.618) ); // returns: 22px
// font-size: ceil( modular-scale(14px, 1, 1.618) ); // returns: 23px
// }
//
// modularscale.com
@function golden-ratio($value, $increment) {
@return modular-scale($value, $increment, 1.618)
}
// div {
// font-size: golden-ratio(14px, 1); // returns: 22.652px
// }
//
// goldenratiocalculator.com

View File

@@ -0,0 +1,8 @@
// Convert pixels to ems
// eg. for a relational value of 12px write em(12) when the parent is 16px
// if the parent is another value say 24px write em(12, 24)
@function em($pxval, $base: 16) {
@return ($pxval / $base) * 1em;
}

View File

@@ -0,0 +1,23 @@
// This function is required and used by the background-image mixin.
@function radial-gradient($G1, $G2,
$G3: false, $G4: false,
$G5: false, $G6: false,
$G7: false, $G8: false,
$G9: false, $G10: false,
$pos: null,
$shape-size: null) {
$data: _radial-arg-parser($G1, $G2, $pos, $shape-size);
$G1: nth($data, 1);
$G2: nth($data, 2);
$pos: nth($data, 3);
$shape-size: nth($data, 4);
$type: radial;
$gradient: compact($G1, $G2, $G3, $G4, $G5, $G6, $G7, $G8, $G9, $G10);
$type-gradient: $type, $shape-size $pos, $gradient;
@return $type-gradient;
}

Some files were not shown because too many files have changed in this diff Show More