roots 3.0.0
18
404.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php get_header(); ?>
|
||||
<div id="content" class="span-24">
|
||||
<div id="main" role="main">
|
||||
<div class="container">
|
||||
<h1>File Not Found</h1>
|
||||
<div class="error">
|
||||
<p class="bottom">The page you are looking for might have been removed, had its name changed, or is temporarily unavailable.</p>
|
||||
</div>
|
||||
<p>Please try the following:</p>
|
||||
<ul>
|
||||
<li>Check your spelling</li>
|
||||
<li>Return to the <a href="<?php echo home_url(); ?>/">home page</a></li>
|
||||
<li>Click the <a href="javascript:history.back()">Back</a> button</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div><!-- /#main -->
|
||||
</div><!-- /#content -->
|
||||
<?php get_footer(); ?>
|
||||
110
README.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# Roots WordPress Theme [http://www.rootstheme.com/](http://www.rootstheme.com/)
|
||||
|
||||
## Changelog:
|
||||
|
||||
### 3.0.0: March 28th, 2011
|
||||
|
||||
<ul>
|
||||
<li>Changed name from BB to Roots</li>
|
||||
<li>Updated various areas to match the latest changes to HTML5 Boilerplate</li>
|
||||
<li>Changed the theme markup based on hCard/Readability Guidelines and work by Jonathan Neal</li>
|
||||
<li>Theme activation now creates the navigation menus and automatically sets their locations</li>
|
||||
<li>Permalink structure is now set to <code>/%year%/%postname%/</code> for performance reasons</li>
|
||||
<li>Uploads folder is now /assets/ and not organized by month and date</li>
|
||||
<li>All static folders in <code>/wp-content/themes/roots/</code> (css/, js/, img/) now rewrite to the root (<code>/css/</code>, <code>/js/</code>, <code>/img/</code>)</li>
|
||||
<li><code>/wp-content/plugins/</code> now rewrites to <code>/plugins/</code></li>
|
||||
<li>More root relative URLs on WordPress functions</li>
|
||||
<li>Search results (<code>/?s=query</code>) now rewrites to <code>/search/query/</code></li>
|
||||
<li><code>l10n.js</code> is deregistered</li>
|
||||
<li>Gallery shortcode has been changed to output <code><figure></code> and <code><figcaption></code> and now links to the file by default</li>
|
||||
<li>Added more <code>loop.php</code> templates</li>
|
||||
<li>Made the HTML editor have a monospaced font</li>
|
||||
<li>Added <code>front-page.php</code></li>
|
||||
<li>Updated CSS for Gravity Forms 1.5</li>
|
||||
<li>Added <code>searchform.php template</code></li>
|
||||
</ul>
|
||||
|
||||
#### Contributors
|
||||
[Scott Walkinshaw](http://www.scottwalkinshaw.com/), [Matthew Price](http://www.matthewaprice.com/), [Kyle Geminden](http://www.kylegeminden.com/), [Steve Jothen](http://twitter.com/sjothen)
|
||||
|
||||
### 2.4.0: January 25th, 2011
|
||||
|
||||
<ul>
|
||||
<li>Added a notification when saving the theme settings</li>
|
||||
<li>Added support for navigation menus</li>
|
||||
<li>Created function that makes sure there is a Home page on theme activation</li>
|
||||
<li>Updated various areas to match the latest changes to HTML5 Boilerplate</li>
|
||||
</ul>
|
||||
|
||||
### 2.3.0: December 8th, 2010
|
||||
|
||||
<ul>
|
||||
<li>Logo is no longer an <code><h1></code></li>
|
||||
<li>Added ARIA roles again</li>
|
||||
<li>Changed <code>ul#nav</code> to <code>nav#nav-main</code></li>
|
||||
<li>Added vCard to footer</li>
|
||||
<li>Made all URL's root relative</li>
|
||||
<li>Added Twitter and Facebook widgets to footer</li>
|
||||
<li>Added SEO optimized <code>robots.txt</code> from WordPress codex</li>
|
||||
</ul>
|
||||
|
||||
### 2.2.0: September 20th, 2010
|
||||
|
||||
<ul>
|
||||
<li>Added asynchronous Google Analytics</li>
|
||||
<li>Updated <code>.htaccess</code> with latest changes from HTML5 Boilerplate</li>
|
||||
</ul>
|
||||
|
||||
### 2.1.0: August 19th, 2010
|
||||
|
||||
<ul>
|
||||
<li>Removed optimizeLegibility from headings</li>
|
||||
<li>Updated jQuery to latest version</li>
|
||||
<li>Implemented HTML5 Boilerplate <code>.htaccess</code></li>
|
||||
</ul>
|
||||
|
||||
### 2.0.1: August 2nd, 2010
|
||||
|
||||
<ul>
|
||||
<li>Added some presentational CSS classes</li>
|
||||
<li>Added footer widget</li>
|
||||
<li>Added more Gravity Forms default styling</li>
|
||||
</ul>
|
||||
|
||||
### 2.0.0: July 19th, 2010
|
||||
|
||||
<ul>
|
||||
<li>Added HTML5 Boilerplate changes</li>
|
||||
<li>Implemented <code>loop.php</code></li>
|
||||
<li>wp_head cleanup</li>
|
||||
<li>Added <code>page-subpages.php</code> template</li>
|
||||
</ul>
|
||||
|
||||
### 1.5.0: April 15th, 2010
|
||||
|
||||
<ul>
|
||||
<li>Integrated Paul Irish's frontend-pro-template (the original HTML5 Boilerplate)</li>
|
||||
</ul>
|
||||
|
||||
### 1.0.0: December 18th, 2009
|
||||
|
||||
<ul>
|
||||
<li>Added Blueprint CSS to Starkers</li>
|
||||
</ul>
|
||||
|
||||
## License:
|
||||
|
||||
Major components:
|
||||
|
||||
* HTML5 Boileplate: [The Unlicense](http://unlicense.org)
|
||||
* Blueprint CSS: Modified MIT License
|
||||
* Modernizr: MIT/BSD license
|
||||
* jQuery: MIT/GPL license
|
||||
|
||||
Everything else:
|
||||
|
||||
* [The Unlicense](http://unlicense.org) (aka: public domain)
|
||||
|
||||
## Summary:
|
||||
|
||||
Roots is a starting WordPress theme made for developers that<61>s based on HTML5 Boilerplate, Blueprint CSS and Starkers that will help you rapidly create brochure sites and blogs.
|
||||
15
archive.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php get_header(); ?>
|
||||
<div id="content" class="span-24">
|
||||
<div id="main" class="<?php echo get_option('roots_main_class'); ?>" role="main">
|
||||
<div class="container">
|
||||
<h1><?php single_cat_title(); ?></h1>
|
||||
<?php get_template_part('loop', 'category'); ?>
|
||||
</div>
|
||||
</div><!-- /#main -->
|
||||
<aside id="sidebar" class="<?php echo get_option('roots_sidebar_class'); ?>" role="complementary">
|
||||
<div class="container">
|
||||
<?php get_sidebar(); ?>
|
||||
</div>
|
||||
</aside><!-- /#sidebar -->
|
||||
</div><!-- /#content -->
|
||||
<?php get_footer(); ?>
|
||||
99
comments.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php function roots_comments($comment, $args, $depth) {
|
||||
$GLOBALS['comment'] = $comment; ?>
|
||||
<li <?php comment_class(); ?>>
|
||||
<article id="comment-<?php comment_ID(); ?>">
|
||||
<header class="comment-author vcard">
|
||||
<?php echo get_avatar($comment,$size='32',$default='<path_to_url>' ); ?>
|
||||
<?php printf(__('<cite class="fn">%s</cite>'), get_comment_author_link()) ?>
|
||||
<time datetime="<?php echo comment_date('c') ?>"><a href="<?php echo htmlspecialchars( get_comment_link( $comment->comment_ID ) ) ?>"><?php printf(__('%1$s'), get_comment_date(), get_comment_time()) ?></a></time>
|
||||
<?php edit_comment_link(__('(Edit)'),' ','') ?>
|
||||
</header>
|
||||
|
||||
<?php if ($comment->comment_approved == '0') : ?>
|
||||
<div class="notice">
|
||||
<p class="bottom"><?php _e('Your comment is awaiting moderation.') ?></p>
|
||||
</div>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<section class="comment">
|
||||
<?php comment_text() ?>
|
||||
</section>
|
||||
|
||||
<?php comment_reply_link(array_merge( $args, array('depth' => $depth, 'max_depth' => $args['max_depth']))) ?>
|
||||
|
||||
</article>
|
||||
<?php } ?>
|
||||
|
||||
<?php
|
||||
// Do not delete these lines
|
||||
if (!empty($_SERVER['SCRIPT_FILENAME']) && 'comments.php' == basename($_SERVER['SCRIPT_FILENAME']))
|
||||
die ('Please do not load this page directly. Thanks!');
|
||||
|
||||
if ( post_password_required() ) { ?>
|
||||
<section id="comments">
|
||||
<div class="notice">
|
||||
<p class="bottom">This post is password protected. Enter the password to view comments.</p>
|
||||
</div>
|
||||
</section>
|
||||
<?php
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<?php // You can start editing here. ?>
|
||||
<?php if ( have_comments() ) : ?>
|
||||
<section id="comments">
|
||||
<h3><?php comments_number('No Responses', 'One Response', '% Responses' );?> to “<?php the_title(); ?>”</h3>
|
||||
<ol class="commentlist">
|
||||
<?php wp_list_comments('type=comment&callback=roots_comments'); ?>
|
||||
<?php // wp_list_comments(); ?>
|
||||
</ol>
|
||||
<footer>
|
||||
<nav id="comments-nav">
|
||||
<div class="comments-previous"><?php previous_comments_link( __( '← Older comments', 'roots' ) ); ?></div>
|
||||
<div class="comments-next"><?php next_comments_link( __( 'Newer comments →', 'roots' ) ); ?></div>
|
||||
</nav>
|
||||
</footer>
|
||||
</section>
|
||||
<?php else : // this is displayed if there are no comments so far ?>
|
||||
<?php if ( comments_open() ) : ?>
|
||||
<?php else : // comments are closed ?>
|
||||
<section id="comments">
|
||||
<div class="notice">
|
||||
<p class="bottom">Comments are closed.</p>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
<?php if ( comments_open() ) : ?>
|
||||
<section id="respond">
|
||||
<h3><?php comment_form_title( 'Leave a Reply', 'Leave a Reply to %s' ); ?></h3>
|
||||
<p class="cancel-comment-reply"><?php cancel_comment_reply_link(); ?></p>
|
||||
<?php if ( get_option('comment_registration') && !is_user_logged_in() ) : ?>
|
||||
<p>You must be <a href="<?php echo wp_login_url( get_permalink() ); ?>">logged in</a> to post a comment.</p>
|
||||
<?php else : ?>
|
||||
<form action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform">
|
||||
<?php if ( is_user_logged_in() ) : ?>
|
||||
<p>Logged in as <a href="<?php echo get_option('siteurl'); ?>/wp-admin/profile.php"><?php echo $user_identity; ?></a>. <a href="<?php echo wp_logout_url(get_permalink()); ?>" title="Log out of this account">Log out »</a></p>
|
||||
<?php else : ?>
|
||||
<p>
|
||||
<label for="author">Name <?php if ($req) echo "(required)"; ?></label>
|
||||
<input type="text" class="text" name="author" id="author" value="<?php echo esc_attr($comment_author); ?>" size="22" tabindex="1" <?php if ($req) echo "aria-required='true'"; ?>>
|
||||
</p>
|
||||
<p>
|
||||
<label for="email">Email (will not be published) <?php if ($req) echo "(required)"; ?></label>
|
||||
<input type="email" class="text" name="email" id="email" value="<?php echo esc_attr($comment_author_email); ?>" size="22" tabindex="2" <?php if ($req) echo "aria-required='true'"; ?>>
|
||||
</p>
|
||||
<p>
|
||||
<label for="url">Website</label>
|
||||
<input type="url" class="text" name="url" id="url" value="<?php echo esc_attr($comment_author_url); ?>" size="22" tabindex="3">
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<p><textarea name="comment" id="comment" rows="10" tabindex="4"></textarea></p>
|
||||
<p><input name="submit" class="button" type="submit" id="submit" tabindex="5" value="Submit Comment"></p>
|
||||
<?php comment_id_fields(); ?>
|
||||
<?php do_action('comment_form', $post->ID); ?>
|
||||
</form>
|
||||
<?php endif; // If registration required and not logged in ?>
|
||||
</section>
|
||||
<?php endif; // if you delete this the sky will fall on your head ?>
|
||||
22
css/blueprint/LICENSE
Normal file
@@ -0,0 +1,22 @@
|
||||
Copyright (c) 2007 - 2010 blueprintcss.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
36
css/blueprint/ie.css
Normal file
@@ -0,0 +1,36 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
|
||||
|
||||
Blueprint CSS Framework 1.0
|
||||
http://blueprintcss.org
|
||||
|
||||
* Copyright (c) 2007-Present. See LICENSE for more info.
|
||||
* See README for instructions on how to use Blueprint.
|
||||
* For credits and origins, see AUTHORS.
|
||||
* This is a compressed file. See the sources in the 'src' directory.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
/* ie.css */
|
||||
body {text-align:center;}
|
||||
.container {text-align:left;}
|
||||
* html .column, * html .span-1, * html .span-2, * html .span-3, * html .span-4, * html .span-5, * html .span-6, * html .span-7, * html .span-8, * html .span-9, * html .span-10, * html .span-11, * html .span-12, * html .span-13, * html .span-14, * html .span-15, * html .span-16, * html .span-17, * html .span-18, * html .span-19, * html .span-20, * html .span-21, * html .span-22, * html .span-23, * html .span-24 {display:inline;overflow-x:hidden;}
|
||||
* html legend {margin:0px -8px 16px 0;padding:0;}
|
||||
sup {vertical-align:text-top;}
|
||||
sub {vertical-align:text-bottom;}
|
||||
html>body p code {*white-space:normal;}
|
||||
hr {margin:-8px auto 11px;}
|
||||
img {-ms-interpolation-mode:bicubic;}
|
||||
.clearfix, .container {display:inline-block;}
|
||||
* html .clearfix, * html .container {height:1%;}
|
||||
fieldset {padding-top:0;}
|
||||
legend {margin-top:-0.2em;margin-bottom:1em;margin-left:-0.5em;}
|
||||
textarea {overflow:auto;}
|
||||
label {vertical-align:middle;position:relative;top:-0.25em;}
|
||||
input.text, input.title, textarea {background-color:#fff;border:1px solid #bbb;}
|
||||
input.text:focus, input.title:focus {border-color:#666;}
|
||||
input.text, input.title, textarea, select {margin:0.5em 0;}
|
||||
input.checkbox, input.radio {position:relative;top:.25em;}
|
||||
form.inline div, form.inline p {vertical-align:middle;}
|
||||
form.inline input.checkbox, form.inline input.radio, form.inline input.button, form.inline button {margin:0.5em 0;}
|
||||
button, input.button {position:relative;top:0.25em;}
|
||||
29
css/blueprint/print.css
Normal file
@@ -0,0 +1,29 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
|
||||
|
||||
Blueprint CSS Framework 1.0
|
||||
http://blueprintcss.org
|
||||
|
||||
* Copyright (c) 2007-Present. See LICENSE for more info.
|
||||
* See README for instructions on how to use Blueprint.
|
||||
* For credits and origins, see AUTHORS.
|
||||
* This is a compressed file. See the sources in the 'src' directory.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
/* print.css */
|
||||
body {line-height:1.5;font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;color:#000;background:none;font-size:10pt;}
|
||||
.container {background:none;}
|
||||
hr {background:#ccc;color:#ccc;width:100%;height:2px;margin:2em 0;padding:0;border:none;}
|
||||
hr.space {background:#fff;color:#fff;visibility:hidden;}
|
||||
h1, h2, h3, h4, h5, h6 {font-family:"Helvetica Neue", Arial, "Lucida Grande", sans-serif;}
|
||||
code {font:.9em "Courier New", Monaco, Courier, monospace;}
|
||||
a img {border:none;}
|
||||
p img.top {margin-top:0;}
|
||||
blockquote {margin:1.5em;padding:1em;font-style:italic;font-size:.9em;}
|
||||
.small {font-size:.9em;}
|
||||
.large {font-size:1.1em;}
|
||||
.quiet {color:#999;}
|
||||
.hide {display:none;}
|
||||
a:link, a:visited {background:transparent;font-weight:700;text-decoration:underline;}
|
||||
a:link:after, a:visited:after {content:" (" attr(href) ")";font-size:90%;}
|
||||
264
css/blueprint/screen.css
Normal file
@@ -0,0 +1,264 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
|
||||
|
||||
Blueprint CSS Framework 1.0
|
||||
http://blueprintcss.org
|
||||
|
||||
* Copyright (c) 2007-Present. See LICENSE for more info.
|
||||
* See README for instructions on how to use Blueprint.
|
||||
* For credits and origins, see AUTHORS.
|
||||
* This is a compressed file. See the sources in the 'src' directory.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
/* reset.css */
|
||||
html {margin:0;padding:0;border:0;}
|
||||
body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, code, del, dfn, em, img, q, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, dialog, figure, footer, header, hgroup, nav, section {margin:0;padding:0;border:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline;}
|
||||
article, aside, dialog, figure, footer, header, hgroup, nav, section {display:block;}
|
||||
body {line-height:1.5;background:white;}
|
||||
table {border-collapse:separate;border-spacing:0;}
|
||||
caption, th, td {text-align:left;font-weight:normal;float:none !important;}
|
||||
table, th, td {vertical-align:middle;}
|
||||
blockquote:before, blockquote:after, q:before, q:after {content:'';}
|
||||
blockquote, q {quotes:"" "";}
|
||||
a img {border:none;}
|
||||
:focus {outline:0;}
|
||||
|
||||
/* typography.css */
|
||||
html {font-size:100.01%;}
|
||||
body {font-size:75%;color:#222;background:#fff;font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;}
|
||||
h1, h2, h3, h4, h5, h6 {font-weight:normal;color:#111;}
|
||||
h1 {font-size:3em;line-height:1;margin-bottom:0.5em;}
|
||||
h2 {font-size:2em;margin-bottom:0.75em;}
|
||||
h3 {font-size:1.5em;line-height:1;margin-bottom:1em;}
|
||||
h4 {font-size:1.2em;line-height:1.25;margin-bottom:1.25em;}
|
||||
h5 {font-size:1em;font-weight:bold;margin-bottom:1.5em;}
|
||||
h6 {font-size:1em;font-weight:bold;}
|
||||
h1 img, h2 img, h3 img, h4 img, h5 img, h6 img {margin:0;}
|
||||
p {margin:0 0 1.5em;}
|
||||
.left {float:left !important;}
|
||||
p .left {margin:1.5em 1.5em 1.5em 0;padding:0;}
|
||||
.right {float:right !important;}
|
||||
p .right {margin:1.5em 0 1.5em 1.5em;padding:0;}
|
||||
a:focus, a:hover {color:#09f;}
|
||||
a {color:#06c;text-decoration:underline;}
|
||||
blockquote {margin:1.5em;color:#666;font-style:italic;}
|
||||
strong, dfn {font-weight:bold;}
|
||||
em, dfn {font-style:italic;}
|
||||
sup, sub {line-height:0;}
|
||||
abbr, acronym {border-bottom:1px dotted #666;}
|
||||
address {margin:0 0 1.5em;font-style:italic;}
|
||||
del {color:#666;}
|
||||
pre {margin:1.5em 0;white-space:pre;}
|
||||
pre, code, tt {font:1em 'andale mono', 'lucida console', monospace;line-height:1.5;}
|
||||
li ul, li ol {margin:0;}
|
||||
ul, ol {margin:0 1.5em 1.5em 0;padding-left:1.5em;}
|
||||
ul {list-style-type:disc;}
|
||||
ol {list-style-type:decimal;}
|
||||
dl {margin:0 0 1.5em 0;}
|
||||
dl dt {font-weight:bold;}
|
||||
dd {margin-left:1.5em;}
|
||||
table {margin-bottom:1.4em;width:100%;}
|
||||
th {font-weight:bold;}
|
||||
thead th {background:#c3d9ff;}
|
||||
th, td, caption {padding:4px 10px 4px 5px;}
|
||||
tbody tr:nth-child(even) td, tbody tr.even td {background:#e5ecf9;}
|
||||
tfoot {font-style:italic;}
|
||||
caption {background:#eee;}
|
||||
.small {font-size:.8em;margin-bottom:1.875em;line-height:1.875em;}
|
||||
.large {font-size:1.2em;line-height:2.5em;margin-bottom:1.25em;}
|
||||
.hide {display:none;}
|
||||
.quiet {color:#666;}
|
||||
.loud {color:#000;}
|
||||
.highlight {background:#ff0;}
|
||||
.added {background:#060;color:#fff;}
|
||||
.removed {background:#900;color:#fff;}
|
||||
.first {margin-left:0;padding-left:0;}
|
||||
.last {margin-right:0;padding-right:0;}
|
||||
.top {margin-top:0;padding-top:0;}
|
||||
.bottom {margin-bottom:0;padding-bottom:0;}
|
||||
|
||||
/* forms.css */
|
||||
label {font-weight:bold;}
|
||||
fieldset {padding:0 1.4em 1.4em 1.4em;margin:0 0 1.5em 0;border:1px solid #ccc;}
|
||||
legend {font-weight:bold;font-size:1.2em;margin-top:-0.2em;margin-bottom:1em;}
|
||||
fieldset, #IE8#HACK {padding-top:1.4em;}
|
||||
legend, #IE8#HACK {margin-top:0;margin-bottom:0;}
|
||||
input[type=text], input[type=password], input.text, input.title, textarea {background-color:#fff;border:1px solid #bbb;}
|
||||
input[type=text]:focus, input[type=password]:focus, input.text:focus, input.title:focus, textarea:focus {border-color:#666;}
|
||||
select {background-color:#fff;border-width:1px;border-style:solid;}
|
||||
input[type=text], input[type=password], input.text, input.title, textarea, select {margin:0.5em 0;}
|
||||
input.text, input.title {width:300px;padding:5px;}
|
||||
input.title {font-size:1.5em;}
|
||||
textarea {width:390px;height:250px;padding:5px;}
|
||||
form.inline {line-height:3;}
|
||||
form.inline p {margin-bottom:0;}
|
||||
.error, .alert, .notice, .success, .info {padding:0.8em;margin-bottom:1em;border:2px solid #ddd;}
|
||||
.error, .alert {background:#fbe3e4;color:#8a1f11;border-color:#fbc2c4;}
|
||||
.notice {background:#fff6bf;color:#514721;border-color:#ffd324;}
|
||||
.success {background:#e6efc2;color:#264409;border-color:#c6d880;}
|
||||
.info {background:#d5edf8;color:#205791;border-color:#92cae4;}
|
||||
.error a, .alert a {color:#8a1f11;}
|
||||
.notice a {color:#514721;}
|
||||
.success a {color:#264409;}
|
||||
.info a {color:#205791;}
|
||||
|
||||
/* grid.css */
|
||||
.container {width:950px;margin:0 auto;}
|
||||
.column, .span-1, .span-2, .span-3, .span-4, .span-5, .span-6, .span-7, .span-8, .span-9, .span-10, .span-11, .span-12, .span-13, .span-14, .span-15, .span-16, .span-17, .span-18, .span-19, .span-20, .span-21, .span-22, .span-23, .span-24 {float:left;margin-right:10px;}
|
||||
.last {margin-right:0;}
|
||||
.span-1 {width:30px;}
|
||||
.span-2 {width:70px;}
|
||||
.span-3 {width:110px;}
|
||||
.span-4 {width:150px;}
|
||||
.span-5 {width:190px;}
|
||||
.span-6 {width:230px;}
|
||||
.span-7 {width:270px;}
|
||||
.span-8 {width:310px;}
|
||||
.span-9 {width:350px;}
|
||||
.span-10 {width:390px;}
|
||||
.span-11 {width:430px;}
|
||||
.span-12 {width:470px;}
|
||||
.span-13 {width:510px;}
|
||||
.span-14 {width:550px;}
|
||||
.span-15 {width:590px;}
|
||||
.span-16 {width:630px;}
|
||||
.span-17 {width:670px;}
|
||||
.span-18 {width:710px;}
|
||||
.span-19 {width:750px;}
|
||||
.span-20 {width:790px;}
|
||||
.span-21 {width:830px;}
|
||||
.span-22 {width:870px;}
|
||||
.span-23 {width:910px;}
|
||||
.span-24 {width:950px;margin-right:0;}
|
||||
input.span-1, textarea.span-1, input.span-2, textarea.span-2, input.span-3, textarea.span-3, input.span-4, textarea.span-4, input.span-5, textarea.span-5, input.span-6, textarea.span-6, input.span-7, textarea.span-7, input.span-8, textarea.span-8, input.span-9, textarea.span-9, input.span-10, textarea.span-10, input.span-11, textarea.span-11, input.span-12, textarea.span-12, input.span-13, textarea.span-13, input.span-14, textarea.span-14, input.span-15, textarea.span-15, input.span-16, textarea.span-16, input.span-17, textarea.span-17, input.span-18, textarea.span-18, input.span-19, textarea.span-19, input.span-20, textarea.span-20, input.span-21, textarea.span-21, input.span-22, textarea.span-22, input.span-23, textarea.span-23, input.span-24, textarea.span-24 {border-left-width:1px;border-right-width:1px;padding-left:5px;padding-right:5px;}
|
||||
input.span-1, textarea.span-1 {width:18px;}
|
||||
input.span-2, textarea.span-2 {width:58px;}
|
||||
input.span-3, textarea.span-3 {width:98px;}
|
||||
input.span-4, textarea.span-4 {width:138px;}
|
||||
input.span-5, textarea.span-5 {width:178px;}
|
||||
input.span-6, textarea.span-6 {width:218px;}
|
||||
input.span-7, textarea.span-7 {width:258px;}
|
||||
input.span-8, textarea.span-8 {width:298px;}
|
||||
input.span-9, textarea.span-9 {width:338px;}
|
||||
input.span-10, textarea.span-10 {width:378px;}
|
||||
input.span-11, textarea.span-11 {width:418px;}
|
||||
input.span-12, textarea.span-12 {width:458px;}
|
||||
input.span-13, textarea.span-13 {width:498px;}
|
||||
input.span-14, textarea.span-14 {width:538px;}
|
||||
input.span-15, textarea.span-15 {width:578px;}
|
||||
input.span-16, textarea.span-16 {width:618px;}
|
||||
input.span-17, textarea.span-17 {width:658px;}
|
||||
input.span-18, textarea.span-18 {width:698px;}
|
||||
input.span-19, textarea.span-19 {width:738px;}
|
||||
input.span-20, textarea.span-20 {width:778px;}
|
||||
input.span-21, textarea.span-21 {width:818px;}
|
||||
input.span-22, textarea.span-22 {width:858px;}
|
||||
input.span-23, textarea.span-23 {width:898px;}
|
||||
input.span-24, textarea.span-24 {width:938px;}
|
||||
.append-1 {padding-right:40px;}
|
||||
.append-2 {padding-right:80px;}
|
||||
.append-3 {padding-right:120px;}
|
||||
.append-4 {padding-right:160px;}
|
||||
.append-5 {padding-right:200px;}
|
||||
.append-6 {padding-right:240px;}
|
||||
.append-7 {padding-right:280px;}
|
||||
.append-8 {padding-right:320px;}
|
||||
.append-9 {padding-right:360px;}
|
||||
.append-10 {padding-right:400px;}
|
||||
.append-11 {padding-right:440px;}
|
||||
.append-12 {padding-right:480px;}
|
||||
.append-13 {padding-right:520px;}
|
||||
.append-14 {padding-right:560px;}
|
||||
.append-15 {padding-right:600px;}
|
||||
.append-16 {padding-right:640px;}
|
||||
.append-17 {padding-right:680px;}
|
||||
.append-18 {padding-right:720px;}
|
||||
.append-19 {padding-right:760px;}
|
||||
.append-20 {padding-right:800px;}
|
||||
.append-21 {padding-right:840px;}
|
||||
.append-22 {padding-right:880px;}
|
||||
.append-23 {padding-right:920px;}
|
||||
.prepend-1 {padding-left:40px;}
|
||||
.prepend-2 {padding-left:80px;}
|
||||
.prepend-3 {padding-left:120px;}
|
||||
.prepend-4 {padding-left:160px;}
|
||||
.prepend-5 {padding-left:200px;}
|
||||
.prepend-6 {padding-left:240px;}
|
||||
.prepend-7 {padding-left:280px;}
|
||||
.prepend-8 {padding-left:320px;}
|
||||
.prepend-9 {padding-left:360px;}
|
||||
.prepend-10 {padding-left:400px;}
|
||||
.prepend-11 {padding-left:440px;}
|
||||
.prepend-12 {padding-left:480px;}
|
||||
.prepend-13 {padding-left:520px;}
|
||||
.prepend-14 {padding-left:560px;}
|
||||
.prepend-15 {padding-left:600px;}
|
||||
.prepend-16 {padding-left:640px;}
|
||||
.prepend-17 {padding-left:680px;}
|
||||
.prepend-18 {padding-left:720px;}
|
||||
.prepend-19 {padding-left:760px;}
|
||||
.prepend-20 {padding-left:800px;}
|
||||
.prepend-21 {padding-left:840px;}
|
||||
.prepend-22 {padding-left:880px;}
|
||||
.prepend-23 {padding-left:920px;}
|
||||
.border {padding-right:4px;margin-right:5px;border-right:1px solid #ddd;}
|
||||
.colborder {padding-right:24px;margin-right:25px;border-right:1px solid #ddd;}
|
||||
.pull-1 {margin-left:-40px;}
|
||||
.pull-2 {margin-left:-80px;}
|
||||
.pull-3 {margin-left:-120px;}
|
||||
.pull-4 {margin-left:-160px;}
|
||||
.pull-5 {margin-left:-200px;}
|
||||
.pull-6 {margin-left:-240px;}
|
||||
.pull-7 {margin-left:-280px;}
|
||||
.pull-8 {margin-left:-320px;}
|
||||
.pull-9 {margin-left:-360px;}
|
||||
.pull-10 {margin-left:-400px;}
|
||||
.pull-11 {margin-left:-440px;}
|
||||
.pull-12 {margin-left:-480px;}
|
||||
.pull-13 {margin-left:-520px;}
|
||||
.pull-14 {margin-left:-560px;}
|
||||
.pull-15 {margin-left:-600px;}
|
||||
.pull-16 {margin-left:-640px;}
|
||||
.pull-17 {margin-left:-680px;}
|
||||
.pull-18 {margin-left:-720px;}
|
||||
.pull-19 {margin-left:-760px;}
|
||||
.pull-20 {margin-left:-800px;}
|
||||
.pull-21 {margin-left:-840px;}
|
||||
.pull-22 {margin-left:-880px;}
|
||||
.pull-23 {margin-left:-920px;}
|
||||
.pull-24 {margin-left:-960px;}
|
||||
.pull-1, .pull-2, .pull-3, .pull-4, .pull-5, .pull-6, .pull-7, .pull-8, .pull-9, .pull-10, .pull-11, .pull-12, .pull-13, .pull-14, .pull-15, .pull-16, .pull-17, .pull-18, .pull-19, .pull-20, .pull-21, .pull-22, .pull-23, .pull-24 {float:left;position:relative;}
|
||||
.push-1 {margin:0 -40px 1.5em 40px;}
|
||||
.push-2 {margin:0 -80px 1.5em 80px;}
|
||||
.push-3 {margin:0 -120px 1.5em 120px;}
|
||||
.push-4 {margin:0 -160px 1.5em 160px;}
|
||||
.push-5 {margin:0 -200px 1.5em 200px;}
|
||||
.push-6 {margin:0 -240px 1.5em 240px;}
|
||||
.push-7 {margin:0 -280px 1.5em 280px;}
|
||||
.push-8 {margin:0 -320px 1.5em 320px;}
|
||||
.push-9 {margin:0 -360px 1.5em 360px;}
|
||||
.push-10 {margin:0 -400px 1.5em 400px;}
|
||||
.push-11 {margin:0 -440px 1.5em 440px;}
|
||||
.push-12 {margin:0 -480px 1.5em 480px;}
|
||||
.push-13 {margin:0 -520px 1.5em 520px;}
|
||||
.push-14 {margin:0 -560px 1.5em 560px;}
|
||||
.push-15 {margin:0 -600px 1.5em 600px;}
|
||||
.push-16 {margin:0 -640px 1.5em 640px;}
|
||||
.push-17 {margin:0 -680px 1.5em 680px;}
|
||||
.push-18 {margin:0 -720px 1.5em 720px;}
|
||||
.push-19 {margin:0 -760px 1.5em 760px;}
|
||||
.push-20 {margin:0 -800px 1.5em 800px;}
|
||||
.push-21 {margin:0 -840px 1.5em 840px;}
|
||||
.push-22 {margin:0 -880px 1.5em 880px;}
|
||||
.push-23 {margin:0 -920px 1.5em 920px;}
|
||||
.push-24 {margin:0 -960px 1.5em 960px;}
|
||||
.push-1, .push-2, .push-3, .push-4, .push-5, .push-6, .push-7, .push-8, .push-9, .push-10, .push-11, .push-12, .push-13, .push-14, .push-15, .push-16, .push-17, .push-18, .push-19, .push-20, .push-21, .push-22, .push-23, .push-24 {float:left;position:relative;}
|
||||
div.prepend-top, .prepend-top {margin-top:1.5em;}
|
||||
div.append-bottom, .append-bottom {margin-bottom:1.5em;}
|
||||
.box {padding:1.5em;margin-bottom:1.5em;background:#e5eCf9;}
|
||||
hr {background:#ddd;color:#ddd;clear:both;float:none;width:100%;height:1px;margin:0 0 1.45em;border:none;}
|
||||
hr.space {background:#fff;color:#fff;visibility:hidden;}
|
||||
.clearfix:after, .container:after {content:"\0020";display:block;height:0;clear:both;visibility:hidden;overflow:hidden;}
|
||||
.clearfix, .container {display:block;}
|
||||
.clear {clear:both;}
|
||||
454
css/style.css
Normal file
@@ -0,0 +1,454 @@
|
||||
/* GENERAL
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------------- */
|
||||
/* Typography */
|
||||
html { overflow-y: scroll; }
|
||||
body { background: #fff; }
|
||||
|
||||
a { color: #06c; }
|
||||
a:hover, a:focus { color:#09f; }
|
||||
a:hover, a:active { outline: none; }
|
||||
a:active, input.button:active { outline: 0; position: relative; top: 1px; }
|
||||
|
||||
h1, h2, h3, h4, h5, h6 { text-shadow: 0 1px 1px rgba(0, 0, 0, 0.15); }
|
||||
|
||||
ul.none { margin: 0 0 1.5em 0; padding: 0; list-style: none; }
|
||||
.icon { vertical-align: middle; }
|
||||
.large { line-height: 1.5em; }
|
||||
.center { text-align: center; }
|
||||
.aligncenter { display: block; margin: 0 auto; }
|
||||
img.left, p img.left, .alignleft { margin: 0 1.5em 1.5em 0; float: left; }
|
||||
img.right, p img.right, .alignright { margin: 0 0 1.5em 1.5em; float: right; }
|
||||
.wp-caption { border: 1px solid #ddd; text-align: center; background: #eee; padding: 14px 10px 6px 10px; margin: 15px 10px; }
|
||||
.wp-caption-text { margin: 0; }
|
||||
.ir { display: block; text-indent: -999em; overflow: hidden; background-repeat: no-repeat; text-align: left; direction: ltr; }
|
||||
.hidden { display: none; visibility: hidden; }
|
||||
.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
|
||||
.visuallyhidden.focusable:active,
|
||||
.visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; }
|
||||
.invisible { visibility: hidden; }
|
||||
|
||||
::-moz-selection { text-shadow: none; background: #3399FF; color: #fff; }
|
||||
::selection { text-shadow: none; background: #3399FF; color: #fff; }
|
||||
a:link { -webkit-tap-highlight-color: #3399FF; }
|
||||
|
||||
.button, #post-nav a, #comments-nav a {
|
||||
display: inline-block;
|
||||
background: #06c;
|
||||
background-image: -moz-linear-gradient(top, rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.1));
|
||||
background-image: -o-linear-gradient(top, rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.1));
|
||||
background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.1));
|
||||
background-image: linear-gradient(top, rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.1));
|
||||
-moz-border-radius: 6px;
|
||||
-webkit-border-radius: 6px;
|
||||
border-radius: 6px;
|
||||
color: #fff;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
text-shadow: -1px -1px 0 rgba(0, 0, 0, 0.15);
|
||||
width: auto;
|
||||
overflow: visible;
|
||||
-moz-box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2), 1px 1px 3px rgba(0, 0, 0, 0.2) inset;
|
||||
-webkit-box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2), 1px 1px 3px rgba(0, 0, 0, 0.2) inset;
|
||||
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2), 1px 1px 3px rgba(0, 0, 0, 0.2) inset;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
.button:hover, #post-nav a:hover, #comments-nav a:hover {
|
||||
background: #09f;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Forms */
|
||||
input, select, textarea { font-family: sans-serif; font-size: 1em; }
|
||||
button, input, select, textarea { margin: 0; }
|
||||
label, input[type=button], input[type=submit], button { cursor: pointer; }
|
||||
button { width: auto; overflow: visible; }
|
||||
textarea { overflow: auto; }
|
||||
|
||||
/* Grid */
|
||||
#wrap { }
|
||||
hr { background: #ddd; color: #ddd; }
|
||||
|
||||
|
||||
/* HEADER
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------------- */
|
||||
#banner { position: relative; margin: 16px auto; z-index: 1000; }
|
||||
|
||||
#logo { float: left; width: 300px; height: 75px; margin: 0 0 16px; padding: 0; }
|
||||
|
||||
#nav-main ul {
|
||||
background: #06c;
|
||||
background-image: -moz-linear-gradient(top, rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.1));
|
||||
background-image: -o-linear-gradient(top, rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.1));
|
||||
background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.1));
|
||||
background-image: linear-gradient(top, rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.1));
|
||||
position: relative;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
float: left;
|
||||
width: 100%;
|
||||
-moz-border-radius: 6px;
|
||||
-webkit-border-radius: 6px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
#nav-main ul li { float: left; }
|
||||
#nav-main ul li:hover { position: relative; }
|
||||
#nav-main ul li a {
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
padding: 8px 16px;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
text-shadow: -1px -1px 0 rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
#nav-main ul li a:hover,
|
||||
#nav-main ul li.current_page_item > a,
|
||||
#nav-main ul li.current_page_parent > a,
|
||||
#nav-main ul li.current_page_ancestor > a,
|
||||
#nav-main ul li.current-cat > a,
|
||||
#nav-main ul li.current-cat-parent > a,
|
||||
#nav-main ul li.current-category-ancestor > a,
|
||||
#nav-main ul li.current-menu-item > a,
|
||||
#nav-main ul li.current-menu-parent > a,
|
||||
#nav-main ul li.current-post-parent > a,
|
||||
#nav-main ul li.current-post-ancestor > a,
|
||||
#nav-main ul li:hover > a {
|
||||
color: #73C8FF;
|
||||
}
|
||||
|
||||
#nav-main ul ul {
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
width: 200px;
|
||||
background: #73C8FF;
|
||||
padding: 0;
|
||||
-moz-border-radius: 0;
|
||||
-webkit-border-radius: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
#nav-main ul ul li { float: none; }
|
||||
#nav-main ul ul li a {
|
||||
font-size: 12px;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.1);
|
||||
padding: 4px 16px;
|
||||
width: 168px; /* account for the width of ul#nav-main ul and the padding on the anchor */
|
||||
display: inline-block;
|
||||
|
||||
}
|
||||
#nav-main ul ul li a:hover,
|
||||
#nav-main ul ul li.current_page_item > a,
|
||||
#nav-main ul ul li.current_page_parent > a,
|
||||
#nav-main ul ul li.current_page_ancestor > a,
|
||||
#nav-main ul ul li.current-cat > a,
|
||||
#nav-main ul ul li.current-cat-parent > a,
|
||||
#nav-main ul ul li.current-category-ancestor > a,
|
||||
#nav-main ul ul li.current-menu-item > a,
|
||||
#nav-main ul ul li.current-menu-parent > a,
|
||||
#nav-main ul ul li.current-post-parent > a,
|
||||
#nav-main ul ul li.current-post-ancestor > a,
|
||||
#nav-main ul ul li:hover > a {
|
||||
color: #06c;
|
||||
}
|
||||
|
||||
#nav-main ul ul ul { left: 100%; top: 0; }
|
||||
#nav-main ul li:hover > ul { visibility: visible; }
|
||||
|
||||
#nav-utility { position: absolute; top: 0; right: 0; }
|
||||
#nav-utility ul { list-style: none; margin: 0; padding: 0; float: right; width: auto; position: relative; }
|
||||
#nav-utility ul li { float: left; position: relative; }
|
||||
#nav-utility ul li a { display: block; float: left; padding: 2px 6px; }
|
||||
|
||||
|
||||
/* CONTENT
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------------- */
|
||||
#content { margin-bottom: 24px; }
|
||||
#content .container { width: auto; position: relative; }
|
||||
|
||||
#main { position: relative; }
|
||||
|
||||
/* Posts */
|
||||
.hentry header { margin-bottom: 1.5em; }
|
||||
.hentry h1 { line-height: 1.2em; margin-bottom: 0.2em; }
|
||||
.hentry h2:first-child { line-height: 1.2em; margin-bottom: 0; }
|
||||
.hentry h2 a { text-decoration: none; }
|
||||
.hentry iframe.twitter-share-button { position: absolute; top: 0; right: 0; width: 110px; height: 20px; }
|
||||
.hentry time { display: block; font-size: 1.2em; position: relative; }
|
||||
.hentry p.byline { }
|
||||
|
||||
/* Post, page, comment navigation */
|
||||
#post-nav { clear: both; }
|
||||
#post-nav:after { content: "\0020"; display: block; height: 0; clear: both; visibility: hidden; overflow: hidden; }
|
||||
#post-nav .post-previous { float: left; width: 50%; }
|
||||
#post-nav .post-next { float: right; width: 50%; text-align: right; }
|
||||
#post-nav .post-next a { float: right; }
|
||||
|
||||
#comments-nav { clear: both; margin: 0 0 1.5em 0; }
|
||||
#comments-nav:after { content: "\0020"; display: block; height: 0; clear: both; visibility: hidden; overflow: hidden; }
|
||||
#comments-nav .comments-previous { float: left; width: 50%; }
|
||||
#comments-nav .comments-next { float: right; width: 50%; text-align: right; }
|
||||
#comments-nav .comments-next a { float: right; }
|
||||
|
||||
/* Post comments */
|
||||
ol.commentlist img.avatar { float: left; margin-right: 10px; }
|
||||
ol.commentlist time { display: block; font-size: 1em; margin-bottom: 0.5em; position: relative; }
|
||||
ol.commentlist .comment-reply-link { display: block; margin-bottom: 1.5em; }
|
||||
#commentform p { margin-bottom: 1em; }
|
||||
#commentform label { display: block; }
|
||||
#commentform textarea { display: block; }
|
||||
#commentform input.button { margin-top: 0.5em; }
|
||||
#commentform:after { content: "\0020"; display: block; height: 0; clear: both; visibility: hidden; overflow: hidden; }
|
||||
|
||||
/* Gallery */
|
||||
figure.gallery-item { float: left; margin: 0 1em 1em 0; position: relative; }
|
||||
figure.gallery-item a img {
|
||||
border: 4px solid #bbb;
|
||||
-moz-border-radius: 6px;
|
||||
-webkit-border-radius: 6px;
|
||||
border-radius: 6px;
|
||||
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
figure.gallery-item a:hover img { border-color: #ccc; }
|
||||
figure.gallery-item figcaption { display: none; }
|
||||
|
||||
/* Primary Sidebar */
|
||||
#sidebar { position: relative; }
|
||||
#sidebar .container { width: auto; }
|
||||
#sidebar .widget { clear: both; margin-bottom: 1.5em; }
|
||||
#sidebar .widget .gform_wrapper ul { padding: 0; list-style-type: none; }
|
||||
|
||||
|
||||
/* FOOTER
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------------- */
|
||||
#content-info { clear: both; position: relative; }
|
||||
#content-info > .container { padding-bottom: 1.5em; }
|
||||
|
||||
#content-info ul.menu { margin: 0 0 24px; padding: 0; list-style-type: none; }
|
||||
#content-info ul.menu li { display: inline; margin-right: 1em; }
|
||||
|
||||
#content-info p.copy small { font-size: 1em; }
|
||||
|
||||
#content-info p.social .twitter-share-button { float: left; }
|
||||
#content-info p.social .fb_iframe_widget { float: left; }
|
||||
|
||||
#content-info p.vcard { position: absolute; top: 0; right: 0; margin: 0; text-align: right; }
|
||||
#content-info p.vcard a.fn { font-size: 14px; }
|
||||
|
||||
|
||||
/* WIDGETS & PLUGINS
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------------- */
|
||||
/* Gravity Forms */
|
||||
.gform_wrapper { margin: 0; max-width: none; }
|
||||
.gform_wrapper .gform_heading { width: 100%; margin-bottom: 1.5em; }
|
||||
.gform_wrapper .gsection .gfield_label, .gform_wrapper h2.gsection_title, .gform_wrapper h3.gform_title { font-size: 1.5em; font-weight: 400; }
|
||||
.gform_wrapper h3.gform_title { margin-top: 0; }
|
||||
.gform_wrapper .top_label .gfield_label { margin: 6px 0 0 0; }
|
||||
.gform_wrapper .top_label input.medium { padding-right: 0; }
|
||||
.gform_wrapper .left_label .gfield_label,
|
||||
.gform_wrapper .right_label .gfield_label { margin: 10px 10px 0 0; }
|
||||
.gform_wrapper .left_label ul.gfield_checkbox,
|
||||
.gform_wrapper .left_label ul.gfield_radio,
|
||||
.gform_wrapper .right_label ul.gfield_checkbox,
|
||||
.gform_wrapper .right_label ul.gfield_radio {
|
||||
margin: 9px 0 0 31%;
|
||||
}
|
||||
.gform_wrapper input[type=text],
|
||||
.gform_wrapper input[type=url],
|
||||
.gform_wrapper input[type=email],
|
||||
.gform_wrapper input[type=tel],
|
||||
.gform_wrapper input[type=file],
|
||||
.gform_wrapper input[type=number],
|
||||
.gform_wrapper input[type=password],
|
||||
.gform_wrapper textarea,
|
||||
.gform_wrapper select {
|
||||
font-size: 1em;
|
||||
line-height: 14px;
|
||||
padding: 4px;
|
||||
margin: 6px 0;
|
||||
border: 1px solid #bbb;
|
||||
-moz-background-clip: padding;
|
||||
-webkit-background-clip: padding;
|
||||
background-clip: padding-box;
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.gform_wrapper input[type=text]:focus,
|
||||
.gform_wrapper input[type=url]:focus,
|
||||
.gform_wrapper input[type=email]:focus,
|
||||
.gform_wrapper input[type=tel]:focus,
|
||||
.gform_wrapper input[type=number]:focus,
|
||||
.gform_wrapper input[type=password]:focus,
|
||||
.gform_wrapper textarea:focus,
|
||||
.gform_wrapper select:focus {
|
||||
border: 1px solid #666;
|
||||
}
|
||||
.gform_wrapper select { padding: 3px; }
|
||||
.gform_wrapper .small, .gform_wrapper .large { font-size: 1em; line-height: 14px; }
|
||||
.gform_wrapper ul.right_label li,
|
||||
.gform_wrapper ul.left_label li,
|
||||
.gform_wrapper form ul.right_label li,
|
||||
.gform_wrapper form ul.left_label li {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.gform_wrapper .description,
|
||||
.gform_wrapper .gfield_description,
|
||||
.gform_wrapper .gsection_description,
|
||||
.gform_wrapper .instruction {
|
||||
font-size: 0.9em;
|
||||
font-style: normal;
|
||||
padding: 0;
|
||||
}
|
||||
.gform_wrapper .right_label .gfield_description,
|
||||
.gform_wrapper .right_label .instruction,
|
||||
.gform_wrapper .left_label .gfield_description,
|
||||
.gform_wrapper .left_label .instruction {
|
||||
padding: 0;
|
||||
margin-left: 31%;
|
||||
}
|
||||
.gform_wrapper .ginput_complex label,
|
||||
.gform_wrapper .gfield_time_hour label,
|
||||
.gform_wrapper .gfield_time_minute label,
|
||||
.gform_wrapper .gfield_date_month label,
|
||||
.gform_wrapper .gfield_date_day label,
|
||||
.gform_wrapper .gfield_date_year label,
|
||||
.gform_wrapper .instruction {
|
||||
font-size: 0.9em;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0;
|
||||
margin: 0 0 6px 0;
|
||||
}
|
||||
.gform_wrapper .gfield_checkbox li input[type=checkbox],
|
||||
.gform_wrapper .gfield_radio li input[type=radio],
|
||||
.gform_wrapper .gfield_checkbox li input { float: none; display: inline-block; margin-top: 0; vertical-align: middle; }
|
||||
.gform_wrapper .gfield_checkbox li label, .gform_wrapper .gfield_radio li label { display: inline-block; margin: 0 0 0 8px; vertical-align: middle; }
|
||||
.gform_wrapper .left_label .ginput_complex .ginput_right label,
|
||||
.gform_wrapper .left_label .ginput_complex .ginput_left label,
|
||||
.gform_wrapper .right_label .ginput_complex .ginput_right label,
|
||||
.gform_wrapper .right_label .ginput_complex .ginput_left label { word-spacing: 0; }
|
||||
.gform_wrapper .gfield_checkbox li label, .gform_wrapper .gfield_radio li label { font-weight: 400; }
|
||||
img.ui-datepicker-trigger { vertical-align: middle; }
|
||||
.gform_wrapper .gf_progressbar_wrapper { width: 100%; }
|
||||
.gform_wrapper .gf_page_steps { border-bottom: 1px dashed #ddd; width: 100%; }
|
||||
.gform_wrapper .gf_step { font-family: sans-serif; }
|
||||
.gform_wrapper .gf_step span.gf_step_number { font-family: sans-serif; }
|
||||
.gform_wrapper .gsection { border-bottom: 1px dashed #ddd; }
|
||||
.gform_wrapper .gform_page_footer { border-top: 1px dashed #ddd; }
|
||||
.gform_wrapper .gform_footer { margin: 6px 0 0 0; padding: 0; }
|
||||
.gform_wrapper .gform_footer.right_label, .gform_wrapper .gform_footer.left_label { margin: 6px 0 0 0; padding: 0 0 0 31%; }
|
||||
.ie7 .gform_footer input.button { padding: 8px 16px; }
|
||||
.gform_wrapper .gform_edit_link { display: none; }
|
||||
.gform_wrapper .validation_error { font-size: 1em; font-weight: 400; padding: 0.8em; margin-bottom: 1.5em; background: #fbe3e4; color: #8a1f11; border: 2px solid #fbc2c4; }
|
||||
.gform_wrapper .validation_message { display: none; }
|
||||
.gform_wrapper li.gfield.gfield_error {
|
||||
background: none;
|
||||
margin-bottom: 6px !important;
|
||||
padding: 0 !important;
|
||||
border: none;
|
||||
}
|
||||
.gform_wrapper .top_label .gfield_error .ginput_container { max-width: none; }
|
||||
.gform_wrapper .top_label .gfield_error { margin-bottom: 0 !important; }
|
||||
.gform_wrapper .gfield_error .gfield_label { color: #8a1f11; }
|
||||
.gform_wrapper .gfield_error input,
|
||||
.gform_wrapper .gfield_error select,
|
||||
.gform_wrapper .gfield_error textarea { background: #FBE3E4; border-color: #FBC2C4; }
|
||||
.gform_wrapper .top_label .gfield_error input,
|
||||
.gform_wrapper .top_label .gfield_error textarea,
|
||||
.gform_wrapper .top_label .gfield_error select { border-color: #FBC2C4; }
|
||||
.gform_wrapper .top_label .gfield_error { width: auto; }
|
||||
|
||||
/* Fancybox */
|
||||
#fancybox-loading { position: fixed; top: 50%; left: 50%; width: 40px; height: 40px; margin-top: -20px; margin-left: -20px; cursor: pointer; overflow: hidden; z-index: 1104; display: none; }
|
||||
#fancybox-loading div { position: absolute; top: 0; left: 0; width: 40px; height: 480px; background-image: url(../img/fancybox/fancybox.png); }
|
||||
#fancybox-overlay { position: absolute; top: 0; left: 0; width: 100%; z-index: 1100; display: none; }
|
||||
#fancybox-tmp { padding: 0; margin: 0; border: 0; overflow: auto; display: none; }
|
||||
#fancybox-wrap { position: absolute; top: 0; left: 0; padding: 20px; z-index: 1101; outline: none; display: none; }
|
||||
#fancybox-outer { position: relative; width: 100%; height: 100%; background: #fff; }
|
||||
#fancybox-content { width: 0; height: 0; padding: 0; outline: none; position: relative; overflow: hidden; z-index: 1102; border: 0px solid #fff; }
|
||||
#fancybox-hide-sel-frame { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: transparent; z-index: 1101; }
|
||||
#fancybox-close { position: absolute; top: -15px; right: -15px; width: 30px; height: 30px; background: transparent url(../img/fancybox/fancybox.png) -40px 0px; cursor: pointer; z-index: 1103; display: none; }
|
||||
#fancybox-error { color: #444; font: normal 12px/20px sans-serif; padding: 14px; margin: 0; }
|
||||
#fancybox-img { width: 100%; height: 100%; padding: 0; margin: 0; border: none; outline: none; line-height: 0; vertical-align: top; }
|
||||
#fancybox-frame { width: 100%; height: 100%; border: none; display: block; }
|
||||
#fancybox-left, #fancybox-right { position: absolute; bottom: 0px; height: 100%; width: 35%; cursor: pointer; outline: none; background: transparent url(../img/fancybox/blank.gif); z-index: 1102; display: none; }
|
||||
#fancybox-left:hover, #fancybox-right:hover { visibility: visible; }
|
||||
#fancybox-right:hover span { left: auto; right: 20px; }
|
||||
#fancybox-left:hover span { left: 20px }
|
||||
#fancybox-left { left: 0px }
|
||||
#fancybox-right { right: 0px }
|
||||
#fancybox-left-ico, #fancybox-right-ico { position: absolute; top: 50%; left: -9999px; width: 30px; height: 30px; margin-top: -15px; cursor: pointer; z-index: 1102; display: block; }
|
||||
#fancybox-left-ico { background-image: url(../img/fancybox/fancybox.png); background-position: -40px -30px; }
|
||||
#fancybox-right-ico { background-image: url(../img/fancybox/fancybox.png); background-position: -40px -60px; }
|
||||
.fancybox-bg { position: absolute; padding: 0; margin: 0; border: 0; width: 20px; height: 20px; z-index: 1001; }
|
||||
#fancybox-bg-n { top: -20px; left: 0; width: 100%; background-image: url(../img/fancybox/fancybox-x.png); }
|
||||
#fancybox-bg-ne { top: -20px; right: -20px; background-image: url(../img/fancybox/fancybox.png); background-position: -40px -162px; }
|
||||
#fancybox-bg-e { top: 0; right: -20px; height: 100%; background-image: url(../img/fancybox/fancybox-y.png); background-position: -20px 0px; }
|
||||
#fancybox-bg-se { bottom: -20px; right: -20px; background-image: url(../img/fancybox/fancybox.png); background-position: -40px -182px; }
|
||||
#fancybox-bg-s { bottom: -20px; left: 0; width: 100%; background-image: url(../img/fancybox/fancybox-x.png); background-position: 0px -20px; }
|
||||
#fancybox-bg-sw { bottom: -20px; left: -20px; background-image: url(../img/fancybox/fancybox.png); background-position: -40px -142px; }
|
||||
#fancybox-bg-w { top: 0; left: -20px; height: 100%; background-image: url(../img/fancybox/fancybox-y.png); }
|
||||
#fancybox-bg-nw { top: -20px; left: -20px; background-image: url(../img/fancybox/fancybox.png); background-position: -40px -122px; }
|
||||
#fancybox-title { font-size: 12px; z-index: 1102; }
|
||||
.fancybox-title-inside { padding-bottom: 10px; text-align: center; color: #333; background: #fff; position: relative; }
|
||||
.fancybox-title-outside { padding-top: 10px; color: #fff; }
|
||||
.fancybox-title-over { position: absolute; bottom: 0; left: 0; color: #fff; text-align: left; }
|
||||
#fancybox-title-over { padding: 10px; background-image: url(../img/fancybox/fancy_title_over.png); display: block; }
|
||||
.fancybox-title-float { position: absolute; left: 0; bottom: -20px; height: 32px; }
|
||||
#fancybox-title-float-wrap { border: none; border-collapse: collapse; width: auto; }
|
||||
#fancybox-title-float-wrap td { border: none; white-space: nowrap; }
|
||||
#fancybox-title-float-left { padding: 0 0 0 15px; background: url(../img/fancybox/fancybox.png) -40px -90px no-repeat; }
|
||||
#fancybox-title-float-main { color: #fff; line-height: 29px; font-weight: bold; padding: 0 0 3px 0; background: url(../img/fancybox/fancybox-x.png) 0px -40px; }
|
||||
#fancybox-title-float-right { padding: 0 0 0 15px; background: url(../img/fancybox/fancybox.png) -55px -90px no-repeat; }
|
||||
|
||||
/* MapPress */
|
||||
#mapp0_poweredby, #mapp1_poweredby, #mapp2_poweredby, #mapp3_poweredby, #mapp4_poweredby, #mapp5_poweredby, #mapp6_poweredby, #mapp7_poweredby, #mapp8_poweredby, #mapp9_poweredby, #mapp10_poweredby { display: none !important; } /* remove MapPress credit */
|
||||
|
||||
/* Search */
|
||||
#searchform #s { padding: 5px; }
|
||||
|
||||
|
||||
/* INTERNET EXPLORER
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------------- */
|
||||
.ie7 #nav-main ul li { zoom: 1; }
|
||||
|
||||
/* Clearfixes */
|
||||
.ie7 #commentform, .ie7 #post-nav, .ie7 #comments-nav { display: inline-block; }
|
||||
|
||||
|
||||
/* MEDIA QUERIES
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------------- */
|
||||
@media all and (orientation: portrait) {
|
||||
/* Style adjustments for portrait mode goes here */
|
||||
|
||||
}
|
||||
|
||||
@media all and (orientation: landscape) {
|
||||
/* Style adjustments for landscape mode goes here */
|
||||
|
||||
}
|
||||
|
||||
@media screen and (max-device-width: 480px) {
|
||||
/* Grade-A Mobile Browsers (Opera Mobile, iPhone Safari, Android Chrome) */
|
||||
|
||||
}
|
||||
|
||||
@media print {
|
||||
* { background: transparent !important; color: black !important; text-shadow: none !important; filter: none !important; -ms-filter: none !important; }
|
||||
a, a: visited { color: #444 !important; text-decoration: underline; }
|
||||
a[href]:after { content: " (" attr(href) ")"; }
|
||||
abbr[title]:after { content: " (" attr(title) ")"; }
|
||||
.ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; }
|
||||
pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
|
||||
thead { display: table-header-group; }
|
||||
tr, img { page-break-inside: avoid; }
|
||||
@page { margin: 0.5cm; }
|
||||
p, h2, h3 { orphans: 3; widows: 3; }
|
||||
h2, h3 { page-break-after: avoid; }
|
||||
}
|
||||
7
editor-style.css
Normal file
@@ -0,0 +1,7 @@
|
||||
/*
|
||||
Theme Name: Roots
|
||||
Description: Used to style the TinyMCE editor
|
||||
*/
|
||||
|
||||
img.left, p img.left, .alignleft { margin: 0 1.5em 1.5em 0; float: left; }
|
||||
img.right, p img.right, .alignright { margin: 0 0 1.5em 1.5em; float: right; }
|
||||
32
footer.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<footer id="content-info" class="span-24" role="contentinfo">
|
||||
<div class="container">
|
||||
<?php if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar("Footer") ) : ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<p class="copy"><small>© <?php echo date('Y'); ?> <?php bloginfo('name'); ?></small></p>
|
||||
<?php if (get_option('roots_footer_social_share') == 'checked') { ?>
|
||||
<p class="social">
|
||||
<a href="http://twitter.com/share" class="twitter-share-button" data-url="<?php echo home_url('/'); ?>" data-count="horizontal">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>
|
||||
<iframe src="http://www.facebook.com/plugins/like.php?href=<?php echo home_url('/'); ?>&layout=button_count&show_faces=false&width=110&action=like&colorscheme=light&height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:110px; height:21px;" allowTransparency="true"></iframe>
|
||||
</p>
|
||||
<?php } ?>
|
||||
<?php if (get_option('roots_footer_vcard') == 'checked') { ?>
|
||||
<p class="vcard">
|
||||
<a class="fn org url" href="<?php echo home_url('/'); ?>" title="Contact Information for <?php bloginfo('name'); ?>"><?php bloginfo('name'); ?></a><br>
|
||||
<span class="adr">
|
||||
<span class="street-address"><?php echo get_option('roots_vcard_street-address'); ?></span><br>
|
||||
<span class="locality"><?php echo get_option('roots_vcard_locality'); ?></span>,
|
||||
<span class="region"><?php echo get_option('roots_vcard_region'); ?></span>
|
||||
<span class="postal-code"><?php echo get_option('roots_vcard_postal-code'); ?></span><br>
|
||||
</span>
|
||||
<span class="tel"><span class="value"><span class="hidden">+1-</span><?php echo get_option('roots_vcard_tel'); ?></span></span><br>
|
||||
<a class="email" href="mailto:<?php echo get_option('roots_vcard_email'); ?>"><?php echo get_option('roots_vcard_email'); ?></a>
|
||||
</p>
|
||||
<?php } ?>
|
||||
|
||||
</div>
|
||||
</footer>
|
||||
</div><!-- /#wrap -->
|
||||
<?php wp_footer(); ?>
|
||||
</body>
|
||||
</html>
|
||||
14
front-page.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php get_header(); ?>
|
||||
<div id="content" class="span-24">
|
||||
<div id="main" class="<?php echo get_option('roots_main_class'); ?>" role="main">
|
||||
<div class="container">
|
||||
<?php get_template_part('loop', 'page'); ?>
|
||||
</div>
|
||||
</div><!-- /#main -->
|
||||
<aside id="sidebar" class="<?php echo get_option('roots_sidebar_class'); ?>" role="complementary">
|
||||
<div class="container">
|
||||
<?php get_sidebar(); ?>
|
||||
</div>
|
||||
</aside><!-- /#sidebar -->
|
||||
</div><!-- /#content -->
|
||||
<?php get_footer(); ?>
|
||||
83
functions.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
include_once('includes/roots-activation.php'); // activation
|
||||
include_once('includes/roots-admin.php'); // admin additions/mods
|
||||
include_once('includes/roots-options.php'); // theme options menu
|
||||
include_once('includes/roots-ob.php'); // output buffer
|
||||
include_once('includes/roots-cleanup.php'); // code cleanup/removal
|
||||
include_once('includes/roots-htaccess.php'); // h5bp htaccess
|
||||
|
||||
// set the maximum 'Large' image width to the Blueprint grid maximum width
|
||||
if (!isset($content_width)) $content_width = 950;
|
||||
|
||||
// tell the TinyMCE editor to use editor-style.css
|
||||
// if you have issues with getting the editor to show your changes then use the following line:
|
||||
// add_editor_style('editor-style.css?' . time());
|
||||
add_editor_style('editor-style.css');
|
||||
|
||||
add_theme_support('post-thumbnails');
|
||||
|
||||
// http://codex.wordpress.org/Post_Formats
|
||||
// add_theme_support('post-formats', array('aside', 'gallery', 'link', 'image', 'quote', 'status', 'video', 'audio', 'chat'));
|
||||
|
||||
add_theme_support('menus');
|
||||
register_nav_menus(
|
||||
array(
|
||||
'primary_navigation' => 'Primary Navigation',
|
||||
'utility_navigation' => 'Utility Navigation'
|
||||
)
|
||||
);
|
||||
|
||||
// make sure the menu fallback (wp_list_pages) adds the home link
|
||||
function roots_page_menu_args($args) {
|
||||
$args['show_home'] = true;
|
||||
return $args;
|
||||
}
|
||||
|
||||
add_filter('wp_page_menu_args', 'roots_page_menu_args');
|
||||
|
||||
// remove container from menus
|
||||
function roots_nav_menu_args($args = ''){
|
||||
$args['container'] = false;
|
||||
return $args;
|
||||
}
|
||||
|
||||
add_filter('wp_nav_menu_args', 'roots_nav_menu_args');
|
||||
|
||||
// create widget areas: sidebar, footer
|
||||
$sidebars = array('Sidebar', 'Footer');
|
||||
foreach ($sidebars as $sidebar) {
|
||||
register_sidebar(array('name'=> $sidebar,
|
||||
'before_widget' => '<article id="%1$s" class="widget %2$s"><div class="container">',
|
||||
'after_widget' => '</div></article>',
|
||||
'before_title' => '<h3>',
|
||||
'after_title' => '</h3>'
|
||||
));
|
||||
}
|
||||
|
||||
// add to robots.txt
|
||||
// http://codex.wordpress.org/Search_Engine_Optimization_for_WordPress#Robots.txt_Optimization
|
||||
add_action('do_robots', 'roots_robots');
|
||||
|
||||
function roots_robots() {
|
||||
echo "Disallow: /cgi-bin\n";
|
||||
echo "Disallow: /wp-admin\n";
|
||||
echo "Disallow: /wp-includes\n";
|
||||
echo "Disallow: /wp-content/plugins\n";
|
||||
echo "Disallow: /plugins\n";
|
||||
echo "Disallow: /wp-content/cache\n";
|
||||
echo "Disallow: /wp-content/themes\n";
|
||||
echo "Disallow: /trackback\n";
|
||||
echo "Disallow: /feed\n";
|
||||
echo "Disallow: /comments\n";
|
||||
echo "Disallow: /category/*/*\n";
|
||||
echo "Disallow: */trackback\n";
|
||||
echo "Disallow: */feed\n";
|
||||
echo "Disallow: */comments\n";
|
||||
echo "Disallow: /*?*\n";
|
||||
echo "Disallow: /*?\n";
|
||||
echo "Allow: /wp-content/uploads\n";
|
||||
echo "Allow: /assets";
|
||||
}
|
||||
|
||||
?>
|
||||
50
header.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<!doctype html>
|
||||
<!--[if lt IE 7 ]> <html class="no-js ie6" lang="en"> <![endif]-->
|
||||
<!--[if IE 7 ]> <html class="no-js ie7" lang="en"> <![endif]-->
|
||||
<!--[if IE 8 ]> <html class="no-js ie8" lang="en"> <![endif]-->
|
||||
<!--[if (gte IE 9)|!(IE)]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title><?php wp_title('|', true, 'right'); ?><?php bloginfo('name'); ?></title>
|
||||
|
||||
<meta name="viewport" content="width=device-width; initial-scale=1.0">
|
||||
|
||||
<link rel="stylesheet" href="<?php echo get_stylesheet_directory_uri(); ?>/css/blueprint/screen.css">
|
||||
<?php if (class_exists('RGForms')) { ?>
|
||||
<link rel="stylesheet" href="<?php echo plugins_url(); ?>/gravityforms/css/forms.css">
|
||||
<?php } ?>
|
||||
<link rel="stylesheet" href="<?php echo get_stylesheet_directory_uri(); ?>/css/style.css">
|
||||
<!--[if lt IE 8]><link rel="stylesheet" href="<?php echo get_stylesheet_directory_uri(); ?>/css/blueprint/ie.css"><![endif]-->
|
||||
|
||||
<link rel="alternate" type="application/rss+xml" title="<?php bloginfo('name'); ?> Feed" href="<?php site_url(); ?>/feed/">
|
||||
|
||||
<script src="<?php echo get_stylesheet_directory_uri(); ?>/js/libs/modernizr-1.7.min.js"></script>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
|
||||
<script>window.jQuery || document.write("<script src='<?php echo get_stylesheet_directory_uri(); ?>/js/libs/jquery-1.5.1.min.js'>\x3C/script>")</script>
|
||||
|
||||
<?php wp_head(); ?>
|
||||
|
||||
<script src="<?php echo get_stylesheet_directory_uri(); ?>/js/scripts.js"></script>
|
||||
<?php if (get_option('roots_google_analytics') !== "") { ?>
|
||||
<script>
|
||||
var _gaq=[["_setAccount","<?php echo get_option('roots_google_analytics') ?>"],["_trackPageview"]];
|
||||
(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.async=1;
|
||||
g.src=("https:"==location.protocol?"//ssl":"//www")+".google-analytics.com/ga.js";
|
||||
s.parentNode.insertBefore(g,s)}(document,"script"));
|
||||
</script>
|
||||
<?php } ?>
|
||||
</head>
|
||||
<body <?php $page_slug = $post->post_name; body_class($page_slug); ?>>
|
||||
<div id="wrap" class="container" role="document">
|
||||
<header id="banner" class="span-24" role="banner">
|
||||
<div class="container">
|
||||
<a id="logo" href="<?php site_url(); ?>/"><img src="<?php echo get_stylesheet_directory_uri(); ?>/img/logo.png" width="300" height="75" alt="<?php bloginfo('name'); ?>"></a>
|
||||
<nav id="nav-main" class="span-24" role="navigation">
|
||||
<?php wp_nav_menu(array('theme_location' => 'primary_navigation')); ?>
|
||||
</nav>
|
||||
<nav id="nav-utility">
|
||||
<?php wp_nav_menu(array('theme_location' => 'utility_navigation')); ?>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
BIN
img/fancybox/blank.gif
Normal file
|
After Width: | Height: | Size: 43 B |
BIN
img/fancybox/fancy_close.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
img/fancybox/fancy_loading.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
img/fancybox/fancy_nav_left.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
img/fancybox/fancy_nav_right.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
img/fancybox/fancy_shadow_e.png
Normal file
|
After Width: | Height: | Size: 107 B |
BIN
img/fancybox/fancy_shadow_n.png
Normal file
|
After Width: | Height: | Size: 106 B |
BIN
img/fancybox/fancy_shadow_ne.png
Normal file
|
After Width: | Height: | Size: 347 B |
BIN
img/fancybox/fancy_shadow_nw.png
Normal file
|
After Width: | Height: | Size: 324 B |
BIN
img/fancybox/fancy_shadow_s.png
Normal file
|
After Width: | Height: | Size: 111 B |
BIN
img/fancybox/fancy_shadow_se.png
Normal file
|
After Width: | Height: | Size: 352 B |
BIN
img/fancybox/fancy_shadow_sw.png
Normal file
|
After Width: | Height: | Size: 340 B |
BIN
img/fancybox/fancy_shadow_w.png
Normal file
|
After Width: | Height: | Size: 103 B |
BIN
img/fancybox/fancy_title_left.png
Normal file
|
After Width: | Height: | Size: 503 B |
BIN
img/fancybox/fancy_title_main.png
Normal file
|
After Width: | Height: | Size: 96 B |
BIN
img/fancybox/fancy_title_over.png
Normal file
|
After Width: | Height: | Size: 70 B |
BIN
img/fancybox/fancy_title_right.png
Normal file
|
After Width: | Height: | Size: 506 B |
BIN
img/fancybox/fancybox-x.png
Normal file
|
After Width: | Height: | Size: 203 B |
BIN
img/fancybox/fancybox-y.png
Normal file
|
After Width: | Height: | Size: 176 B |
BIN
img/fancybox/fancybox.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
img/logo.png
Normal file
|
After Width: | Height: | Size: 671 B |
62
includes/css/admin.css
Normal file
@@ -0,0 +1,62 @@
|
||||
@import url("//ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/themes/smoothness/jquery-ui.css");
|
||||
|
||||
.clearfix:before,
|
||||
.clearfix:after {
|
||||
content: ".";
|
||||
display: block;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.clearfix:after { clear: both; }
|
||||
.clearfix { zoom: 1; } /* IE < 8 */
|
||||
|
||||
/* theme options */
|
||||
#tabs { margin-top: 1em; }
|
||||
body.toplevel_page_roots .ui-widget { font-size: 1em !important; font-family: inherit !important; }
|
||||
body.toplevel_page_roots .ui-widget-header {
|
||||
/* match #wp-head */
|
||||
background: #d9d9d9;
|
||||
background: -moz-linear-gradient(bottom, #d7d7d7, #e4e4e4) !important;
|
||||
background: -webkit-gradient(linear, left bottom, left top, from(#d7d7d7), to(#e4e4e4)) !important;
|
||||
}
|
||||
|
||||
body.toplevel_page_roots .ui-state-default,
|
||||
body.toplevel_page_roots .ui-widget-content .ui-state-default,
|
||||
body.toplevel_page_roots .ui-widget-header .ui-state-default {
|
||||
/* match #adminmenu a.menu-top */
|
||||
background: url(../images/menu-bits.gif) repeat-x scroll left -379px #F1F1F1 !important;
|
||||
}
|
||||
body.toplevel_page_roots .ui-state-active,
|
||||
body.toplevel_page_roots .ui-widget-content .ui-state-active,
|
||||
body.toplevel_page_roots .ui-widget-header .ui-state-active { background: #fff !important; }
|
||||
|
||||
ul.options li { clear: both; margin-bottom: 8px; }
|
||||
ul.options label.settings-label { font-size: 1em; font-weight: 700; float: left; width: 250px; margin: 3px 0 0 0; }
|
||||
ul.options input.text { float: left; width: 300px; }
|
||||
ul.options span.note { clear: both; float: left; margin: 2px 0 8px 250px; display: block; font-size: 0.8em; line-height: 1.5em; }
|
||||
|
||||
ul.options div.address { float: left; }
|
||||
ul.options div.address label { clear: both; float: left; width: 160px; margin: 3px 10px 0 0; }
|
||||
ul.options div.address input.text { float: left; width: 200px; }
|
||||
|
||||
/* search engines blocked message to match .button-primary */
|
||||
#privacy-on-link {
|
||||
color: #fff !important;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3);
|
||||
background: #21759B url(../../../../../wp-admin/images/button-grad.png) repeat-x scroll left top;
|
||||
padding: 3px 11px !important;
|
||||
-moz-border-radius: 11px;
|
||||
-webkit-border-radius: 11px;
|
||||
border-radius: 11px;
|
||||
border: 1px solid #298CBA;
|
||||
font-weight: 700;
|
||||
font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif;
|
||||
margin-left: 6px;
|
||||
line-height: 13px !important;
|
||||
}
|
||||
#privacy-on-link:hover { text-decoration: none !important; border: 1px solid #13455B; color: #EAF2FA !important; }
|
||||
|
||||
#editorcontainer #content {
|
||||
font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace;
|
||||
font-size: 14px;
|
||||
}
|
||||
55
includes/css/codemirror/csscolors.css
Normal file
@@ -0,0 +1,55 @@
|
||||
html {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.editbox {
|
||||
margin: .4em;
|
||||
padding: 0;
|
||||
font-family: monospace;
|
||||
font-size: 10pt;
|
||||
color: black;
|
||||
}
|
||||
|
||||
pre.code, .editbox {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.editbox p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
span.css-at {
|
||||
color: #708;
|
||||
}
|
||||
|
||||
span.css-unit {
|
||||
color: #281;
|
||||
}
|
||||
|
||||
span.css-value {
|
||||
color: #708;
|
||||
}
|
||||
|
||||
span.css-identifier {
|
||||
color: black;
|
||||
}
|
||||
|
||||
span.css-selector {
|
||||
color: #11B;
|
||||
}
|
||||
|
||||
span.css-important {
|
||||
color: #00F;
|
||||
}
|
||||
|
||||
span.css-colorcode {
|
||||
color: #299;
|
||||
}
|
||||
|
||||
span.css-comment {
|
||||
color: #A70;
|
||||
}
|
||||
|
||||
span.css-string {
|
||||
color: #A22;
|
||||
}
|
||||
158
includes/css/codemirror/docs.css
Normal file
@@ -0,0 +1,158 @@
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
max-width: 64.3em;
|
||||
margin: 3em auto;
|
||||
padding: 0 1em;
|
||||
}
|
||||
body.droid {
|
||||
font-family: Droid Sans, Arial, sans-serif;
|
||||
}
|
||||
|
||||
h1 {
|
||||
letter-spacing: -3px;
|
||||
font-size: 3.23em;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.23em;
|
||||
font-weight: bold;
|
||||
margin: .5em 0;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1em;
|
||||
font-weight: bold;
|
||||
margin: .4em 0;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: Courier New, monospaced;
|
||||
background-color: #eee;
|
||||
-moz-border-radius: 6px;
|
||||
-webkit-border-radius: 6px;
|
||||
border-radius: 6px;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
pre.code {
|
||||
margin: 0 1em;
|
||||
}
|
||||
|
||||
.grey {
|
||||
font-size: 2em;
|
||||
padding: .5em 1em;
|
||||
line-height: 1.2em;
|
||||
margin-top: .5em;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
img.logo {
|
||||
position: absolute;
|
||||
right: -25px;
|
||||
bottom: 4px;
|
||||
}
|
||||
|
||||
a:link, a:visited, .quasilink {
|
||||
color: #df0019;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover, .quasilink:hover {
|
||||
color: #800004;
|
||||
}
|
||||
|
||||
h1 a:link, h1 a:visited, h1 a:hover {
|
||||
color: black;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding-left: 1.2em;
|
||||
}
|
||||
|
||||
a.download {
|
||||
color: white;
|
||||
background-color: #df0019;
|
||||
width: 100%;
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-size: 1.23em;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
-moz-border-radius: 6px;
|
||||
-webkit-border-radius: 6px;
|
||||
border-radius: 6px;
|
||||
padding: .5em 0;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
a.download:hover {
|
||||
background-color: #bb0010;
|
||||
}
|
||||
|
||||
.rel {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.rel-note {
|
||||
color: #777;
|
||||
font-size: .9em;
|
||||
margin-top: .1em;
|
||||
}
|
||||
|
||||
.logo-braces {
|
||||
color: #df0019;
|
||||
position: relative;
|
||||
top: -4px;
|
||||
}
|
||||
|
||||
.blk {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.left {
|
||||
width: 37em;
|
||||
padding-right: 6.53em;
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
.left1 {
|
||||
width: 15.24em;
|
||||
padding-right: 6.45em;
|
||||
}
|
||||
|
||||
.left2 {
|
||||
width: 15.24em;
|
||||
}
|
||||
|
||||
.right {
|
||||
width: 20.68em;
|
||||
}
|
||||
|
||||
.leftbig {
|
||||
width: 42.44em;
|
||||
padding-right: 6.53em;
|
||||
}
|
||||
|
||||
.rightsmall {
|
||||
width: 15.24em;
|
||||
}
|
||||
|
||||
.clear:after {
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
font-size: 0;
|
||||
content: " ";
|
||||
clear: both;
|
||||
height: 0;
|
||||
}
|
||||
.clear { display: inline-block; }
|
||||
/* start commented backslash hack \*/
|
||||
* html .clear { height: 1%; }
|
||||
.clear { display: block; }
|
||||
/* close commented backslash hack */
|
||||
59
includes/css/codemirror/jscolors.css
Normal file
@@ -0,0 +1,59 @@
|
||||
html {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.editbox {
|
||||
margin: .4em;
|
||||
padding: 0;
|
||||
font-family: monospace;
|
||||
font-size: 10pt;
|
||||
color: black;
|
||||
}
|
||||
|
||||
pre.code, .editbox {
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.editbox p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
span.js-punctuation {
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
span.js-operator {
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
span.js-keyword {
|
||||
color: #770088;
|
||||
}
|
||||
|
||||
span.js-atom {
|
||||
color: #228811;
|
||||
}
|
||||
|
||||
span.js-variable {
|
||||
color: black;
|
||||
}
|
||||
|
||||
span.js-variabledef {
|
||||
color: #0000FF;
|
||||
}
|
||||
|
||||
span.js-localvariable {
|
||||
color: #004499;
|
||||
}
|
||||
|
||||
span.js-property {
|
||||
color: black;
|
||||
}
|
||||
|
||||
span.js-comment {
|
||||
color: #AA7700;
|
||||
}
|
||||
|
||||
span.js-string {
|
||||
color: #AA2222;
|
||||
}
|
||||
43
includes/css/codemirror/sparqlcolors.css
Normal file
@@ -0,0 +1,43 @@
|
||||
html {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.editbox {
|
||||
margin: .4em;
|
||||
padding: 0;
|
||||
font-family: monospace;
|
||||
font-size: 10pt;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.editbox p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
span.sp-keyword {
|
||||
color: #708;
|
||||
}
|
||||
|
||||
span.sp-prefixed {
|
||||
color: #5d1;
|
||||
}
|
||||
|
||||
span.sp-var {
|
||||
color: #00c;
|
||||
}
|
||||
|
||||
span.sp-comment {
|
||||
color: #a70;
|
||||
}
|
||||
|
||||
span.sp-literal {
|
||||
color: #a22;
|
||||
}
|
||||
|
||||
span.sp-uri {
|
||||
color: #292;
|
||||
}
|
||||
|
||||
span.sp-operator {
|
||||
color: #088;
|
||||
}
|
||||
55
includes/css/codemirror/xmlcolors.css
Normal file
@@ -0,0 +1,55 @@
|
||||
html {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.editbox {
|
||||
margin: .4em;
|
||||
padding: 0;
|
||||
font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace;
|
||||
font-size: 14px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.editbox p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
span.xml-tagname {
|
||||
color: #A0B;
|
||||
}
|
||||
|
||||
span.xml-attribute {
|
||||
color: #281;
|
||||
}
|
||||
|
||||
span.xml-punctuation {
|
||||
color: black;
|
||||
}
|
||||
|
||||
span.xml-attname {
|
||||
color: #00F;
|
||||
}
|
||||
|
||||
span.xml-comment {
|
||||
color: #A70;
|
||||
}
|
||||
|
||||
span.xml-cdata {
|
||||
color: #48A;
|
||||
}
|
||||
|
||||
span.xml-processing {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
span.xml-entity {
|
||||
color: #A22;
|
||||
}
|
||||
|
||||
span.xml-error {
|
||||
color: #F00 !important;
|
||||
}
|
||||
|
||||
span.xml-text {
|
||||
color: black;
|
||||
}
|
||||
BIN
includes/images/icon-roots.png
Normal file
|
After Width: | Height: | Size: 659 B |
582
includes/js/codemirror/codemirror.js
Normal file
@@ -0,0 +1,582 @@
|
||||
/* CodeMirror main module (http://codemirror.net/)
|
||||
*
|
||||
* Implements the CodeMirror constructor and prototype, which take care
|
||||
* of initializing the editor frame, and providing the outside interface.
|
||||
*/
|
||||
|
||||
// The CodeMirrorConfig object is used to specify a default
|
||||
// configuration. If you specify such an object before loading this
|
||||
// file, the values you put into it will override the defaults given
|
||||
// below. You can also assign to it after loading.
|
||||
var CodeMirrorConfig = window.CodeMirrorConfig || {};
|
||||
|
||||
var CodeMirror = (function(){
|
||||
function setDefaults(object, defaults) {
|
||||
for (var option in defaults) {
|
||||
if (!object.hasOwnProperty(option))
|
||||
object[option] = defaults[option];
|
||||
}
|
||||
}
|
||||
function forEach(array, action) {
|
||||
for (var i = 0; i < array.length; i++)
|
||||
action(array[i]);
|
||||
}
|
||||
function createHTMLElement(el) {
|
||||
if (document.createElementNS && document.documentElement.namespaceURI !== null)
|
||||
return document.createElementNS("http://www.w3.org/1999/xhtml", el)
|
||||
else
|
||||
return document.createElement(el)
|
||||
}
|
||||
|
||||
// These default options can be overridden by passing a set of
|
||||
// options to a specific CodeMirror constructor. See manual.html for
|
||||
// their meaning.
|
||||
setDefaults(CodeMirrorConfig, {
|
||||
stylesheet: [],
|
||||
path: "",
|
||||
parserfile: [],
|
||||
basefiles: ["util.js", "stringstream.js", "select.js", "undo.js", "editor.js", "tokenize.js"],
|
||||
iframeClass: null,
|
||||
passDelay: 200,
|
||||
passTime: 50,
|
||||
lineNumberDelay: 200,
|
||||
lineNumberTime: 50,
|
||||
continuousScanning: false,
|
||||
saveFunction: null,
|
||||
onLoad: null,
|
||||
onChange: null,
|
||||
undoDepth: 50,
|
||||
undoDelay: 800,
|
||||
disableSpellcheck: true,
|
||||
textWrapping: true,
|
||||
readOnly: false,
|
||||
width: "",
|
||||
height: "300px",
|
||||
minHeight: 100,
|
||||
autoMatchParens: false,
|
||||
markParen: null,
|
||||
unmarkParen: null,
|
||||
parserConfig: null,
|
||||
tabMode: "indent", // or "spaces", "default", "shift"
|
||||
enterMode: "indent", // or "keep", "flat"
|
||||
electricChars: true,
|
||||
reindentOnLoad: false,
|
||||
activeTokens: null,
|
||||
onCursorActivity: null,
|
||||
lineNumbers: false,
|
||||
firstLineNumber: 1,
|
||||
onLineNumberClick: null,
|
||||
indentUnit: 2,
|
||||
domain: null,
|
||||
noScriptCaching: false,
|
||||
incrementalLoading: false
|
||||
});
|
||||
|
||||
function addLineNumberDiv(container, firstNum) {
|
||||
var nums = createHTMLElement("div"),
|
||||
scroller = createHTMLElement("div");
|
||||
nums.style.position = "absolute";
|
||||
nums.style.height = "100%";
|
||||
if (nums.style.setExpression) {
|
||||
try {nums.style.setExpression("height", "this.previousSibling.offsetHeight + 'px'");}
|
||||
catch(e) {} // Seems to throw 'Not Implemented' on some IE8 versions
|
||||
}
|
||||
nums.style.top = "0px";
|
||||
nums.style.left = "0px";
|
||||
nums.style.overflow = "hidden";
|
||||
container.appendChild(nums);
|
||||
scroller.className = "CodeMirror-line-numbers";
|
||||
nums.appendChild(scroller);
|
||||
scroller.innerHTML = "<div>" + firstNum + "</div>";
|
||||
return nums;
|
||||
}
|
||||
|
||||
function frameHTML(options) {
|
||||
if (typeof options.parserfile == "string")
|
||||
options.parserfile = [options.parserfile];
|
||||
if (typeof options.basefiles == "string")
|
||||
options.basefiles = [options.basefiles];
|
||||
if (typeof options.stylesheet == "string")
|
||||
options.stylesheet = [options.stylesheet];
|
||||
|
||||
var sp = " spellcheck=\"" + (options.disableSpellcheck ? "false" : "true") + "\"";
|
||||
var html = ["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\"><html" + sp + "><head>"];
|
||||
// Hack to work around a bunch of IE8-specific problems.
|
||||
html.push("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=EmulateIE7\"/>");
|
||||
var queryStr = options.noScriptCaching ? "?nocache=" + new Date().getTime().toString(16) : "";
|
||||
forEach(options.stylesheet, function(file) {
|
||||
html.push("<link rel=\"stylesheet\" type=\"text/css\" href=\"" + file + queryStr + "\"/>");
|
||||
});
|
||||
forEach(options.basefiles.concat(options.parserfile), function(file) {
|
||||
if (!/^https?:/.test(file)) file = options.path + file;
|
||||
html.push("<script type=\"text/javascript\" src=\"" + file + queryStr + "\"><" + "/script>");
|
||||
});
|
||||
html.push("</head><body style=\"border-width: 0;\" class=\"editbox\"" + sp + "></body></html>");
|
||||
return html.join("");
|
||||
}
|
||||
|
||||
var internetExplorer = document.selection && window.ActiveXObject && /MSIE/.test(navigator.userAgent);
|
||||
|
||||
function CodeMirror(place, options) {
|
||||
// Use passed options, if any, to override defaults.
|
||||
this.options = options = options || {};
|
||||
setDefaults(options, CodeMirrorConfig);
|
||||
|
||||
// Backward compatibility for deprecated options.
|
||||
if (options.dumbTabs) options.tabMode = "spaces";
|
||||
else if (options.normalTab) options.tabMode = "default";
|
||||
if (options.cursorActivity) options.onCursorActivity = options.cursorActivity;
|
||||
|
||||
var frame = this.frame = createHTMLElement("iframe");
|
||||
if (options.iframeClass) frame.className = options.iframeClass;
|
||||
frame.frameBorder = 0;
|
||||
frame.style.border = "0";
|
||||
frame.style.width = '100%';
|
||||
frame.style.height = '100%';
|
||||
// display: block occasionally suppresses some Firefox bugs, so we
|
||||
// always add it, redundant as it sounds.
|
||||
frame.style.display = "block";
|
||||
|
||||
var div = this.wrapping = createHTMLElement("div");
|
||||
div.style.position = "relative";
|
||||
div.className = "CodeMirror-wrapping";
|
||||
div.style.width = options.width;
|
||||
div.style.height = (options.height == "dynamic") ? options.minHeight + "px" : options.height;
|
||||
// This is used by Editor.reroutePasteEvent
|
||||
var teHack = this.textareaHack = createHTMLElement("textarea");
|
||||
div.appendChild(teHack);
|
||||
teHack.style.position = "absolute";
|
||||
teHack.style.left = "-10000px";
|
||||
teHack.style.width = "10px";
|
||||
teHack.tabIndex = 100000;
|
||||
|
||||
// Link back to this object, so that the editor can fetch options
|
||||
// and add a reference to itself.
|
||||
frame.CodeMirror = this;
|
||||
if (options.domain && internetExplorer) {
|
||||
this.html = frameHTML(options);
|
||||
frame.src = "javascript:(function(){document.open();" +
|
||||
(options.domain ? "document.domain=\"" + options.domain + "\";" : "") +
|
||||
"document.write(window.frameElement.CodeMirror.html);document.close();})()";
|
||||
}
|
||||
else {
|
||||
frame.src = "javascript:;";
|
||||
}
|
||||
|
||||
if (place.appendChild) place.appendChild(div);
|
||||
else place(div);
|
||||
div.appendChild(frame);
|
||||
if (options.lineNumbers) this.lineNumbers = addLineNumberDiv(div, options.firstLineNumber);
|
||||
|
||||
this.win = frame.contentWindow;
|
||||
if (!options.domain || !internetExplorer) {
|
||||
this.win.document.open();
|
||||
this.win.document.write(frameHTML(options));
|
||||
this.win.document.close();
|
||||
}
|
||||
}
|
||||
|
||||
CodeMirror.prototype = {
|
||||
init: function() {
|
||||
// Deprecated, but still supported.
|
||||
if (this.options.initCallback) this.options.initCallback(this);
|
||||
if (this.options.onLoad) this.options.onLoad(this);
|
||||
if (this.options.lineNumbers) this.activateLineNumbers();
|
||||
if (this.options.reindentOnLoad) this.reindent();
|
||||
if (this.options.height == "dynamic") this.setDynamicHeight();
|
||||
},
|
||||
|
||||
getCode: function() {return this.editor.getCode();},
|
||||
setCode: function(code) {this.editor.importCode(code);},
|
||||
selection: function() {this.focusIfIE(); return this.editor.selectedText();},
|
||||
reindent: function() {this.editor.reindent();},
|
||||
reindentSelection: function() {this.focusIfIE(); this.editor.reindentSelection(null);},
|
||||
|
||||
focusIfIE: function() {
|
||||
// in IE, a lot of selection-related functionality only works when the frame is focused
|
||||
if (this.win.select.ie_selection && document.activeElement != this.frame)
|
||||
this.focus();
|
||||
},
|
||||
focus: function() {
|
||||
this.win.focus();
|
||||
if (this.editor.selectionSnapshot) // IE hack
|
||||
this.win.select.setBookmark(this.win.document.body, this.editor.selectionSnapshot);
|
||||
},
|
||||
replaceSelection: function(text) {
|
||||
this.focus();
|
||||
this.editor.replaceSelection(text);
|
||||
return true;
|
||||
},
|
||||
replaceChars: function(text, start, end) {
|
||||
this.editor.replaceChars(text, start, end);
|
||||
},
|
||||
getSearchCursor: function(string, fromCursor, caseFold) {
|
||||
return this.editor.getSearchCursor(string, fromCursor, caseFold);
|
||||
},
|
||||
|
||||
undo: function() {this.editor.history.undo();},
|
||||
redo: function() {this.editor.history.redo();},
|
||||
historySize: function() {return this.editor.history.historySize();},
|
||||
clearHistory: function() {this.editor.history.clear();},
|
||||
|
||||
grabKeys: function(callback, filter) {this.editor.grabKeys(callback, filter);},
|
||||
ungrabKeys: function() {this.editor.ungrabKeys();},
|
||||
|
||||
setParser: function(name, parserConfig) {this.editor.setParser(name, parserConfig);},
|
||||
setSpellcheck: function(on) {this.win.document.body.spellcheck = on;},
|
||||
setStylesheet: function(names) {
|
||||
if (typeof names === "string") names = [names];
|
||||
var activeStylesheets = {};
|
||||
var matchedNames = {};
|
||||
var links = this.win.document.getElementsByTagName("link");
|
||||
// Create hashes of active stylesheets and matched names.
|
||||
// This is O(n^2) but n is expected to be very small.
|
||||
for (var x = 0, link; link = links[x]; x++) {
|
||||
if (link.rel.indexOf("stylesheet") !== -1) {
|
||||
for (var y = 0; y < names.length; y++) {
|
||||
var name = names[y];
|
||||
if (link.href.substring(link.href.length - name.length) === name) {
|
||||
activeStylesheets[link.href] = true;
|
||||
matchedNames[name] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Activate the selected stylesheets and disable the rest.
|
||||
for (var x = 0, link; link = links[x]; x++) {
|
||||
if (link.rel.indexOf("stylesheet") !== -1) {
|
||||
link.disabled = !(link.href in activeStylesheets);
|
||||
}
|
||||
}
|
||||
// Create any new stylesheets.
|
||||
for (var y = 0; y < names.length; y++) {
|
||||
var name = names[y];
|
||||
if (!(name in matchedNames)) {
|
||||
var link = this.win.document.createElement("link");
|
||||
link.rel = "stylesheet";
|
||||
link.type = "text/css";
|
||||
link.href = name;
|
||||
this.win.document.getElementsByTagName('head')[0].appendChild(link);
|
||||
}
|
||||
}
|
||||
},
|
||||
setTextWrapping: function(on) {
|
||||
if (on == this.options.textWrapping) return;
|
||||
this.win.document.body.style.whiteSpace = on ? "" : "nowrap";
|
||||
this.options.textWrapping = on;
|
||||
if (this.lineNumbers) {
|
||||
this.setLineNumbers(false);
|
||||
this.setLineNumbers(true);
|
||||
}
|
||||
},
|
||||
setIndentUnit: function(unit) {this.win.indentUnit = unit;},
|
||||
setUndoDepth: function(depth) {this.editor.history.maxDepth = depth;},
|
||||
setTabMode: function(mode) {this.options.tabMode = mode;},
|
||||
setEnterMode: function(mode) {this.options.enterMode = mode;},
|
||||
setLineNumbers: function(on) {
|
||||
if (on && !this.lineNumbers) {
|
||||
this.lineNumbers = addLineNumberDiv(this.wrapping,this.options.firstLineNumber);
|
||||
this.activateLineNumbers();
|
||||
}
|
||||
else if (!on && this.lineNumbers) {
|
||||
this.wrapping.removeChild(this.lineNumbers);
|
||||
this.wrapping.style.paddingLeft = "";
|
||||
this.lineNumbers = null;
|
||||
}
|
||||
},
|
||||
|
||||
cursorPosition: function(start) {this.focusIfIE(); return this.editor.cursorPosition(start);},
|
||||
firstLine: function() {return this.editor.firstLine();},
|
||||
lastLine: function() {return this.editor.lastLine();},
|
||||
nextLine: function(line) {return this.editor.nextLine(line);},
|
||||
prevLine: function(line) {return this.editor.prevLine(line);},
|
||||
lineContent: function(line) {return this.editor.lineContent(line);},
|
||||
setLineContent: function(line, content) {this.editor.setLineContent(line, content);},
|
||||
removeLine: function(line){this.editor.removeLine(line);},
|
||||
insertIntoLine: function(line, position, content) {this.editor.insertIntoLine(line, position, content);},
|
||||
selectLines: function(startLine, startOffset, endLine, endOffset) {
|
||||
this.win.focus();
|
||||
this.editor.selectLines(startLine, startOffset, endLine, endOffset);
|
||||
},
|
||||
nthLine: function(n) {
|
||||
var line = this.firstLine();
|
||||
for (; n > 1 && line !== false; n--)
|
||||
line = this.nextLine(line);
|
||||
return line;
|
||||
},
|
||||
lineNumber: function(line) {
|
||||
var num = 0;
|
||||
while (line !== false) {
|
||||
num++;
|
||||
line = this.prevLine(line);
|
||||
}
|
||||
return num;
|
||||
},
|
||||
jumpToLine: function(line) {
|
||||
if (typeof line == "number") line = this.nthLine(line);
|
||||
this.selectLines(line, 0);
|
||||
this.win.focus();
|
||||
},
|
||||
currentLine: function() { // Deprecated, but still there for backward compatibility
|
||||
return this.lineNumber(this.cursorLine());
|
||||
},
|
||||
cursorLine: function() {
|
||||
return this.cursorPosition().line;
|
||||
},
|
||||
cursorCoords: function(start) {return this.editor.cursorCoords(start);},
|
||||
|
||||
activateLineNumbers: function() {
|
||||
var frame = this.frame, win = frame.contentWindow, doc = win.document, body = doc.body,
|
||||
nums = this.lineNumbers, scroller = nums.firstChild, self = this;
|
||||
var barWidth = null;
|
||||
|
||||
nums.onclick = function(e) {
|
||||
var handler = self.options.onLineNumberClick;
|
||||
if (handler) {
|
||||
var div = (e || window.event).target || (e || window.event).srcElement;
|
||||
var num = div == nums ? NaN : Number(div.innerHTML);
|
||||
if (!isNaN(num)) handler(num, div);
|
||||
}
|
||||
};
|
||||
|
||||
function sizeBar() {
|
||||
if (frame.offsetWidth == 0) return;
|
||||
for (var root = frame; root.parentNode; root = root.parentNode){}
|
||||
if (!nums.parentNode || root != document || !win.Editor) {
|
||||
// Clear event handlers (their nodes might already be collected, so try/catch)
|
||||
try{clear();}catch(e){}
|
||||
clearInterval(sizeInterval);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nums.offsetWidth != barWidth) {
|
||||
barWidth = nums.offsetWidth;
|
||||
frame.parentNode.style.paddingLeft = barWidth + "px";
|
||||
}
|
||||
}
|
||||
function doScroll() {
|
||||
nums.scrollTop = body.scrollTop || doc.documentElement.scrollTop || 0;
|
||||
}
|
||||
// Cleanup function, registered by nonWrapping and wrapping.
|
||||
var clear = function(){};
|
||||
sizeBar();
|
||||
var sizeInterval = setInterval(sizeBar, 500);
|
||||
|
||||
function ensureEnoughLineNumbers(fill) {
|
||||
var lineHeight = scroller.firstChild.offsetHeight;
|
||||
if (lineHeight == 0) return;
|
||||
var targetHeight = 50 + Math.max(body.offsetHeight, Math.max(frame.offsetHeight, body.scrollHeight || 0)),
|
||||
lastNumber = Math.ceil(targetHeight / lineHeight);
|
||||
for (var i = scroller.childNodes.length; i <= lastNumber; i++) {
|
||||
var div = createHTMLElement("div");
|
||||
div.appendChild(document.createTextNode(fill ? String(i + self.options.firstLineNumber) : "\u00a0"));
|
||||
scroller.appendChild(div);
|
||||
}
|
||||
}
|
||||
|
||||
function nonWrapping() {
|
||||
function update() {
|
||||
ensureEnoughLineNumbers(true);
|
||||
doScroll();
|
||||
}
|
||||
self.updateNumbers = update;
|
||||
var onScroll = win.addEventHandler(win, "scroll", doScroll, true),
|
||||
onResize = win.addEventHandler(win, "resize", update, true);
|
||||
clear = function(){
|
||||
onScroll(); onResize();
|
||||
if (self.updateNumbers == update) self.updateNumbers = null;
|
||||
};
|
||||
update();
|
||||
}
|
||||
|
||||
function wrapping() {
|
||||
var node, lineNum, next, pos, changes = [], styleNums = self.options.styleNumbers;
|
||||
|
||||
function setNum(n, node) {
|
||||
// Does not typically happen (but can, if you mess with the
|
||||
// document during the numbering)
|
||||
if (!lineNum) lineNum = scroller.appendChild(createHTMLElement("div"));
|
||||
if (styleNums) styleNums(lineNum, node, n);
|
||||
// Changes are accumulated, so that the document layout
|
||||
// doesn't have to be recomputed during the pass
|
||||
changes.push(lineNum); changes.push(n);
|
||||
pos = lineNum.offsetHeight + lineNum.offsetTop;
|
||||
lineNum = lineNum.nextSibling;
|
||||
}
|
||||
function commitChanges() {
|
||||
for (var i = 0; i < changes.length; i += 2)
|
||||
changes[i].innerHTML = changes[i + 1];
|
||||
changes = [];
|
||||
}
|
||||
function work() {
|
||||
if (!scroller.parentNode || scroller.parentNode != self.lineNumbers) return;
|
||||
|
||||
var endTime = new Date().getTime() + self.options.lineNumberTime;
|
||||
while (node) {
|
||||
setNum(next++, node.previousSibling);
|
||||
for (; node && !win.isBR(node); node = node.nextSibling) {
|
||||
var bott = node.offsetTop + node.offsetHeight;
|
||||
while (scroller.offsetHeight && bott - 3 > pos) {
|
||||
var oldPos = pos;
|
||||
setNum(" ");
|
||||
if (pos <= oldPos) break;
|
||||
}
|
||||
}
|
||||
if (node) node = node.nextSibling;
|
||||
if (new Date().getTime() > endTime) {
|
||||
commitChanges();
|
||||
pending = setTimeout(work, self.options.lineNumberDelay);
|
||||
return;
|
||||
}
|
||||
}
|
||||
while (lineNum) setNum(next++);
|
||||
commitChanges();
|
||||
doScroll();
|
||||
}
|
||||
function start(firstTime) {
|
||||
doScroll();
|
||||
ensureEnoughLineNumbers(firstTime);
|
||||
node = body.firstChild;
|
||||
lineNum = scroller.firstChild;
|
||||
pos = 0;
|
||||
next = self.options.firstLineNumber;
|
||||
work();
|
||||
}
|
||||
|
||||
start(true);
|
||||
var pending = null;
|
||||
function update() {
|
||||
if (pending) clearTimeout(pending);
|
||||
if (self.editor.allClean()) start();
|
||||
else pending = setTimeout(update, 200);
|
||||
}
|
||||
self.updateNumbers = update;
|
||||
var onScroll = win.addEventHandler(win, "scroll", doScroll, true),
|
||||
onResize = win.addEventHandler(win, "resize", update, true);
|
||||
clear = function(){
|
||||
if (pending) clearTimeout(pending);
|
||||
if (self.updateNumbers == update) self.updateNumbers = null;
|
||||
onScroll();
|
||||
onResize();
|
||||
};
|
||||
}
|
||||
(this.options.textWrapping || this.options.styleNumbers ? wrapping : nonWrapping)();
|
||||
},
|
||||
|
||||
setDynamicHeight: function() {
|
||||
var self = this, activity = self.options.onCursorActivity, win = self.win, body = win.document.body,
|
||||
lineHeight = null, timeout = null, vmargin = 2 * self.frame.offsetTop;
|
||||
body.style.overflowY = "hidden";
|
||||
win.document.documentElement.style.overflowY = "hidden";
|
||||
this.frame.scrolling = "no";
|
||||
|
||||
function updateHeight() {
|
||||
var trailingLines = 0, node = body.lastChild, computedHeight;
|
||||
while (node && win.isBR(node)) {
|
||||
if (!node.hackBR) trailingLines++;
|
||||
node = node.previousSibling;
|
||||
}
|
||||
if (node) {
|
||||
lineHeight = node.offsetHeight;
|
||||
computedHeight = node.offsetTop + (1 + trailingLines) * lineHeight;
|
||||
}
|
||||
else if (lineHeight) {
|
||||
computedHeight = trailingLines * lineHeight;
|
||||
}
|
||||
if (computedHeight)
|
||||
self.wrapping.style.height = Math.max(vmargin + computedHeight, self.options.minHeight) + "px";
|
||||
}
|
||||
setTimeout(updateHeight, 300);
|
||||
self.options.onCursorActivity = function(x) {
|
||||
if (activity) activity(x);
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(updateHeight, 100);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
CodeMirror.InvalidLineHandle = {toString: function(){return "CodeMirror.InvalidLineHandle";}};
|
||||
|
||||
CodeMirror.replace = function(element) {
|
||||
if (typeof element == "string")
|
||||
element = document.getElementById(element);
|
||||
return function(newElement) {
|
||||
element.parentNode.replaceChild(newElement, element);
|
||||
};
|
||||
};
|
||||
|
||||
CodeMirror.fromTextArea = function(area, options) {
|
||||
if (typeof area == "string")
|
||||
area = document.getElementById(area);
|
||||
|
||||
options = options || {};
|
||||
if (area.style.width && options.width == null)
|
||||
options.width = area.style.width;
|
||||
if (area.style.height && options.height == null)
|
||||
options.height = area.style.height;
|
||||
if (options.content == null) options.content = area.value;
|
||||
|
||||
function updateField() {
|
||||
area.value = mirror.getCode();
|
||||
}
|
||||
if (area.form) {
|
||||
if (typeof area.form.addEventListener == "function")
|
||||
area.form.addEventListener("submit", updateField, false);
|
||||
else
|
||||
area.form.attachEvent("onsubmit", updateField);
|
||||
var realSubmit = area.form.submit;
|
||||
function wrapSubmit() {
|
||||
updateField();
|
||||
// Can't use realSubmit.apply because IE6 is too stupid
|
||||
area.form.submit = realSubmit;
|
||||
area.form.submit();
|
||||
area.form.submit = wrapSubmit;
|
||||
}
|
||||
try {area.form.submit = wrapSubmit;} catch(e){}
|
||||
}
|
||||
|
||||
function insert(frame) {
|
||||
if (area.nextSibling)
|
||||
area.parentNode.insertBefore(frame, area.nextSibling);
|
||||
else
|
||||
area.parentNode.appendChild(frame);
|
||||
}
|
||||
|
||||
area.style.display = "none";
|
||||
var mirror = new CodeMirror(insert, options);
|
||||
mirror.save = updateField;
|
||||
mirror.toTextArea = function() {
|
||||
updateField();
|
||||
area.parentNode.removeChild(mirror.wrapping);
|
||||
area.style.display = "";
|
||||
if (area.form) {
|
||||
try {area.form.submit = realSubmit;} catch(e) {}
|
||||
if (typeof area.form.removeEventListener == "function")
|
||||
area.form.removeEventListener("submit", updateField, false);
|
||||
else
|
||||
area.form.detachEvent("onsubmit", updateField);
|
||||
}
|
||||
};
|
||||
|
||||
return mirror;
|
||||
};
|
||||
|
||||
CodeMirror.isProbablySupported = function() {
|
||||
// This is rather awful, but can be useful.
|
||||
var match;
|
||||
if (window.opera)
|
||||
return Number(window.opera.version()) >= 9.52;
|
||||
else if (/Apple Computer, Inc/.test(navigator.vendor) && (match = navigator.userAgent.match(/Version\/(\d+(?:\.\d+)?)\./)))
|
||||
return Number(match[1]) >= 3;
|
||||
else if (document.selection && window.ActiveXObject && (match = navigator.userAgent.match(/MSIE (\d+(?:\.\d*)?)\b/)))
|
||||
return Number(match[1]) >= 6;
|
||||
else if (match = navigator.userAgent.match(/gecko\/(\d{8})/i))
|
||||
return Number(match[1]) >= 20050901;
|
||||
else if (match = navigator.userAgent.match(/AppleWebKit\/(\d+)/))
|
||||
return Number(match[1]) >= 525;
|
||||
else
|
||||
return null;
|
||||
};
|
||||
|
||||
return CodeMirror;
|
||||
})();
|
||||
1671
includes/js/codemirror/editor.js
Normal file
68
includes/js/codemirror/highlight.js
Normal file
@@ -0,0 +1,68 @@
|
||||
// Minimal framing needed to use CodeMirror-style parsers to highlight
|
||||
// code. Load this along with tokenize.js, stringstream.js, and your
|
||||
// parser. Then call highlightText, passing a string as the first
|
||||
// argument, and as the second argument either a callback function
|
||||
// that will be called with an array of SPAN nodes for every line in
|
||||
// the code, or a DOM node to which to append these spans, and
|
||||
// optionally (not needed if you only loaded one parser) a parser
|
||||
// object.
|
||||
|
||||
// Stuff from util.js that the parsers are using.
|
||||
var StopIteration = {toString: function() {return "StopIteration"}};
|
||||
|
||||
var Editor = {};
|
||||
var indentUnit = 2;
|
||||
|
||||
(function(){
|
||||
function normaliseString(string) {
|
||||
var tab = "";
|
||||
for (var i = 0; i < indentUnit; i++) tab += " ";
|
||||
|
||||
string = string.replace(/\t/g, tab).replace(/\u00a0/g, " ").replace(/\r\n?/g, "\n");
|
||||
var pos = 0, parts = [], lines = string.split("\n");
|
||||
for (var line = 0; line < lines.length; line++) {
|
||||
if (line != 0) parts.push("\n");
|
||||
parts.push(lines[line]);
|
||||
}
|
||||
|
||||
return {
|
||||
next: function() {
|
||||
if (pos < parts.length) return parts[pos++];
|
||||
else throw StopIteration;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
window.highlightText = function(string, callback, parser) {
|
||||
parser = (parser || Editor.Parser).make(stringStream(normaliseString(string)));
|
||||
var line = [];
|
||||
if (callback.nodeType == 1) {
|
||||
var node = callback;
|
||||
callback = function(line) {
|
||||
for (var i = 0; i < line.length; i++)
|
||||
node.appendChild(line[i]);
|
||||
node.appendChild(document.createElement("br"));
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
while (true) {
|
||||
var token = parser.next();
|
||||
if (token.value == "\n") {
|
||||
callback(line);
|
||||
line = [];
|
||||
}
|
||||
else {
|
||||
var span = document.createElement("span");
|
||||
span.className = token.style;
|
||||
span.appendChild(document.createTextNode(token.value));
|
||||
line.push(span);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
if (e != StopIteration) throw e;
|
||||
}
|
||||
if (line.length) callback(line);
|
||||
}
|
||||
})();
|
||||
81
includes/js/codemirror/mirrorframe.js
Normal file
@@ -0,0 +1,81 @@
|
||||
/* Demonstration of embedding CodeMirror in a bigger application. The
|
||||
* interface defined here is a mess of prompts and confirms, and
|
||||
* should probably not be used in a real project.
|
||||
*/
|
||||
|
||||
function MirrorFrame(place, options) {
|
||||
this.home = document.createElement("div");
|
||||
if (place.appendChild)
|
||||
place.appendChild(this.home);
|
||||
else
|
||||
place(this.home);
|
||||
|
||||
var self = this;
|
||||
function makeButton(name, action) {
|
||||
var button = document.createElement("input");
|
||||
button.type = "button";
|
||||
button.value = name;
|
||||
self.home.appendChild(button);
|
||||
button.onclick = function(){self[action].call(self);};
|
||||
}
|
||||
|
||||
makeButton("Search", "search");
|
||||
makeButton("Replace", "replace");
|
||||
makeButton("Current line", "line");
|
||||
makeButton("Jump to line", "jump");
|
||||
makeButton("Insert constructor", "macro");
|
||||
makeButton("Indent all", "reindent");
|
||||
|
||||
this.mirror = new CodeMirror(this.home, options);
|
||||
}
|
||||
|
||||
MirrorFrame.prototype = {
|
||||
search: function() {
|
||||
var text = prompt("Enter search term:", "");
|
||||
if (!text) return;
|
||||
|
||||
var first = true;
|
||||
do {
|
||||
var cursor = this.mirror.getSearchCursor(text, first);
|
||||
first = false;
|
||||
while (cursor.findNext()) {
|
||||
cursor.select();
|
||||
if (!confirm("Search again?"))
|
||||
return;
|
||||
}
|
||||
} while (confirm("End of document reached. Start over?"));
|
||||
},
|
||||
|
||||
replace: function() {
|
||||
// This is a replace-all, but it is possible to implement a
|
||||
// prompting replace.
|
||||
var from = prompt("Enter search string:", ""), to;
|
||||
if (from) to = prompt("What should it be replaced with?", "");
|
||||
if (to == null) return;
|
||||
|
||||
var cursor = this.mirror.getSearchCursor(from, false);
|
||||
while (cursor.findNext())
|
||||
cursor.replace(to);
|
||||
},
|
||||
|
||||
jump: function() {
|
||||
var line = prompt("Jump to line:", "");
|
||||
if (line && !isNaN(Number(line)))
|
||||
this.mirror.jumpToLine(Number(line));
|
||||
},
|
||||
|
||||
line: function() {
|
||||
alert("The cursor is currently at line " + this.mirror.currentLine());
|
||||
this.mirror.focus();
|
||||
},
|
||||
|
||||
macro: function() {
|
||||
var name = prompt("Name your constructor:", "");
|
||||
if (name)
|
||||
this.mirror.replaceSelection("function " + name + "() {\n \n}\n\n" + name + ".prototype = {\n \n};\n");
|
||||
},
|
||||
|
||||
reindent: function() {
|
||||
this.mirror.reindent();
|
||||
}
|
||||
};
|
||||
161
includes/js/codemirror/parsecss.js
Normal file
@@ -0,0 +1,161 @@
|
||||
/* Simple parser for CSS */
|
||||
|
||||
var CSSParser = Editor.Parser = (function() {
|
||||
var tokenizeCSS = (function() {
|
||||
function normal(source, setState) {
|
||||
var ch = source.next();
|
||||
if (ch == "@") {
|
||||
source.nextWhileMatches(/\w/);
|
||||
return "css-at";
|
||||
}
|
||||
else if (ch == "/" && source.equals("*")) {
|
||||
setState(inCComment);
|
||||
return null;
|
||||
}
|
||||
else if (ch == "<" && source.equals("!")) {
|
||||
setState(inSGMLComment);
|
||||
return null;
|
||||
}
|
||||
else if (ch == "=") {
|
||||
return "css-compare";
|
||||
}
|
||||
else if (source.equals("=") && (ch == "~" || ch == "|")) {
|
||||
source.next();
|
||||
return "css-compare";
|
||||
}
|
||||
else if (ch == "\"" || ch == "'") {
|
||||
setState(inString(ch));
|
||||
return null;
|
||||
}
|
||||
else if (ch == "#") {
|
||||
source.nextWhileMatches(/\w/);
|
||||
return "css-hash";
|
||||
}
|
||||
else if (ch == "!") {
|
||||
source.nextWhileMatches(/[ \t]/);
|
||||
source.nextWhileMatches(/\w/);
|
||||
return "css-important";
|
||||
}
|
||||
else if (/\d/.test(ch)) {
|
||||
source.nextWhileMatches(/[\w.%]/);
|
||||
return "css-unit";
|
||||
}
|
||||
else if (/[,.+>*\/]/.test(ch)) {
|
||||
return "css-select-op";
|
||||
}
|
||||
else if (/[;{}:\[\]]/.test(ch)) {
|
||||
return "css-punctuation";
|
||||
}
|
||||
else {
|
||||
source.nextWhileMatches(/[\w\\\-_]/);
|
||||
return "css-identifier";
|
||||
}
|
||||
}
|
||||
|
||||
function inCComment(source, setState) {
|
||||
var maybeEnd = false;
|
||||
while (!source.endOfLine()) {
|
||||
var ch = source.next();
|
||||
if (maybeEnd && ch == "/") {
|
||||
setState(normal);
|
||||
break;
|
||||
}
|
||||
maybeEnd = (ch == "*");
|
||||
}
|
||||
return "css-comment";
|
||||
}
|
||||
|
||||
function inSGMLComment(source, setState) {
|
||||
var dashes = 0;
|
||||
while (!source.endOfLine()) {
|
||||
var ch = source.next();
|
||||
if (dashes >= 2 && ch == ">") {
|
||||
setState(normal);
|
||||
break;
|
||||
}
|
||||
dashes = (ch == "-") ? dashes + 1 : 0;
|
||||
}
|
||||
return "css-comment";
|
||||
}
|
||||
|
||||
function inString(quote) {
|
||||
return function(source, setState) {
|
||||
var escaped = false;
|
||||
while (!source.endOfLine()) {
|
||||
var ch = source.next();
|
||||
if (ch == quote && !escaped)
|
||||
break;
|
||||
escaped = !escaped && ch == "\\";
|
||||
}
|
||||
if (!escaped)
|
||||
setState(normal);
|
||||
return "css-string";
|
||||
};
|
||||
}
|
||||
|
||||
return function(source, startState) {
|
||||
return tokenizer(source, startState || normal);
|
||||
};
|
||||
})();
|
||||
|
||||
function indentCSS(inBraces, inRule, base) {
|
||||
return function(nextChars) {
|
||||
if (!inBraces || /^\}/.test(nextChars)) return base;
|
||||
else if (inRule) return base + indentUnit * 2;
|
||||
else return base + indentUnit;
|
||||
};
|
||||
}
|
||||
|
||||
// This is a very simplistic parser -- since CSS does not really
|
||||
// nest, it works acceptably well, but some nicer colouroing could
|
||||
// be provided with a more complicated parser.
|
||||
function parseCSS(source, basecolumn) {
|
||||
basecolumn = basecolumn || 0;
|
||||
var tokens = tokenizeCSS(source);
|
||||
var inBraces = false, inRule = false, inDecl = false;;
|
||||
|
||||
var iter = {
|
||||
next: function() {
|
||||
var token = tokens.next(), style = token.style, content = token.content;
|
||||
|
||||
if (style == "css-hash")
|
||||
style = token.style = inRule ? "css-colorcode" : "css-identifier";
|
||||
if (style == "css-identifier") {
|
||||
if (inRule) token.style = "css-value";
|
||||
else if (!inBraces && !inDecl) token.style = "css-selector";
|
||||
}
|
||||
|
||||
if (content == "\n")
|
||||
token.indentation = indentCSS(inBraces, inRule, basecolumn);
|
||||
|
||||
if (content == "{" && inDecl == "@media")
|
||||
inDecl = false;
|
||||
else if (content == "{")
|
||||
inBraces = true;
|
||||
else if (content == "}")
|
||||
inBraces = inRule = inDecl = false;
|
||||
else if (content == ";")
|
||||
inRule = inDecl = false;
|
||||
else if (inBraces && style != "css-comment" && style != "whitespace")
|
||||
inRule = true;
|
||||
else if (!inBraces && style == "css-at")
|
||||
inDecl = content;
|
||||
|
||||
return token;
|
||||
},
|
||||
|
||||
copy: function() {
|
||||
var _inBraces = inBraces, _inRule = inRule, _tokenState = tokens.state;
|
||||
return function(source) {
|
||||
tokens = tokenizeCSS(source, _tokenState);
|
||||
inBraces = _inBraces;
|
||||
inRule = _inRule;
|
||||
return iter;
|
||||
};
|
||||
}
|
||||
};
|
||||
return iter;
|
||||
}
|
||||
|
||||
return {make: parseCSS, electricChars: "}"};
|
||||
})();
|
||||
32
includes/js/codemirror/parsedummy.js
Normal file
@@ -0,0 +1,32 @@
|
||||
var DummyParser = Editor.Parser = (function() {
|
||||
function tokenizeDummy(source) {
|
||||
while (!source.endOfLine()) source.next();
|
||||
return "text";
|
||||
}
|
||||
function parseDummy(source) {
|
||||
function indentTo(n) {return function() {return n;}}
|
||||
source = tokenizer(source, tokenizeDummy);
|
||||
var space = 0;
|
||||
|
||||
var iter = {
|
||||
next: function() {
|
||||
var tok = source.next();
|
||||
if (tok.type == "whitespace") {
|
||||
if (tok.value == "\n") tok.indentation = indentTo(space);
|
||||
else space = tok.value.length;
|
||||
}
|
||||
return tok;
|
||||
},
|
||||
copy: function() {
|
||||
var _space = space;
|
||||
return function(_source) {
|
||||
space = _space;
|
||||
source = tokenizer(_source, tokenizeDummy);
|
||||
return iter;
|
||||
};
|
||||
}
|
||||
};
|
||||
return iter;
|
||||
}
|
||||
return {make: parseDummy};
|
||||
})();
|
||||
93
includes/js/codemirror/parsehtmlmixed.js
Normal file
@@ -0,0 +1,93 @@
|
||||
var HTMLMixedParser = Editor.Parser = (function() {
|
||||
|
||||
// tags that trigger seperate parsers
|
||||
var triggers = {
|
||||
"script": "JSParser",
|
||||
"style": "CSSParser"
|
||||
};
|
||||
|
||||
function checkDependencies() {
|
||||
var parsers = ['XMLParser'];
|
||||
for (var p in triggers) parsers.push(triggers[p]);
|
||||
for (var i in parsers) {
|
||||
if (!window[parsers[i]]) throw new Error(parsers[i] + " parser must be loaded for HTML mixed mode to work.");
|
||||
}
|
||||
XMLParser.configure({useHTMLKludges: true});
|
||||
}
|
||||
|
||||
function parseMixed(stream) {
|
||||
checkDependencies();
|
||||
var htmlParser = XMLParser.make(stream), localParser = null, inTag = false;
|
||||
var iter = {next: top, copy: copy};
|
||||
|
||||
function top() {
|
||||
var token = htmlParser.next();
|
||||
if (token.content == "<")
|
||||
inTag = true;
|
||||
else if (token.style == "xml-tagname" && inTag === true)
|
||||
inTag = token.content.toLowerCase();
|
||||
else if (token.content == ">") {
|
||||
if (triggers[inTag]) {
|
||||
var parser = window[triggers[inTag]];
|
||||
iter.next = local(parser, "</" + inTag);
|
||||
}
|
||||
inTag = false;
|
||||
}
|
||||
return token;
|
||||
}
|
||||
function local(parser, tag) {
|
||||
var baseIndent = htmlParser.indentation();
|
||||
localParser = parser.make(stream, baseIndent + indentUnit);
|
||||
return function() {
|
||||
if (stream.lookAhead(tag, false, false, true)) {
|
||||
localParser = null;
|
||||
iter.next = top;
|
||||
return top();
|
||||
}
|
||||
|
||||
var token = localParser.next();
|
||||
var lt = token.value.lastIndexOf("<"), sz = Math.min(token.value.length - lt, tag.length);
|
||||
if (lt != -1 && token.value.slice(lt, lt + sz).toLowerCase() == tag.slice(0, sz) &&
|
||||
stream.lookAhead(tag.slice(sz), false, false, true)) {
|
||||
stream.push(token.value.slice(lt));
|
||||
token.value = token.value.slice(0, lt);
|
||||
}
|
||||
|
||||
if (token.indentation) {
|
||||
var oldIndent = token.indentation;
|
||||
token.indentation = function(chars) {
|
||||
if (chars == "</")
|
||||
return baseIndent;
|
||||
else
|
||||
return oldIndent(chars);
|
||||
};
|
||||
}
|
||||
|
||||
return token;
|
||||
};
|
||||
}
|
||||
|
||||
function copy() {
|
||||
var _html = htmlParser.copy(), _local = localParser && localParser.copy(),
|
||||
_next = iter.next, _inTag = inTag;
|
||||
return function(_stream) {
|
||||
stream = _stream;
|
||||
htmlParser = _html(_stream);
|
||||
localParser = _local && _local(_stream);
|
||||
iter.next = _next;
|
||||
inTag = _inTag;
|
||||
return iter;
|
||||
};
|
||||
}
|
||||
return iter;
|
||||
}
|
||||
|
||||
return {
|
||||
make: parseMixed,
|
||||
electricChars: "{}/:",
|
||||
configure: function(obj) {
|
||||
if (obj.triggers) triggers = obj.triggers;
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
359
includes/js/codemirror/parsejavascript.js
Normal file
@@ -0,0 +1,359 @@
|
||||
/* Parse function for JavaScript. Makes use of the tokenizer from
|
||||
* tokenizejavascript.js. Note that your parsers do not have to be
|
||||
* this complicated -- if you don't want to recognize local variables,
|
||||
* in many languages it is enough to just look for braces, semicolons,
|
||||
* parentheses, etc, and know when you are inside a string or comment.
|
||||
*
|
||||
* See manual.html for more info about the parser interface.
|
||||
*/
|
||||
|
||||
var JSParser = Editor.Parser = (function() {
|
||||
// Token types that can be considered to be atoms.
|
||||
var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};
|
||||
// Setting that can be used to have JSON data indent properly.
|
||||
var json = false;
|
||||
// Constructor for the lexical context objects.
|
||||
function JSLexical(indented, column, type, align, prev, info) {
|
||||
// indentation at start of this line
|
||||
this.indented = indented;
|
||||
// column at which this scope was opened
|
||||
this.column = column;
|
||||
// type of scope ('vardef', 'stat' (statement), 'form' (special form), '[', '{', or '(')
|
||||
this.type = type;
|
||||
// '[', '{', or '(' blocks that have any text after their opening
|
||||
// character are said to be 'aligned' -- any lines below are
|
||||
// indented all the way to the opening character.
|
||||
if (align != null)
|
||||
this.align = align;
|
||||
// Parent scope, if any.
|
||||
this.prev = prev;
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
// My favourite JavaScript indentation rules.
|
||||
function indentJS(lexical) {
|
||||
return function(firstChars) {
|
||||
var firstChar = firstChars && firstChars.charAt(0), type = lexical.type;
|
||||
var closing = firstChar == type;
|
||||
if (type == "vardef")
|
||||
return lexical.indented + 4;
|
||||
else if (type == "form" && firstChar == "{")
|
||||
return lexical.indented;
|
||||
else if (type == "stat" || type == "form")
|
||||
return lexical.indented + indentUnit;
|
||||
else if (lexical.info == "switch" && !closing)
|
||||
return lexical.indented + (/^(?:case|default)\b/.test(firstChars) ? indentUnit : 2 * indentUnit);
|
||||
else if (lexical.align)
|
||||
return lexical.column - (closing ? 1 : 0);
|
||||
else
|
||||
return lexical.indented + (closing ? 0 : indentUnit);
|
||||
};
|
||||
}
|
||||
|
||||
// The parser-iterator-producing function itself.
|
||||
function parseJS(input, basecolumn) {
|
||||
// Wrap the input in a token stream
|
||||
var tokens = tokenizeJavaScript(input);
|
||||
// The parser state. cc is a stack of actions that have to be
|
||||
// performed to finish the current statement. For example we might
|
||||
// know that we still need to find a closing parenthesis and a
|
||||
// semicolon. Actions at the end of the stack go first. It is
|
||||
// initialized with an infinitely looping action that consumes
|
||||
// whole statements.
|
||||
var cc = [json ? expressions : statements];
|
||||
// Context contains information about the current local scope, the
|
||||
// variables defined in that, and the scopes above it.
|
||||
var context = null;
|
||||
// The lexical scope, used mostly for indentation.
|
||||
var lexical = new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false);
|
||||
// Current column, and the indentation at the start of the current
|
||||
// line. Used to create lexical scope objects.
|
||||
var column = 0;
|
||||
var indented = 0;
|
||||
// Variables which are used by the mark, cont, and pass functions
|
||||
// below to communicate with the driver loop in the 'next'
|
||||
// function.
|
||||
var consume, marked;
|
||||
|
||||
// The iterator object.
|
||||
var parser = {next: next, copy: copy};
|
||||
|
||||
function next(){
|
||||
// Start by performing any 'lexical' actions (adjusting the
|
||||
// lexical variable), or the operations below will be working
|
||||
// with the wrong lexical state.
|
||||
while(cc[cc.length - 1].lex)
|
||||
cc.pop()();
|
||||
|
||||
// Fetch a token.
|
||||
var token = tokens.next();
|
||||
|
||||
// Adjust column and indented.
|
||||
if (token.type == "whitespace" && column == 0)
|
||||
indented = token.value.length;
|
||||
column += token.value.length;
|
||||
if (token.content == "\n"){
|
||||
indented = column = 0;
|
||||
// If the lexical scope's align property is still undefined at
|
||||
// the end of the line, it is an un-aligned scope.
|
||||
if (!("align" in lexical))
|
||||
lexical.align = false;
|
||||
// Newline tokens get an indentation function associated with
|
||||
// them.
|
||||
token.indentation = indentJS(lexical);
|
||||
}
|
||||
// No more processing for meaningless tokens.
|
||||
if (token.type == "whitespace" || token.type == "comment")
|
||||
return token;
|
||||
// When a meaningful token is found and the lexical scope's
|
||||
// align is undefined, it is an aligned scope.
|
||||
if (!("align" in lexical))
|
||||
lexical.align = true;
|
||||
|
||||
// Execute actions until one 'consumes' the token and we can
|
||||
// return it.
|
||||
while(true) {
|
||||
consume = marked = false;
|
||||
// Take and execute the topmost action.
|
||||
cc.pop()(token.type, token.content);
|
||||
if (consume){
|
||||
// Marked is used to change the style of the current token.
|
||||
if (marked)
|
||||
token.style = marked;
|
||||
// Here we differentiate between local and global variables.
|
||||
else if (token.type == "variable" && inScope(token.content))
|
||||
token.style = "js-localvariable";
|
||||
return token;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This makes a copy of the parser state. It stores all the
|
||||
// stateful variables in a closure, and returns a function that
|
||||
// will restore them when called with a new input stream. Note
|
||||
// that the cc array has to be copied, because it is contantly
|
||||
// being modified. Lexical objects are not mutated, and context
|
||||
// objects are not mutated in a harmful way, so they can be shared
|
||||
// between runs of the parser.
|
||||
function copy(){
|
||||
var _context = context, _lexical = lexical, _cc = cc.concat([]), _tokenState = tokens.state;
|
||||
|
||||
return function copyParser(input){
|
||||
context = _context;
|
||||
lexical = _lexical;
|
||||
cc = _cc.concat([]); // copies the array
|
||||
column = indented = 0;
|
||||
tokens = tokenizeJavaScript(input, _tokenState);
|
||||
return parser;
|
||||
};
|
||||
}
|
||||
|
||||
// Helper function for pushing a number of actions onto the cc
|
||||
// stack in reverse order.
|
||||
function push(fs){
|
||||
for (var i = fs.length - 1; i >= 0; i--)
|
||||
cc.push(fs[i]);
|
||||
}
|
||||
// cont and pass are used by the action functions to add other
|
||||
// actions to the stack. cont will cause the current token to be
|
||||
// consumed, pass will leave it for the next action.
|
||||
function cont(){
|
||||
push(arguments);
|
||||
consume = true;
|
||||
}
|
||||
function pass(){
|
||||
push(arguments);
|
||||
consume = false;
|
||||
}
|
||||
// Used to change the style of the current token.
|
||||
function mark(style){
|
||||
marked = style;
|
||||
}
|
||||
|
||||
// Push a new scope. Will automatically link the current scope.
|
||||
function pushcontext(){
|
||||
context = {prev: context, vars: {"this": true, "arguments": true}};
|
||||
}
|
||||
// Pop off the current scope.
|
||||
function popcontext(){
|
||||
context = context.prev;
|
||||
}
|
||||
// Register a variable in the current scope.
|
||||
function register(varname){
|
||||
if (context){
|
||||
mark("js-variabledef");
|
||||
context.vars[varname] = true;
|
||||
}
|
||||
}
|
||||
// Check whether a variable is defined in the current scope.
|
||||
function inScope(varname){
|
||||
var cursor = context;
|
||||
while (cursor) {
|
||||
if (cursor.vars[varname])
|
||||
return true;
|
||||
cursor = cursor.prev;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Push a new lexical context of the given type.
|
||||
function pushlex(type, info) {
|
||||
var result = function(){
|
||||
lexical = new JSLexical(indented, column, type, null, lexical, info)
|
||||
};
|
||||
result.lex = true;
|
||||
return result;
|
||||
}
|
||||
// Pop off the current lexical context.
|
||||
function poplex(){
|
||||
if (lexical.type == ")")
|
||||
indented = lexical.indented;
|
||||
lexical = lexical.prev;
|
||||
}
|
||||
poplex.lex = true;
|
||||
// The 'lex' flag on these actions is used by the 'next' function
|
||||
// to know they can (and have to) be ran before moving on to the
|
||||
// next token.
|
||||
|
||||
// Creates an action that discards tokens until it finds one of
|
||||
// the given type.
|
||||
function expect(wanted){
|
||||
return function expecting(type){
|
||||
if (type == wanted) cont();
|
||||
else if (wanted == ";") pass();
|
||||
else cont(arguments.callee);
|
||||
};
|
||||
}
|
||||
|
||||
// Looks for a statement, and then calls itself.
|
||||
function statements(type){
|
||||
return pass(statement, statements);
|
||||
}
|
||||
function expressions(type){
|
||||
return pass(expression, expressions);
|
||||
}
|
||||
// Dispatches various types of statements based on the type of the
|
||||
// current token.
|
||||
function statement(type){
|
||||
if (type == "var") cont(pushlex("vardef"), vardef1, expect(";"), poplex);
|
||||
else if (type == "keyword a") cont(pushlex("form"), expression, statement, poplex);
|
||||
else if (type == "keyword b") cont(pushlex("form"), statement, poplex);
|
||||
else if (type == "{") cont(pushlex("}"), block, poplex);
|
||||
else if (type == ";") cont();
|
||||
else if (type == "function") cont(functiondef);
|
||||
else if (type == "for") cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"), poplex, statement, poplex);
|
||||
else if (type == "variable") cont(pushlex("stat"), maybelabel);
|
||||
else if (type == "switch") cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), block, poplex, poplex);
|
||||
else if (type == "case") cont(expression, expect(":"));
|
||||
else if (type == "default") cont(expect(":"));
|
||||
else if (type == "catch") cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), statement, poplex, popcontext);
|
||||
else pass(pushlex("stat"), expression, expect(";"), poplex);
|
||||
}
|
||||
// Dispatch expression types.
|
||||
function expression(type){
|
||||
if (atomicTypes.hasOwnProperty(type)) cont(maybeoperator);
|
||||
else if (type == "function") cont(functiondef);
|
||||
else if (type == "keyword c") cont(expression);
|
||||
else if (type == "(") cont(pushlex(")"), expression, expect(")"), poplex, maybeoperator);
|
||||
else if (type == "operator") cont(expression);
|
||||
else if (type == "[") cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
|
||||
else if (type == "{") cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
|
||||
else cont();
|
||||
}
|
||||
// Called for places where operators, function calls, or
|
||||
// subscripts are valid. Will skip on to the next action if none
|
||||
// is found.
|
||||
function maybeoperator(type, value){
|
||||
if (type == "operator" && /\+\+|--/.test(value)) cont(maybeoperator);
|
||||
else if (type == "operator") cont(expression);
|
||||
else if (type == ";") pass();
|
||||
else if (type == "(") cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);
|
||||
else if (type == ".") cont(property, maybeoperator);
|
||||
else if (type == "[") cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
|
||||
}
|
||||
// When a statement starts with a variable name, it might be a
|
||||
// label. If no colon follows, it's a regular statement.
|
||||
function maybelabel(type){
|
||||
if (type == ":") cont(poplex, statement);
|
||||
else pass(maybeoperator, expect(";"), poplex);
|
||||
}
|
||||
// Property names need to have their style adjusted -- the
|
||||
// tokenizer thinks they are variables.
|
||||
function property(type){
|
||||
if (type == "variable") {mark("js-property"); cont();}
|
||||
}
|
||||
// This parses a property and its value in an object literal.
|
||||
function objprop(type){
|
||||
if (type == "variable") mark("js-property");
|
||||
if (atomicTypes.hasOwnProperty(type)) cont(expect(":"), expression);
|
||||
}
|
||||
// Parses a comma-separated list of the things that are recognized
|
||||
// by the 'what' argument.
|
||||
function commasep(what, end){
|
||||
function proceed(type) {
|
||||
if (type == ",") cont(what, proceed);
|
||||
else if (type == end) cont();
|
||||
else cont(expect(end));
|
||||
}
|
||||
return function commaSeparated(type) {
|
||||
if (type == end) cont();
|
||||
else pass(what, proceed);
|
||||
};
|
||||
}
|
||||
// Look for statements until a closing brace is found.
|
||||
function block(type){
|
||||
if (type == "}") cont();
|
||||
else pass(statement, block);
|
||||
}
|
||||
// Variable definitions are split into two actions -- 1 looks for
|
||||
// a name or the end of the definition, 2 looks for an '=' sign or
|
||||
// a comma.
|
||||
function vardef1(type, value){
|
||||
if (type == "variable"){register(value); cont(vardef2);}
|
||||
else cont();
|
||||
}
|
||||
function vardef2(type, value){
|
||||
if (value == "=") cont(expression, vardef2);
|
||||
else if (type == ",") cont(vardef1);
|
||||
}
|
||||
// For loops.
|
||||
function forspec1(type){
|
||||
if (type == "var") cont(vardef1, forspec2);
|
||||
else if (type == ";") pass(forspec2);
|
||||
else if (type == "variable") cont(formaybein);
|
||||
else pass(forspec2);
|
||||
}
|
||||
function formaybein(type, value){
|
||||
if (value == "in") cont(expression);
|
||||
else cont(maybeoperator, forspec2);
|
||||
}
|
||||
function forspec2(type, value){
|
||||
if (type == ";") cont(forspec3);
|
||||
else if (value == "in") cont(expression);
|
||||
else cont(expression, expect(";"), forspec3);
|
||||
}
|
||||
function forspec3(type) {
|
||||
if (type == ")") pass();
|
||||
else cont(expression);
|
||||
}
|
||||
// A function definition creates a new context, and the variables
|
||||
// in its argument list have to be added to this context.
|
||||
function functiondef(type, value){
|
||||
if (type == "variable"){register(value); cont(functiondef);}
|
||||
else if (type == "(") cont(pushcontext, commasep(funarg, ")"), statement, popcontext);
|
||||
}
|
||||
function funarg(type, value){
|
||||
if (type == "variable"){register(value); cont();}
|
||||
}
|
||||
|
||||
return parser;
|
||||
}
|
||||
|
||||
return {
|
||||
make: parseJS,
|
||||
electricChars: "{}:",
|
||||
configure: function(obj) {
|
||||
if (obj.json != null) json = obj.json;
|
||||
}
|
||||
};
|
||||
})();
|
||||
162
includes/js/codemirror/parsesparql.js
Normal file
@@ -0,0 +1,162 @@
|
||||
var SparqlParser = Editor.Parser = (function() {
|
||||
function wordRegexp(words) {
|
||||
return new RegExp("^(?:" + words.join("|") + ")$", "i");
|
||||
}
|
||||
var ops = wordRegexp(["str", "lang", "langmatches", "datatype", "bound", "sameterm", "isiri", "isuri",
|
||||
"isblank", "isliteral", "union", "a"]);
|
||||
var keywords = wordRegexp(["base", "prefix", "select", "distinct", "reduced", "construct", "describe",
|
||||
"ask", "from", "named", "where", "order", "limit", "offset", "filter", "optional",
|
||||
"graph", "by", "asc", "desc"]);
|
||||
var operatorChars = /[*+\-<>=&|]/;
|
||||
|
||||
var tokenizeSparql = (function() {
|
||||
function normal(source, setState) {
|
||||
var ch = source.next();
|
||||
if (ch == "$" || ch == "?") {
|
||||
source.nextWhileMatches(/[\w\d]/);
|
||||
return "sp-var";
|
||||
}
|
||||
else if (ch == "<" && !source.matches(/[\s\u00a0=]/)) {
|
||||
source.nextWhileMatches(/[^\s\u00a0>]/);
|
||||
if (source.equals(">")) source.next();
|
||||
return "sp-uri";
|
||||
}
|
||||
else if (ch == "\"" || ch == "'") {
|
||||
setState(inLiteral(ch));
|
||||
return null;
|
||||
}
|
||||
else if (/[{}\(\),\.;\[\]]/.test(ch)) {
|
||||
return "sp-punc";
|
||||
}
|
||||
else if (ch == "#") {
|
||||
while (!source.endOfLine()) source.next();
|
||||
return "sp-comment";
|
||||
}
|
||||
else if (operatorChars.test(ch)) {
|
||||
source.nextWhileMatches(operatorChars);
|
||||
return "sp-operator";
|
||||
}
|
||||
else if (ch == ":") {
|
||||
source.nextWhileMatches(/[\w\d\._\-]/);
|
||||
return "sp-prefixed";
|
||||
}
|
||||
else {
|
||||
source.nextWhileMatches(/[_\w\d]/);
|
||||
if (source.equals(":")) {
|
||||
source.next();
|
||||
source.nextWhileMatches(/[\w\d_\-]/);
|
||||
return "sp-prefixed";
|
||||
}
|
||||
var word = source.get(), type;
|
||||
if (ops.test(word))
|
||||
type = "sp-operator";
|
||||
else if (keywords.test(word))
|
||||
type = "sp-keyword";
|
||||
else
|
||||
type = "sp-word";
|
||||
return {style: type, content: word};
|
||||
}
|
||||
}
|
||||
|
||||
function inLiteral(quote) {
|
||||
return function(source, setState) {
|
||||
var escaped = false;
|
||||
while (!source.endOfLine()) {
|
||||
var ch = source.next();
|
||||
if (ch == quote && !escaped) {
|
||||
setState(normal);
|
||||
break;
|
||||
}
|
||||
escaped = !escaped && ch == "\\";
|
||||
}
|
||||
return "sp-literal";
|
||||
};
|
||||
}
|
||||
|
||||
return function(source, startState) {
|
||||
return tokenizer(source, startState || normal);
|
||||
};
|
||||
})();
|
||||
|
||||
function indentSparql(context) {
|
||||
return function(nextChars) {
|
||||
var firstChar = nextChars && nextChars.charAt(0);
|
||||
if (/[\]\}]/.test(firstChar))
|
||||
while (context && context.type == "pattern") context = context.prev;
|
||||
|
||||
var closing = context && firstChar == matching[context.type];
|
||||
if (!context)
|
||||
return 0;
|
||||
else if (context.type == "pattern")
|
||||
return context.col;
|
||||
else if (context.align)
|
||||
return context.col - (closing ? context.width : 0);
|
||||
else
|
||||
return context.indent + (closing ? 0 : indentUnit);
|
||||
}
|
||||
}
|
||||
|
||||
function parseSparql(source) {
|
||||
var tokens = tokenizeSparql(source);
|
||||
var context = null, indent = 0, col = 0;
|
||||
function pushContext(type, width) {
|
||||
context = {prev: context, indent: indent, col: col, type: type, width: width};
|
||||
}
|
||||
function popContext() {
|
||||
context = context.prev;
|
||||
}
|
||||
|
||||
var iter = {
|
||||
next: function() {
|
||||
var token = tokens.next(), type = token.style, content = token.content, width = token.value.length;
|
||||
|
||||
if (content == "\n") {
|
||||
token.indentation = indentSparql(context);
|
||||
indent = col = 0;
|
||||
if (context && context.align == null) context.align = false;
|
||||
}
|
||||
else if (type == "whitespace" && col == 0) {
|
||||
indent = width;
|
||||
}
|
||||
else if (type != "sp-comment" && context && context.align == null) {
|
||||
context.align = true;
|
||||
}
|
||||
|
||||
if (content != "\n") col += width;
|
||||
|
||||
if (/[\[\{\(]/.test(content)) {
|
||||
pushContext(content, width);
|
||||
}
|
||||
else if (/[\]\}\)]/.test(content)) {
|
||||
while (context && context.type == "pattern")
|
||||
popContext();
|
||||
if (context && content == matching[context.type])
|
||||
popContext();
|
||||
}
|
||||
else if (content == "." && context && context.type == "pattern") {
|
||||
popContext();
|
||||
}
|
||||
else if ((type == "sp-word" || type == "sp-prefixed" || type == "sp-uri" || type == "sp-var" || type == "sp-literal") &&
|
||||
context && /[\{\[]/.test(context.type)) {
|
||||
pushContext("pattern", width);
|
||||
}
|
||||
|
||||
return token;
|
||||
},
|
||||
|
||||
copy: function() {
|
||||
var _context = context, _indent = indent, _col = col, _tokenState = tokens.state;
|
||||
return function(source) {
|
||||
tokens = tokenizeSparql(source, _tokenState);
|
||||
context = _context;
|
||||
indent = _indent;
|
||||
col = _col;
|
||||
return iter;
|
||||
};
|
||||
}
|
||||
};
|
||||
return iter;
|
||||
}
|
||||
|
||||
return {make: parseSparql, electricChars: "}]"};
|
||||
})();
|
||||
291
includes/js/codemirror/parsexml.js
Normal file
@@ -0,0 +1,291 @@
|
||||
/* This file defines an XML parser, with a few kludges to make it
|
||||
* useable for HTML. autoSelfClosers defines a set of tag names that
|
||||
* are expected to not have a closing tag, and doNotIndent specifies
|
||||
* the tags inside of which no indentation should happen (see Config
|
||||
* object). These can be disabled by passing the editor an object like
|
||||
* {useHTMLKludges: false} as parserConfig option.
|
||||
*/
|
||||
|
||||
var XMLParser = Editor.Parser = (function() {
|
||||
var Kludges = {
|
||||
autoSelfClosers: {"br": true, "img": true, "hr": true, "link": true, "input": true,
|
||||
"meta": true, "col": true, "frame": true, "base": true, "area": true},
|
||||
doNotIndent: {"pre": true, "!cdata": true}
|
||||
};
|
||||
var NoKludges = {autoSelfClosers: {}, doNotIndent: {"!cdata": true}};
|
||||
var UseKludges = Kludges;
|
||||
var alignCDATA = false;
|
||||
|
||||
// Simple stateful tokenizer for XML documents. Returns a
|
||||
// MochiKit-style iterator, with a state property that contains a
|
||||
// function encapsulating the current state. See tokenize.js.
|
||||
var tokenizeXML = (function() {
|
||||
function inText(source, setState) {
|
||||
var ch = source.next();
|
||||
if (ch == "<") {
|
||||
if (source.equals("!")) {
|
||||
source.next();
|
||||
if (source.equals("[")) {
|
||||
if (source.lookAhead("[CDATA[", true)) {
|
||||
setState(inBlock("xml-cdata", "]]>"));
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return "xml-text";
|
||||
}
|
||||
}
|
||||
else if (source.lookAhead("--", true)) {
|
||||
setState(inBlock("xml-comment", "-->"));
|
||||
return null;
|
||||
}
|
||||
else if (source.lookAhead("DOCTYPE", true)) {
|
||||
source.nextWhileMatches(/[\w\._\-]/);
|
||||
setState(inBlock("xml-doctype", ">"));
|
||||
return "xml-doctype";
|
||||
}
|
||||
else {
|
||||
return "xml-text";
|
||||
}
|
||||
}
|
||||
else if (source.equals("?")) {
|
||||
source.next();
|
||||
source.nextWhileMatches(/[\w\._\-]/);
|
||||
setState(inBlock("xml-processing", "?>"));
|
||||
return "xml-processing";
|
||||
}
|
||||
else {
|
||||
if (source.equals("/")) source.next();
|
||||
setState(inTag);
|
||||
return "xml-punctuation";
|
||||
}
|
||||
}
|
||||
else if (ch == "&") {
|
||||
while (!source.endOfLine()) {
|
||||
if (source.next() == ";")
|
||||
break;
|
||||
}
|
||||
return "xml-entity";
|
||||
}
|
||||
else {
|
||||
source.nextWhileMatches(/[^&<\n]/);
|
||||
return "xml-text";
|
||||
}
|
||||
}
|
||||
|
||||
function inTag(source, setState) {
|
||||
var ch = source.next();
|
||||
if (ch == ">") {
|
||||
setState(inText);
|
||||
return "xml-punctuation";
|
||||
}
|
||||
else if (/[?\/]/.test(ch) && source.equals(">")) {
|
||||
source.next();
|
||||
setState(inText);
|
||||
return "xml-punctuation";
|
||||
}
|
||||
else if (ch == "=") {
|
||||
return "xml-punctuation";
|
||||
}
|
||||
else if (/[\'\"]/.test(ch)) {
|
||||
setState(inAttribute(ch));
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
source.nextWhileMatches(/[^\s\u00a0=<>\"\'\/?]/);
|
||||
return "xml-name";
|
||||
}
|
||||
}
|
||||
|
||||
function inAttribute(quote) {
|
||||
return function(source, setState) {
|
||||
while (!source.endOfLine()) {
|
||||
if (source.next() == quote) {
|
||||
setState(inTag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return "xml-attribute";
|
||||
};
|
||||
}
|
||||
|
||||
function inBlock(style, terminator) {
|
||||
return function(source, setState) {
|
||||
while (!source.endOfLine()) {
|
||||
if (source.lookAhead(terminator, true)) {
|
||||
setState(inText);
|
||||
break;
|
||||
}
|
||||
source.next();
|
||||
}
|
||||
return style;
|
||||
};
|
||||
}
|
||||
|
||||
return function(source, startState) {
|
||||
return tokenizer(source, startState || inText);
|
||||
};
|
||||
})();
|
||||
|
||||
// The parser. The structure of this function largely follows that of
|
||||
// parseJavaScript in parsejavascript.js (there is actually a bit more
|
||||
// shared code than I'd like), but it is quite a bit simpler.
|
||||
function parseXML(source) {
|
||||
var tokens = tokenizeXML(source), token;
|
||||
var cc = [base];
|
||||
var tokenNr = 0, indented = 0;
|
||||
var currentTag = null, context = null;
|
||||
var consume;
|
||||
|
||||
function push(fs) {
|
||||
for (var i = fs.length - 1; i >= 0; i--)
|
||||
cc.push(fs[i]);
|
||||
}
|
||||
function cont() {
|
||||
push(arguments);
|
||||
consume = true;
|
||||
}
|
||||
function pass() {
|
||||
push(arguments);
|
||||
consume = false;
|
||||
}
|
||||
|
||||
function markErr() {
|
||||
token.style += " xml-error";
|
||||
}
|
||||
function expect(text) {
|
||||
return function(style, content) {
|
||||
if (content == text) cont();
|
||||
else {markErr(); cont(arguments.callee);}
|
||||
};
|
||||
}
|
||||
|
||||
function pushContext(tagname, startOfLine) {
|
||||
var noIndent = UseKludges.doNotIndent.hasOwnProperty(tagname) || (context && context.noIndent);
|
||||
context = {prev: context, name: tagname, indent: indented, startOfLine: startOfLine, noIndent: noIndent};
|
||||
}
|
||||
function popContext() {
|
||||
context = context.prev;
|
||||
}
|
||||
function computeIndentation(baseContext) {
|
||||
return function(nextChars, current) {
|
||||
var context = baseContext;
|
||||
if (context && context.noIndent)
|
||||
return current;
|
||||
if (alignCDATA && /<!\[CDATA\[/.test(nextChars))
|
||||
return 0;
|
||||
if (context && /^<\//.test(nextChars))
|
||||
context = context.prev;
|
||||
while (context && !context.startOfLine)
|
||||
context = context.prev;
|
||||
if (context)
|
||||
return context.indent + indentUnit;
|
||||
else
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
function base() {
|
||||
return pass(element, base);
|
||||
}
|
||||
var harmlessTokens = {"xml-text": true, "xml-entity": true, "xml-comment": true, "xml-processing": true, "xml-doctype": true};
|
||||
function element(style, content) {
|
||||
if (content == "<") cont(tagname, attributes, endtag(tokenNr == 1));
|
||||
else if (content == "</") cont(closetagname, expect(">"));
|
||||
else if (style == "xml-cdata") {
|
||||
if (!context || context.name != "!cdata") pushContext("!cdata");
|
||||
if (/\]\]>$/.test(content)) popContext();
|
||||
cont();
|
||||
}
|
||||
else if (harmlessTokens.hasOwnProperty(style)) cont();
|
||||
else {markErr(); cont();}
|
||||
}
|
||||
function tagname(style, content) {
|
||||
if (style == "xml-name") {
|
||||
currentTag = content.toLowerCase();
|
||||
token.style = "xml-tagname";
|
||||
cont();
|
||||
}
|
||||
else {
|
||||
currentTag = null;
|
||||
pass();
|
||||
}
|
||||
}
|
||||
function closetagname(style, content) {
|
||||
if (style == "xml-name") {
|
||||
token.style = "xml-tagname";
|
||||
if (context && content.toLowerCase() == context.name) popContext();
|
||||
else markErr();
|
||||
}
|
||||
cont();
|
||||
}
|
||||
function endtag(startOfLine) {
|
||||
return function(style, content) {
|
||||
if (content == "/>" || (content == ">" && UseKludges.autoSelfClosers.hasOwnProperty(currentTag))) cont();
|
||||
else if (content == ">") {pushContext(currentTag, startOfLine); cont();}
|
||||
else {markErr(); cont(arguments.callee);}
|
||||
};
|
||||
}
|
||||
function attributes(style) {
|
||||
if (style == "xml-name") {token.style = "xml-attname"; cont(attribute, attributes);}
|
||||
else pass();
|
||||
}
|
||||
function attribute(style, content) {
|
||||
if (content == "=") cont(value);
|
||||
else if (content == ">" || content == "/>") pass(endtag);
|
||||
else pass();
|
||||
}
|
||||
function value(style) {
|
||||
if (style == "xml-attribute") cont(value);
|
||||
else pass();
|
||||
}
|
||||
|
||||
return {
|
||||
indentation: function() {return indented;},
|
||||
|
||||
next: function(){
|
||||
token = tokens.next();
|
||||
if (token.style == "whitespace" && tokenNr == 0)
|
||||
indented = token.value.length;
|
||||
else
|
||||
tokenNr++;
|
||||
if (token.content == "\n") {
|
||||
indented = tokenNr = 0;
|
||||
token.indentation = computeIndentation(context);
|
||||
}
|
||||
|
||||
if (token.style == "whitespace" || token.type == "xml-comment")
|
||||
return token;
|
||||
|
||||
while(true){
|
||||
consume = false;
|
||||
cc.pop()(token.style, token.content);
|
||||
if (consume) return token;
|
||||
}
|
||||
},
|
||||
|
||||
copy: function(){
|
||||
var _cc = cc.concat([]), _tokenState = tokens.state, _context = context;
|
||||
var parser = this;
|
||||
|
||||
return function(input){
|
||||
cc = _cc.concat([]);
|
||||
tokenNr = indented = 0;
|
||||
context = _context;
|
||||
tokens = tokenizeXML(input, _tokenState);
|
||||
return parser;
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
make: parseXML,
|
||||
electricChars: "/",
|
||||
configure: function(config) {
|
||||
if (config.useHTMLKludges != null)
|
||||
UseKludges = config.useHTMLKludges ? Kludges : NoKludges;
|
||||
if (config.alignCDATA)
|
||||
alignCDATA = config.alignCDATA;
|
||||
}
|
||||
};
|
||||
})();
|
||||
699
includes/js/codemirror/select.js
Normal file
@@ -0,0 +1,699 @@
|
||||
/* Functionality for finding, storing, and restoring selections
|
||||
*
|
||||
* This does not provide a generic API, just the minimal functionality
|
||||
* required by the CodeMirror system.
|
||||
*/
|
||||
|
||||
// Namespace object.
|
||||
var select = {};
|
||||
|
||||
(function() {
|
||||
select.ie_selection = document.selection && document.selection.createRangeCollection;
|
||||
|
||||
// Find the 'top-level' (defined as 'a direct child of the node
|
||||
// passed as the top argument') node that the given node is
|
||||
// contained in. Return null if the given node is not inside the top
|
||||
// node.
|
||||
function topLevelNodeAt(node, top) {
|
||||
while (node && node.parentNode != top)
|
||||
node = node.parentNode;
|
||||
return node;
|
||||
}
|
||||
|
||||
// Find the top-level node that contains the node before this one.
|
||||
function topLevelNodeBefore(node, top) {
|
||||
while (!node.previousSibling && node.parentNode != top)
|
||||
node = node.parentNode;
|
||||
return topLevelNodeAt(node.previousSibling, top);
|
||||
}
|
||||
|
||||
var fourSpaces = "\u00a0\u00a0\u00a0\u00a0";
|
||||
|
||||
select.scrollToNode = function(node, cursor) {
|
||||
if (!node) return;
|
||||
var element = node, body = document.body,
|
||||
html = document.documentElement,
|
||||
atEnd = !element.nextSibling || !element.nextSibling.nextSibling
|
||||
|| !element.nextSibling.nextSibling.nextSibling;
|
||||
// In Opera (and recent Webkit versions), BR elements *always*
|
||||
// have a offsetTop property of zero.
|
||||
var compensateHack = 0;
|
||||
while (element && !element.offsetTop) {
|
||||
compensateHack++;
|
||||
element = element.previousSibling;
|
||||
}
|
||||
// atEnd is another kludge for these browsers -- if the cursor is
|
||||
// at the end of the document, and the node doesn't have an
|
||||
// offset, just scroll to the end.
|
||||
if (compensateHack == 0) atEnd = false;
|
||||
|
||||
// WebKit has a bad habit of (sometimes) happily returning bogus
|
||||
// offsets when the document has just been changed. This seems to
|
||||
// always be 5/5, so we don't use those.
|
||||
if (webkit && element && element.offsetTop == 5 && element.offsetLeft == 5)
|
||||
return;
|
||||
|
||||
var y = compensateHack * (element ? element.offsetHeight : 0), x = 0,
|
||||
width = (node ? node.offsetWidth : 0), pos = element;
|
||||
while (pos && pos.offsetParent) {
|
||||
y += pos.offsetTop;
|
||||
// Don't count X offset for <br> nodes
|
||||
if (!isBR(pos))
|
||||
x += pos.offsetLeft;
|
||||
pos = pos.offsetParent;
|
||||
}
|
||||
|
||||
var scroll_x = body.scrollLeft || html.scrollLeft || 0,
|
||||
scroll_y = body.scrollTop || html.scrollTop || 0,
|
||||
scroll = false, screen_width = window.innerWidth || html.clientWidth || 0;
|
||||
|
||||
if (cursor || width < screen_width) {
|
||||
if (cursor) {
|
||||
var off = select.offsetInNode(node), size = nodeText(node).length;
|
||||
if (size) x += width * (off / size);
|
||||
}
|
||||
var screen_x = x - scroll_x;
|
||||
if (screen_x < 0 || screen_x > screen_width) {
|
||||
scroll_x = x;
|
||||
scroll = true;
|
||||
}
|
||||
}
|
||||
var screen_y = y - scroll_y;
|
||||
if (screen_y < 0 || atEnd || screen_y > (window.innerHeight || html.clientHeight || 0) - 50) {
|
||||
scroll_y = atEnd ? 1e6 : y;
|
||||
scroll = true;
|
||||
}
|
||||
if (scroll) window.scrollTo(scroll_x, scroll_y);
|
||||
};
|
||||
|
||||
select.scrollToCursor = function(container) {
|
||||
select.scrollToNode(select.selectionTopNode(container, true) || container.firstChild, true);
|
||||
};
|
||||
|
||||
// Used to prevent restoring a selection when we do not need to.
|
||||
var currentSelection = null;
|
||||
|
||||
select.snapshotChanged = function() {
|
||||
if (currentSelection) currentSelection.changed = true;
|
||||
};
|
||||
|
||||
// Find the 'leaf' node (BR or text) after the given one.
|
||||
function baseNodeAfter(node) {
|
||||
var next = node.nextSibling;
|
||||
if (next) {
|
||||
while (next.firstChild) next = next.firstChild;
|
||||
if (next.nodeType == 3 || isBR(next)) return next;
|
||||
else return baseNodeAfter(next);
|
||||
}
|
||||
else {
|
||||
var parent = node.parentNode;
|
||||
while (parent && !parent.nextSibling) parent = parent.parentNode;
|
||||
return parent && baseNodeAfter(parent);
|
||||
}
|
||||
}
|
||||
|
||||
// This is called by the code in editor.js whenever it is replacing
|
||||
// a text node. The function sees whether the given oldNode is part
|
||||
// of the current selection, and updates this selection if it is.
|
||||
// Because nodes are often only partially replaced, the length of
|
||||
// the part that gets replaced has to be taken into account -- the
|
||||
// selection might stay in the oldNode if the newNode is smaller
|
||||
// than the selection's offset. The offset argument is needed in
|
||||
// case the selection does move to the new object, and the given
|
||||
// length is not the whole length of the new node (part of it might
|
||||
// have been used to replace another node).
|
||||
select.snapshotReplaceNode = function(from, to, length, offset) {
|
||||
if (!currentSelection) return;
|
||||
|
||||
function replace(point) {
|
||||
if (from == point.node) {
|
||||
currentSelection.changed = true;
|
||||
if (length && point.offset > length) {
|
||||
point.offset -= length;
|
||||
}
|
||||
else {
|
||||
point.node = to;
|
||||
point.offset += (offset || 0);
|
||||
}
|
||||
}
|
||||
else if (select.ie_selection && point.offset == 0 && point.node == baseNodeAfter(from)) {
|
||||
currentSelection.changed = true;
|
||||
}
|
||||
}
|
||||
replace(currentSelection.start);
|
||||
replace(currentSelection.end);
|
||||
};
|
||||
|
||||
select.snapshotMove = function(from, to, distance, relative, ifAtStart) {
|
||||
if (!currentSelection) return;
|
||||
|
||||
function move(point) {
|
||||
if (from == point.node && (!ifAtStart || point.offset == 0)) {
|
||||
currentSelection.changed = true;
|
||||
point.node = to;
|
||||
if (relative) point.offset = Math.max(0, point.offset + distance);
|
||||
else point.offset = distance;
|
||||
}
|
||||
}
|
||||
move(currentSelection.start);
|
||||
move(currentSelection.end);
|
||||
};
|
||||
|
||||
// Most functions are defined in two ways, one for the IE selection
|
||||
// model, one for the W3C one.
|
||||
if (select.ie_selection) {
|
||||
function selRange() {
|
||||
var sel = document.selection;
|
||||
if (!sel) return null;
|
||||
if (sel.createRange) return sel.createRange();
|
||||
else return sel.createTextRange();
|
||||
}
|
||||
|
||||
function selectionNode(start) {
|
||||
var range = selRange();
|
||||
range.collapse(start);
|
||||
|
||||
function nodeAfter(node) {
|
||||
var found = null;
|
||||
while (!found && node) {
|
||||
found = node.nextSibling;
|
||||
node = node.parentNode;
|
||||
}
|
||||
return nodeAtStartOf(found);
|
||||
}
|
||||
|
||||
function nodeAtStartOf(node) {
|
||||
while (node && node.firstChild) node = node.firstChild;
|
||||
return {node: node, offset: 0};
|
||||
}
|
||||
|
||||
var containing = range.parentElement();
|
||||
if (!isAncestor(document.body, containing)) return null;
|
||||
if (!containing.firstChild) return nodeAtStartOf(containing);
|
||||
|
||||
var working = range.duplicate();
|
||||
working.moveToElementText(containing);
|
||||
working.collapse(true);
|
||||
for (var cur = containing.firstChild; cur; cur = cur.nextSibling) {
|
||||
if (cur.nodeType == 3) {
|
||||
var size = cur.nodeValue.length;
|
||||
working.move("character", size);
|
||||
}
|
||||
else {
|
||||
working.moveToElementText(cur);
|
||||
working.collapse(false);
|
||||
}
|
||||
|
||||
var dir = range.compareEndPoints("StartToStart", working);
|
||||
if (dir == 0) return nodeAfter(cur);
|
||||
if (dir == 1) continue;
|
||||
if (cur.nodeType != 3) return nodeAtStartOf(cur);
|
||||
|
||||
working.setEndPoint("StartToEnd", range);
|
||||
return {node: cur, offset: size - working.text.length};
|
||||
}
|
||||
return nodeAfter(containing);
|
||||
}
|
||||
|
||||
select.markSelection = function() {
|
||||
currentSelection = null;
|
||||
var sel = document.selection;
|
||||
if (!sel) return;
|
||||
var start = selectionNode(true),
|
||||
end = selectionNode(false);
|
||||
if (!start || !end) return;
|
||||
currentSelection = {start: start, end: end, changed: false};
|
||||
};
|
||||
|
||||
select.selectMarked = function() {
|
||||
if (!currentSelection || !currentSelection.changed) return;
|
||||
|
||||
function makeRange(point) {
|
||||
var range = document.body.createTextRange(),
|
||||
node = point.node;
|
||||
if (!node) {
|
||||
range.moveToElementText(document.body);
|
||||
range.collapse(false);
|
||||
}
|
||||
else if (node.nodeType == 3) {
|
||||
range.moveToElementText(node.parentNode);
|
||||
var offset = point.offset;
|
||||
while (node.previousSibling) {
|
||||
node = node.previousSibling;
|
||||
offset += (node.innerText || "").length;
|
||||
}
|
||||
range.move("character", offset);
|
||||
}
|
||||
else {
|
||||
range.moveToElementText(node);
|
||||
range.collapse(true);
|
||||
}
|
||||
return range;
|
||||
}
|
||||
|
||||
var start = makeRange(currentSelection.start), end = makeRange(currentSelection.end);
|
||||
start.setEndPoint("StartToEnd", end);
|
||||
start.select();
|
||||
};
|
||||
|
||||
select.offsetInNode = function(node) {
|
||||
var range = selRange();
|
||||
if (!range) return 0;
|
||||
var range2 = range.duplicate();
|
||||
try {range2.moveToElementText(node);} catch(e){return 0;}
|
||||
range.setEndPoint("StartToStart", range2);
|
||||
return range.text.length;
|
||||
};
|
||||
|
||||
// Get the top-level node that one end of the cursor is inside or
|
||||
// after. Note that this returns false for 'no cursor', and null
|
||||
// for 'start of document'.
|
||||
select.selectionTopNode = function(container, start) {
|
||||
var range = selRange();
|
||||
if (!range) return false;
|
||||
var range2 = range.duplicate();
|
||||
range.collapse(start);
|
||||
var around = range.parentElement();
|
||||
if (around && isAncestor(container, around)) {
|
||||
// Only use this node if the selection is not at its start.
|
||||
range2.moveToElementText(around);
|
||||
if (range.compareEndPoints("StartToStart", range2) == 1)
|
||||
return topLevelNodeAt(around, container);
|
||||
}
|
||||
|
||||
// Move the start of a range to the start of a node,
|
||||
// compensating for the fact that you can't call
|
||||
// moveToElementText with text nodes.
|
||||
function moveToNodeStart(range, node) {
|
||||
if (node.nodeType == 3) {
|
||||
var count = 0, cur = node.previousSibling;
|
||||
while (cur && cur.nodeType == 3) {
|
||||
count += cur.nodeValue.length;
|
||||
cur = cur.previousSibling;
|
||||
}
|
||||
if (cur) {
|
||||
try{range.moveToElementText(cur);}
|
||||
catch(e){return false;}
|
||||
range.collapse(false);
|
||||
}
|
||||
else range.moveToElementText(node.parentNode);
|
||||
if (count) range.move("character", count);
|
||||
}
|
||||
else {
|
||||
try{range.moveToElementText(node);}
|
||||
catch(e){return false;}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Do a binary search through the container object, comparing
|
||||
// the start of each node to the selection
|
||||
var start = 0, end = container.childNodes.length - 1;
|
||||
while (start < end) {
|
||||
var middle = Math.ceil((end + start) / 2), node = container.childNodes[middle];
|
||||
if (!node) return false; // Don't ask. IE6 manages this sometimes.
|
||||
if (!moveToNodeStart(range2, node)) return false;
|
||||
if (range.compareEndPoints("StartToStart", range2) == 1)
|
||||
start = middle;
|
||||
else
|
||||
end = middle - 1;
|
||||
}
|
||||
|
||||
if (start == 0) {
|
||||
var test1 = selRange(), test2 = test1.duplicate();
|
||||
try {
|
||||
test2.moveToElementText(container);
|
||||
} catch(exception) {
|
||||
return null;
|
||||
}
|
||||
if (test1.compareEndPoints("StartToStart", test2) == 0)
|
||||
return null;
|
||||
}
|
||||
return container.childNodes[start] || null;
|
||||
};
|
||||
|
||||
// Place the cursor after this.start. This is only useful when
|
||||
// manually moving the cursor instead of restoring it to its old
|
||||
// position.
|
||||
select.focusAfterNode = function(node, container) {
|
||||
var range = document.body.createTextRange();
|
||||
range.moveToElementText(node || container);
|
||||
range.collapse(!node);
|
||||
range.select();
|
||||
};
|
||||
|
||||
select.somethingSelected = function() {
|
||||
var range = selRange();
|
||||
return range && (range.text != "");
|
||||
};
|
||||
|
||||
function insertAtCursor(html) {
|
||||
var range = selRange();
|
||||
if (range) {
|
||||
range.pasteHTML(html);
|
||||
range.collapse(false);
|
||||
range.select();
|
||||
}
|
||||
}
|
||||
|
||||
// Used to normalize the effect of the enter key, since browsers
|
||||
// do widely different things when pressing enter in designMode.
|
||||
select.insertNewlineAtCursor = function() {
|
||||
insertAtCursor("<br>");
|
||||
};
|
||||
|
||||
select.insertTabAtCursor = function() {
|
||||
insertAtCursor(fourSpaces);
|
||||
};
|
||||
|
||||
// Get the BR node at the start of the line on which the cursor
|
||||
// currently is, and the offset into the line. Returns null as
|
||||
// node if cursor is on first line.
|
||||
select.cursorPos = function(container, start) {
|
||||
var range = selRange();
|
||||
if (!range) return null;
|
||||
|
||||
var topNode = select.selectionTopNode(container, start);
|
||||
while (topNode && !isBR(topNode))
|
||||
topNode = topNode.previousSibling;
|
||||
|
||||
var range2 = range.duplicate();
|
||||
range.collapse(start);
|
||||
if (topNode) {
|
||||
range2.moveToElementText(topNode);
|
||||
range2.collapse(false);
|
||||
}
|
||||
else {
|
||||
// When nothing is selected, we can get all kinds of funky errors here.
|
||||
try { range2.moveToElementText(container); }
|
||||
catch (e) { return null; }
|
||||
range2.collapse(true);
|
||||
}
|
||||
range.setEndPoint("StartToStart", range2);
|
||||
|
||||
return {node: topNode, offset: range.text.length};
|
||||
};
|
||||
|
||||
select.setCursorPos = function(container, from, to) {
|
||||
function rangeAt(pos) {
|
||||
var range = document.body.createTextRange();
|
||||
if (!pos.node) {
|
||||
range.moveToElementText(container);
|
||||
range.collapse(true);
|
||||
}
|
||||
else {
|
||||
range.moveToElementText(pos.node);
|
||||
range.collapse(false);
|
||||
}
|
||||
range.move("character", pos.offset);
|
||||
return range;
|
||||
}
|
||||
|
||||
var range = rangeAt(from);
|
||||
if (to && to != from)
|
||||
range.setEndPoint("EndToEnd", rangeAt(to));
|
||||
range.select();
|
||||
}
|
||||
|
||||
// Some hacks for storing and re-storing the selection when the editor loses and regains focus.
|
||||
select.getBookmark = function (container) {
|
||||
var from = select.cursorPos(container, true), to = select.cursorPos(container, false);
|
||||
if (from && to) return {from: from, to: to};
|
||||
};
|
||||
|
||||
// Restore a stored selection.
|
||||
select.setBookmark = function(container, mark) {
|
||||
if (!mark) return;
|
||||
select.setCursorPos(container, mark.from, mark.to);
|
||||
};
|
||||
}
|
||||
// W3C model
|
||||
else {
|
||||
// Find the node right at the cursor, not one of its
|
||||
// ancestors with a suitable offset. This goes down the DOM tree
|
||||
// until a 'leaf' is reached (or is it *up* the DOM tree?).
|
||||
function innerNode(node, offset) {
|
||||
while (node.nodeType != 3 && !isBR(node)) {
|
||||
var newNode = node.childNodes[offset] || node.nextSibling;
|
||||
offset = 0;
|
||||
while (!newNode && node.parentNode) {
|
||||
node = node.parentNode;
|
||||
newNode = node.nextSibling;
|
||||
}
|
||||
node = newNode;
|
||||
if (!newNode) break;
|
||||
}
|
||||
return {node: node, offset: offset};
|
||||
}
|
||||
|
||||
// Store start and end nodes, and offsets within these, and refer
|
||||
// back to the selection object from those nodes, so that this
|
||||
// object can be updated when the nodes are replaced before the
|
||||
// selection is restored.
|
||||
select.markSelection = function () {
|
||||
var selection = window.getSelection();
|
||||
if (!selection || selection.rangeCount == 0)
|
||||
return (currentSelection = null);
|
||||
var range = selection.getRangeAt(0);
|
||||
|
||||
currentSelection = {
|
||||
start: innerNode(range.startContainer, range.startOffset),
|
||||
end: innerNode(range.endContainer, range.endOffset),
|
||||
changed: false
|
||||
};
|
||||
};
|
||||
|
||||
select.selectMarked = function () {
|
||||
var cs = currentSelection;
|
||||
// on webkit-based browsers, it is apparently possible that the
|
||||
// selection gets reset even when a node that is not one of the
|
||||
// endpoints get messed with. the most common situation where
|
||||
// this occurs is when a selection is deleted or overwitten. we
|
||||
// check for that here.
|
||||
function focusIssue() {
|
||||
if (cs.start.node == cs.end.node && cs.start.offset == cs.end.offset) {
|
||||
var selection = window.getSelection();
|
||||
if (!selection || selection.rangeCount == 0) return true;
|
||||
var range = selection.getRangeAt(0), point = innerNode(range.startContainer, range.startOffset);
|
||||
return cs.start.node != point.node || cs.start.offset != point.offset;
|
||||
}
|
||||
}
|
||||
if (!cs || !(cs.changed || (webkit && focusIssue()))) return;
|
||||
var range = document.createRange();
|
||||
|
||||
function setPoint(point, which) {
|
||||
if (point.node) {
|
||||
// Some magic to generalize the setting of the start and end
|
||||
// of a range.
|
||||
if (point.offset == 0)
|
||||
range["set" + which + "Before"](point.node);
|
||||
else
|
||||
range["set" + which](point.node, point.offset);
|
||||
}
|
||||
else {
|
||||
range.setStartAfter(document.body.lastChild || document.body);
|
||||
}
|
||||
}
|
||||
|
||||
setPoint(cs.end, "End");
|
||||
setPoint(cs.start, "Start");
|
||||
selectRange(range);
|
||||
};
|
||||
|
||||
// Helper for selecting a range object.
|
||||
function selectRange(range) {
|
||||
var selection = window.getSelection();
|
||||
if (!selection) return;
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
}
|
||||
function selectionRange() {
|
||||
var selection = window.getSelection();
|
||||
if (!selection || selection.rangeCount == 0)
|
||||
return false;
|
||||
else
|
||||
return selection.getRangeAt(0);
|
||||
}
|
||||
|
||||
// Finding the top-level node at the cursor in the W3C is, as you
|
||||
// can see, quite an involved process.
|
||||
select.selectionTopNode = function(container, start) {
|
||||
var range = selectionRange();
|
||||
if (!range) return false;
|
||||
|
||||
var node = start ? range.startContainer : range.endContainer;
|
||||
var offset = start ? range.startOffset : range.endOffset;
|
||||
// Work around (yet another) bug in Opera's selection model.
|
||||
if (window.opera && !start && range.endContainer == container && range.endOffset == range.startOffset + 1 &&
|
||||
container.childNodes[range.startOffset] && isBR(container.childNodes[range.startOffset]))
|
||||
offset--;
|
||||
|
||||
// For text nodes, we look at the node itself if the cursor is
|
||||
// inside, or at the node before it if the cursor is at the
|
||||
// start.
|
||||
if (node.nodeType == 3){
|
||||
if (offset > 0)
|
||||
return topLevelNodeAt(node, container);
|
||||
else
|
||||
return topLevelNodeBefore(node, container);
|
||||
}
|
||||
// Occasionally, browsers will return the HTML node as
|
||||
// selection. If the offset is 0, we take the start of the frame
|
||||
// ('after null'), otherwise, we take the last node.
|
||||
else if (node.nodeName.toUpperCase() == "HTML") {
|
||||
return (offset == 1 ? null : container.lastChild);
|
||||
}
|
||||
// If the given node is our 'container', we just look up the
|
||||
// correct node by using the offset.
|
||||
else if (node == container) {
|
||||
return (offset == 0) ? null : node.childNodes[offset - 1];
|
||||
}
|
||||
// In any other case, we have a regular node. If the cursor is
|
||||
// at the end of the node, we use the node itself, if it is at
|
||||
// the start, we use the node before it, and in any other
|
||||
// case, we look up the child before the cursor and use that.
|
||||
else {
|
||||
if (offset == node.childNodes.length)
|
||||
return topLevelNodeAt(node, container);
|
||||
else if (offset == 0)
|
||||
return topLevelNodeBefore(node, container);
|
||||
else
|
||||
return topLevelNodeAt(node.childNodes[offset - 1], container);
|
||||
}
|
||||
};
|
||||
|
||||
select.focusAfterNode = function(node, container) {
|
||||
var range = document.createRange();
|
||||
range.setStartBefore(container.firstChild || container);
|
||||
// In Opera, setting the end of a range at the end of a line
|
||||
// (before a BR) will cause the cursor to appear on the next
|
||||
// line, so we set the end inside of the start node when
|
||||
// possible.
|
||||
if (node && !node.firstChild)
|
||||
range.setEndAfter(node);
|
||||
else if (node)
|
||||
range.setEnd(node, node.childNodes.length);
|
||||
else
|
||||
range.setEndBefore(container.firstChild || container);
|
||||
range.collapse(false);
|
||||
selectRange(range);
|
||||
};
|
||||
|
||||
select.somethingSelected = function() {
|
||||
var range = selectionRange();
|
||||
return range && !range.collapsed;
|
||||
};
|
||||
|
||||
select.offsetInNode = function(node) {
|
||||
var range = selectionRange();
|
||||
if (!range) return 0;
|
||||
range = range.cloneRange();
|
||||
range.setStartBefore(node);
|
||||
return range.toString().length;
|
||||
};
|
||||
|
||||
select.insertNodeAtCursor = function(node) {
|
||||
var range = selectionRange();
|
||||
if (!range) return;
|
||||
|
||||
range.deleteContents();
|
||||
range.insertNode(node);
|
||||
webkitLastLineHack(document.body);
|
||||
|
||||
// work around weirdness where Opera will magically insert a new
|
||||
// BR node when a BR node inside a span is moved around. makes
|
||||
// sure the BR ends up outside of spans.
|
||||
if (window.opera && isBR(node) && isSpan(node.parentNode)) {
|
||||
var next = node.nextSibling, p = node.parentNode, outer = p.parentNode;
|
||||
outer.insertBefore(node, p.nextSibling);
|
||||
var textAfter = "";
|
||||
for (; next && next.nodeType == 3; next = next.nextSibling) {
|
||||
textAfter += next.nodeValue;
|
||||
removeElement(next);
|
||||
}
|
||||
outer.insertBefore(makePartSpan(textAfter, document), node.nextSibling);
|
||||
}
|
||||
range = document.createRange();
|
||||
range.selectNode(node);
|
||||
range.collapse(false);
|
||||
selectRange(range);
|
||||
}
|
||||
|
||||
select.insertNewlineAtCursor = function() {
|
||||
select.insertNodeAtCursor(document.createElement("BR"));
|
||||
};
|
||||
|
||||
select.insertTabAtCursor = function() {
|
||||
select.insertNodeAtCursor(document.createTextNode(fourSpaces));
|
||||
};
|
||||
|
||||
select.cursorPos = function(container, start) {
|
||||
var range = selectionRange();
|
||||
if (!range) return;
|
||||
|
||||
var topNode = select.selectionTopNode(container, start);
|
||||
while (topNode && !isBR(topNode))
|
||||
topNode = topNode.previousSibling;
|
||||
|
||||
range = range.cloneRange();
|
||||
range.collapse(start);
|
||||
if (topNode)
|
||||
range.setStartAfter(topNode);
|
||||
else
|
||||
range.setStartBefore(container);
|
||||
|
||||
var text = range.toString();
|
||||
return {node: topNode, offset: text.length};
|
||||
};
|
||||
|
||||
select.setCursorPos = function(container, from, to) {
|
||||
var range = document.createRange();
|
||||
|
||||
function setPoint(node, offset, side) {
|
||||
if (offset == 0 && node && !node.nextSibling) {
|
||||
range["set" + side + "After"](node);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!node)
|
||||
node = container.firstChild;
|
||||
else
|
||||
node = node.nextSibling;
|
||||
|
||||
if (!node) return;
|
||||
|
||||
if (offset == 0) {
|
||||
range["set" + side + "Before"](node);
|
||||
return true;
|
||||
}
|
||||
|
||||
var backlog = []
|
||||
function decompose(node) {
|
||||
if (node.nodeType == 3)
|
||||
backlog.push(node);
|
||||
else
|
||||
forEach(node.childNodes, decompose);
|
||||
}
|
||||
while (true) {
|
||||
while (node && !backlog.length) {
|
||||
decompose(node);
|
||||
node = node.nextSibling;
|
||||
}
|
||||
var cur = backlog.shift();
|
||||
if (!cur) return false;
|
||||
|
||||
var length = cur.nodeValue.length;
|
||||
if (length >= offset) {
|
||||
range["set" + side](cur, offset);
|
||||
return true;
|
||||
}
|
||||
offset -= length;
|
||||
}
|
||||
}
|
||||
|
||||
to = to || from;
|
||||
if (setPoint(to.node, to.offset, "End") && setPoint(from.node, from.offset, "Start"))
|
||||
selectRange(range);
|
||||
};
|
||||
}
|
||||
})();
|
||||
159
includes/js/codemirror/stringstream.js
Normal file
@@ -0,0 +1,159 @@
|
||||
/* String streams are the things fed to parsers (which can feed them
|
||||
* to a tokenizer if they want). They provide peek and next methods
|
||||
* for looking at the current character (next 'consumes' this
|
||||
* character, peek does not), and a get method for retrieving all the
|
||||
* text that was consumed since the last time get was called.
|
||||
*
|
||||
* An easy mistake to make is to let a StopIteration exception finish
|
||||
* the token stream while there are still characters pending in the
|
||||
* string stream (hitting the end of the buffer while parsing a
|
||||
* token). To make it easier to detect such errors, the stringstreams
|
||||
* throw an exception when this happens.
|
||||
*/
|
||||
|
||||
// Make a stringstream stream out of an iterator that returns strings.
|
||||
// This is applied to the result of traverseDOM (see codemirror.js),
|
||||
// and the resulting stream is fed to the parser.
|
||||
var stringStream = function(source){
|
||||
// String that's currently being iterated over.
|
||||
var current = "";
|
||||
// Position in that string.
|
||||
var pos = 0;
|
||||
// Accumulator for strings that have been iterated over but not
|
||||
// get()-ed yet.
|
||||
var accum = "";
|
||||
// Make sure there are more characters ready, or throw
|
||||
// StopIteration.
|
||||
function ensureChars() {
|
||||
while (pos == current.length) {
|
||||
accum += current;
|
||||
current = ""; // In case source.next() throws
|
||||
pos = 0;
|
||||
try {current = source.next();}
|
||||
catch (e) {
|
||||
if (e != StopIteration) throw e;
|
||||
else return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return {
|
||||
// peek: -> character
|
||||
// Return the next character in the stream.
|
||||
peek: function() {
|
||||
if (!ensureChars()) return null;
|
||||
return current.charAt(pos);
|
||||
},
|
||||
// next: -> character
|
||||
// Get the next character, throw StopIteration if at end, check
|
||||
// for unused content.
|
||||
next: function() {
|
||||
if (!ensureChars()) {
|
||||
if (accum.length > 0)
|
||||
throw "End of stringstream reached without emptying buffer ('" + accum + "').";
|
||||
else
|
||||
throw StopIteration;
|
||||
}
|
||||
return current.charAt(pos++);
|
||||
},
|
||||
// get(): -> string
|
||||
// Return the characters iterated over since the last call to
|
||||
// .get().
|
||||
get: function() {
|
||||
var temp = accum;
|
||||
accum = "";
|
||||
if (pos > 0){
|
||||
temp += current.slice(0, pos);
|
||||
current = current.slice(pos);
|
||||
pos = 0;
|
||||
}
|
||||
return temp;
|
||||
},
|
||||
// Push a string back into the stream.
|
||||
push: function(str) {
|
||||
current = current.slice(0, pos) + str + current.slice(pos);
|
||||
},
|
||||
lookAhead: function(str, consume, skipSpaces, caseInsensitive) {
|
||||
function cased(str) {return caseInsensitive ? str.toLowerCase() : str;}
|
||||
str = cased(str);
|
||||
var found = false;
|
||||
|
||||
var _accum = accum, _pos = pos;
|
||||
if (skipSpaces) this.nextWhileMatches(/[\s\u00a0]/);
|
||||
|
||||
while (true) {
|
||||
var end = pos + str.length, left = current.length - pos;
|
||||
if (end <= current.length) {
|
||||
found = str == cased(current.slice(pos, end));
|
||||
pos = end;
|
||||
break;
|
||||
}
|
||||
else if (str.slice(0, left) == cased(current.slice(pos))) {
|
||||
accum += current; current = "";
|
||||
try {current = source.next();}
|
||||
catch (e) {if (e != StopIteration) throw e; break;}
|
||||
pos = 0;
|
||||
str = str.slice(left);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(found && consume)) {
|
||||
current = accum.slice(_accum.length) + current;
|
||||
pos = _pos;
|
||||
accum = _accum;
|
||||
}
|
||||
|
||||
return found;
|
||||
},
|
||||
// Wont't match past end of line.
|
||||
lookAheadRegex: function(regex, consume) {
|
||||
if (regex.source.charAt(0) != "^")
|
||||
throw new Error("Regexps passed to lookAheadRegex must start with ^");
|
||||
|
||||
// Fetch the rest of the line
|
||||
while (current.indexOf("\n", pos) == -1) {
|
||||
try {current += source.next();}
|
||||
catch (e) {if (e != StopIteration) throw e; break;}
|
||||
}
|
||||
var matched = current.slice(pos).match(regex);
|
||||
if (matched && consume) pos += matched[0].length;
|
||||
return matched;
|
||||
},
|
||||
|
||||
// Utils built on top of the above
|
||||
// more: -> boolean
|
||||
// Produce true if the stream isn't empty.
|
||||
more: function() {
|
||||
return this.peek() !== null;
|
||||
},
|
||||
applies: function(test) {
|
||||
var next = this.peek();
|
||||
return (next !== null && test(next));
|
||||
},
|
||||
nextWhile: function(test) {
|
||||
var next;
|
||||
while ((next = this.peek()) !== null && test(next))
|
||||
this.next();
|
||||
},
|
||||
matches: function(re) {
|
||||
var next = this.peek();
|
||||
return (next !== null && re.test(next));
|
||||
},
|
||||
nextWhileMatches: function(re) {
|
||||
var next;
|
||||
while ((next = this.peek()) !== null && re.test(next))
|
||||
this.next();
|
||||
},
|
||||
equals: function(ch) {
|
||||
return ch === this.peek();
|
||||
},
|
||||
endOfLine: function() {
|
||||
var next = this.peek();
|
||||
return next == null || next == "\n";
|
||||
}
|
||||
};
|
||||
};
|
||||
57
includes/js/codemirror/tokenize.js
Normal file
@@ -0,0 +1,57 @@
|
||||
// A framework for simple tokenizers. Takes care of newlines and
|
||||
// white-space, and of getting the text from the source stream into
|
||||
// the token object. A state is a function of two arguments -- a
|
||||
// string stream and a setState function. The second can be used to
|
||||
// change the tokenizer's state, and can be ignored for stateless
|
||||
// tokenizers. This function should advance the stream over a token
|
||||
// and return a string or object containing information about the next
|
||||
// token, or null to pass and have the (new) state be called to finish
|
||||
// the token. When a string is given, it is wrapped in a {style, type}
|
||||
// object. In the resulting object, the characters consumed are stored
|
||||
// under the content property. Any whitespace following them is also
|
||||
// automatically consumed, and added to the value property. (Thus,
|
||||
// content is the actual meaningful part of the token, while value
|
||||
// contains all the text it spans.)
|
||||
|
||||
function tokenizer(source, state) {
|
||||
// Newlines are always a separate token.
|
||||
function isWhiteSpace(ch) {
|
||||
// The messy regexp is because IE's regexp matcher is of the
|
||||
// opinion that non-breaking spaces are no whitespace.
|
||||
return ch != "\n" && /^[\s\u00a0]*$/.test(ch);
|
||||
}
|
||||
|
||||
var tokenizer = {
|
||||
state: state,
|
||||
|
||||
take: function(type) {
|
||||
if (typeof(type) == "string")
|
||||
type = {style: type, type: type};
|
||||
|
||||
type.content = (type.content || "") + source.get();
|
||||
if (!/\n$/.test(type.content))
|
||||
source.nextWhile(isWhiteSpace);
|
||||
type.value = type.content + source.get();
|
||||
return type;
|
||||
},
|
||||
|
||||
next: function () {
|
||||
if (!source.more()) throw StopIteration;
|
||||
|
||||
var type;
|
||||
if (source.equals("\n")) {
|
||||
source.next();
|
||||
return this.take("whitespace");
|
||||
}
|
||||
|
||||
if (source.applies(isWhiteSpace))
|
||||
type = "whitespace";
|
||||
else
|
||||
while (!type)
|
||||
type = this.state(source, function(s) {tokenizer.state = s;});
|
||||
|
||||
return this.take(type);
|
||||
}
|
||||
};
|
||||
return tokenizer;
|
||||
}
|
||||
174
includes/js/codemirror/tokenizejavascript.js
Normal file
@@ -0,0 +1,174 @@
|
||||
/* Tokenizer for JavaScript code */
|
||||
|
||||
var tokenizeJavaScript = (function() {
|
||||
// Advance the stream until the given character (not preceded by a
|
||||
// backslash) is encountered, or the end of the line is reached.
|
||||
function nextUntilUnescaped(source, end) {
|
||||
var escaped = false;
|
||||
while (!source.endOfLine()) {
|
||||
var next = source.next();
|
||||
if (next == end && !escaped)
|
||||
return false;
|
||||
escaped = !escaped && next == "\\";
|
||||
}
|
||||
return escaped;
|
||||
}
|
||||
|
||||
// A map of JavaScript's keywords. The a/b/c keyword distinction is
|
||||
// very rough, but it gives the parser enough information to parse
|
||||
// correct code correctly (we don't care that much how we parse
|
||||
// incorrect code). The style information included in these objects
|
||||
// is used by the highlighter to pick the correct CSS style for a
|
||||
// token.
|
||||
var keywords = function(){
|
||||
function result(type, style){
|
||||
return {type: type, style: "js-" + style};
|
||||
}
|
||||
// keywords that take a parenthised expression, and then a
|
||||
// statement (if)
|
||||
var keywordA = result("keyword a", "keyword");
|
||||
// keywords that take just a statement (else)
|
||||
var keywordB = result("keyword b", "keyword");
|
||||
// keywords that optionally take an expression, and form a
|
||||
// statement (return)
|
||||
var keywordC = result("keyword c", "keyword");
|
||||
var operator = result("operator", "keyword");
|
||||
var atom = result("atom", "atom");
|
||||
return {
|
||||
"if": keywordA, "while": keywordA, "with": keywordA,
|
||||
"else": keywordB, "do": keywordB, "try": keywordB, "finally": keywordB,
|
||||
"return": keywordC, "break": keywordC, "continue": keywordC, "new": keywordC, "delete": keywordC, "throw": keywordC,
|
||||
"in": operator, "typeof": operator, "instanceof": operator,
|
||||
"var": result("var", "keyword"), "function": result("function", "keyword"), "catch": result("catch", "keyword"),
|
||||
"for": result("for", "keyword"), "switch": result("switch", "keyword"),
|
||||
"case": result("case", "keyword"), "default": result("default", "keyword"),
|
||||
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom
|
||||
};
|
||||
}();
|
||||
|
||||
// Some helper regexps
|
||||
var isOperatorChar = /[+\-*&%=<>!?|]/;
|
||||
var isHexDigit = /[0-9A-Fa-f]/;
|
||||
var isWordChar = /[\w\$_]/;
|
||||
|
||||
// Wrapper around jsToken that helps maintain parser state (whether
|
||||
// we are inside of a multi-line comment and whether the next token
|
||||
// could be a regular expression).
|
||||
function jsTokenState(inside, regexp) {
|
||||
return function(source, setState) {
|
||||
var newInside = inside;
|
||||
var type = jsToken(inside, regexp, source, function(c) {newInside = c;});
|
||||
var newRegexp = type.type == "operator" || type.type == "keyword c" || type.type.match(/^[\[{}\(,;:]$/);
|
||||
if (newRegexp != regexp || newInside != inside)
|
||||
setState(jsTokenState(newInside, newRegexp));
|
||||
return type;
|
||||
};
|
||||
}
|
||||
|
||||
// The token reader, intended to be used by the tokenizer from
|
||||
// tokenize.js (through jsTokenState). Advances the source stream
|
||||
// over a token, and returns an object containing the type and style
|
||||
// of that token.
|
||||
function jsToken(inside, regexp, source, setInside) {
|
||||
function readHexNumber(){
|
||||
source.next(); // skip the 'x'
|
||||
source.nextWhileMatches(isHexDigit);
|
||||
return {type: "number", style: "js-atom"};
|
||||
}
|
||||
|
||||
function readNumber() {
|
||||
source.nextWhileMatches(/[0-9]/);
|
||||
if (source.equals(".")){
|
||||
source.next();
|
||||
source.nextWhileMatches(/[0-9]/);
|
||||
}
|
||||
if (source.equals("e") || source.equals("E")){
|
||||
source.next();
|
||||
if (source.equals("-"))
|
||||
source.next();
|
||||
source.nextWhileMatches(/[0-9]/);
|
||||
}
|
||||
return {type: "number", style: "js-atom"};
|
||||
}
|
||||
// Read a word, look it up in keywords. If not found, it is a
|
||||
// variable, otherwise it is a keyword of the type found.
|
||||
function readWord() {
|
||||
source.nextWhileMatches(isWordChar);
|
||||
var word = source.get();
|
||||
var known = keywords.hasOwnProperty(word) && keywords.propertyIsEnumerable(word) && keywords[word];
|
||||
return known ? {type: known.type, style: known.style, content: word} :
|
||||
{type: "variable", style: "js-variable", content: word};
|
||||
}
|
||||
function readRegexp() {
|
||||
nextUntilUnescaped(source, "/");
|
||||
source.nextWhileMatches(/[gimy]/); // 'y' is "sticky" option in Mozilla
|
||||
return {type: "regexp", style: "js-string"};
|
||||
}
|
||||
// Mutli-line comments are tricky. We want to return the newlines
|
||||
// embedded in them as regular newline tokens, and then continue
|
||||
// returning a comment token for every line of the comment. So
|
||||
// some state has to be saved (inside) to indicate whether we are
|
||||
// inside a /* */ sequence.
|
||||
function readMultilineComment(start){
|
||||
var newInside = "/*";
|
||||
var maybeEnd = (start == "*");
|
||||
while (true) {
|
||||
if (source.endOfLine())
|
||||
break;
|
||||
var next = source.next();
|
||||
if (next == "/" && maybeEnd){
|
||||
newInside = null;
|
||||
break;
|
||||
}
|
||||
maybeEnd = (next == "*");
|
||||
}
|
||||
setInside(newInside);
|
||||
return {type: "comment", style: "js-comment"};
|
||||
}
|
||||
function readOperator() {
|
||||
source.nextWhileMatches(isOperatorChar);
|
||||
return {type: "operator", style: "js-operator"};
|
||||
}
|
||||
function readString(quote) {
|
||||
var endBackSlash = nextUntilUnescaped(source, quote);
|
||||
setInside(endBackSlash ? quote : null);
|
||||
return {type: "string", style: "js-string"};
|
||||
}
|
||||
|
||||
// Fetch the next token. Dispatches on first character in the
|
||||
// stream, or first two characters when the first is a slash.
|
||||
if (inside == "\"" || inside == "'")
|
||||
return readString(inside);
|
||||
var ch = source.next();
|
||||
if (inside == "/*")
|
||||
return readMultilineComment(ch);
|
||||
else if (ch == "\"" || ch == "'")
|
||||
return readString(ch);
|
||||
// with punctuation, the type of the token is the symbol itself
|
||||
else if (/[\[\]{}\(\),;\:\.]/.test(ch))
|
||||
return {type: ch, style: "js-punctuation"};
|
||||
else if (ch == "0" && (source.equals("x") || source.equals("X")))
|
||||
return readHexNumber();
|
||||
else if (/[0-9]/.test(ch))
|
||||
return readNumber();
|
||||
else if (ch == "/"){
|
||||
if (source.equals("*"))
|
||||
{ source.next(); return readMultilineComment(ch); }
|
||||
else if (source.equals("/"))
|
||||
{ nextUntilUnescaped(source, null); return {type: "comment", style: "js-comment"};}
|
||||
else if (regexp)
|
||||
return readRegexp();
|
||||
else
|
||||
return readOperator();
|
||||
}
|
||||
else if (isOperatorChar.test(ch))
|
||||
return readOperator();
|
||||
else
|
||||
return readWord();
|
||||
}
|
||||
|
||||
// The external interface to the tokenizer.
|
||||
return function(source, startState) {
|
||||
return tokenizer(source, startState || jsTokenState(false, true));
|
||||
};
|
||||
})();
|
||||
413
includes/js/codemirror/undo.js
Normal file
@@ -0,0 +1,413 @@
|
||||
/**
|
||||
* Storage and control for undo information within a CodeMirror
|
||||
* editor. 'Why on earth is such a complicated mess required for
|
||||
* that?', I hear you ask. The goal, in implementing this, was to make
|
||||
* the complexity of storing and reverting undo information depend
|
||||
* only on the size of the edited or restored content, not on the size
|
||||
* of the whole document. This makes it necessary to use a kind of
|
||||
* 'diff' system, which, when applied to a DOM tree, causes some
|
||||
* complexity and hackery.
|
||||
*
|
||||
* In short, the editor 'touches' BR elements as it parses them, and
|
||||
* the UndoHistory stores these. When nothing is touched in commitDelay
|
||||
* milliseconds, the changes are committed: It goes over all touched
|
||||
* nodes, throws out the ones that did not change since last commit or
|
||||
* are no longer in the document, and assembles the rest into zero or
|
||||
* more 'chains' -- arrays of adjacent lines. Links back to these
|
||||
* chains are added to the BR nodes, while the chain that previously
|
||||
* spanned these nodes is added to the undo history. Undoing a change
|
||||
* means taking such a chain off the undo history, restoring its
|
||||
* content (text is saved per line) and linking it back into the
|
||||
* document.
|
||||
*/
|
||||
|
||||
// A history object needs to know about the DOM container holding the
|
||||
// document, the maximum amount of undo levels it should store, the
|
||||
// delay (of no input) after which it commits a set of changes, and,
|
||||
// unfortunately, the 'parent' window -- a window that is not in
|
||||
// designMode, and on which setTimeout works in every browser.
|
||||
function UndoHistory(container, maxDepth, commitDelay, editor) {
|
||||
this.container = container;
|
||||
this.maxDepth = maxDepth; this.commitDelay = commitDelay;
|
||||
this.editor = editor;
|
||||
// This line object represents the initial, empty editor.
|
||||
var initial = {text: "", from: null, to: null};
|
||||
// As the borders between lines are represented by BR elements, the
|
||||
// start of the first line and the end of the last one are
|
||||
// represented by null. Since you can not store any properties
|
||||
// (links to line objects) in null, these properties are used in
|
||||
// those cases.
|
||||
this.first = initial; this.last = initial;
|
||||
// Similarly, a 'historyTouched' property is added to the BR in
|
||||
// front of lines that have already been touched, and 'firstTouched'
|
||||
// is used for the first line.
|
||||
this.firstTouched = false;
|
||||
// History is the set of committed changes, touched is the set of
|
||||
// nodes touched since the last commit.
|
||||
this.history = []; this.redoHistory = []; this.touched = []; this.lostundo = 0;
|
||||
}
|
||||
|
||||
UndoHistory.prototype = {
|
||||
// Schedule a commit (if no other touches come in for commitDelay
|
||||
// milliseconds).
|
||||
scheduleCommit: function() {
|
||||
var self = this;
|
||||
parent.clearTimeout(this.commitTimeout);
|
||||
this.commitTimeout = parent.setTimeout(function(){self.tryCommit();}, this.commitDelay);
|
||||
},
|
||||
|
||||
// Mark a node as touched. Null is a valid argument.
|
||||
touch: function(node) {
|
||||
this.setTouched(node);
|
||||
this.scheduleCommit();
|
||||
},
|
||||
|
||||
// Undo the last change.
|
||||
undo: function() {
|
||||
// Make sure pending changes have been committed.
|
||||
this.commit();
|
||||
|
||||
if (this.history.length) {
|
||||
// Take the top diff from the history, apply it, and store its
|
||||
// shadow in the redo history.
|
||||
var item = this.history.pop();
|
||||
this.redoHistory.push(this.updateTo(item, "applyChain"));
|
||||
this.notifyEnvironment();
|
||||
return this.chainNode(item);
|
||||
}
|
||||
},
|
||||
|
||||
// Redo the last undone change.
|
||||
redo: function() {
|
||||
this.commit();
|
||||
if (this.redoHistory.length) {
|
||||
// The inverse of undo, basically.
|
||||
var item = this.redoHistory.pop();
|
||||
this.addUndoLevel(this.updateTo(item, "applyChain"));
|
||||
this.notifyEnvironment();
|
||||
return this.chainNode(item);
|
||||
}
|
||||
},
|
||||
|
||||
clear: function() {
|
||||
this.history = [];
|
||||
this.redoHistory = [];
|
||||
this.lostundo = 0;
|
||||
},
|
||||
|
||||
// Ask for the size of the un/redo histories.
|
||||
historySize: function() {
|
||||
return {undo: this.history.length, redo: this.redoHistory.length, lostundo: this.lostundo};
|
||||
},
|
||||
|
||||
// Push a changeset into the document.
|
||||
push: function(from, to, lines) {
|
||||
var chain = [];
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
var end = (i == lines.length - 1) ? to : document.createElement("br");
|
||||
chain.push({from: from, to: end, text: cleanText(lines[i])});
|
||||
from = end;
|
||||
}
|
||||
this.pushChains([chain], from == null && to == null);
|
||||
this.notifyEnvironment();
|
||||
},
|
||||
|
||||
pushChains: function(chains, doNotHighlight) {
|
||||
this.commit(doNotHighlight);
|
||||
this.addUndoLevel(this.updateTo(chains, "applyChain"));
|
||||
this.redoHistory = [];
|
||||
},
|
||||
|
||||
// Retrieve a DOM node from a chain (for scrolling to it after undo/redo).
|
||||
chainNode: function(chains) {
|
||||
for (var i = 0; i < chains.length; i++) {
|
||||
var start = chains[i][0], node = start && (start.from || start.to);
|
||||
if (node) return node;
|
||||
}
|
||||
},
|
||||
|
||||
// Clear the undo history, make the current document the start
|
||||
// position.
|
||||
reset: function() {
|
||||
this.history = []; this.redoHistory = []; this.lostundo = 0;
|
||||
},
|
||||
|
||||
textAfter: function(br) {
|
||||
return this.after(br).text;
|
||||
},
|
||||
|
||||
nodeAfter: function(br) {
|
||||
return this.after(br).to;
|
||||
},
|
||||
|
||||
nodeBefore: function(br) {
|
||||
return this.before(br).from;
|
||||
},
|
||||
|
||||
// Commit unless there are pending dirty nodes.
|
||||
tryCommit: function() {
|
||||
if (!window || !window.parent || !window.UndoHistory) return; // Stop when frame has been unloaded
|
||||
if (this.editor.highlightDirty()) this.commit(true);
|
||||
else this.scheduleCommit();
|
||||
},
|
||||
|
||||
// Check whether the touched nodes hold any changes, if so, commit
|
||||
// them.
|
||||
commit: function(doNotHighlight) {
|
||||
parent.clearTimeout(this.commitTimeout);
|
||||
// Make sure there are no pending dirty nodes.
|
||||
if (!doNotHighlight) this.editor.highlightDirty(true);
|
||||
// Build set of chains.
|
||||
var chains = this.touchedChains(), self = this;
|
||||
|
||||
if (chains.length) {
|
||||
this.addUndoLevel(this.updateTo(chains, "linkChain"));
|
||||
this.redoHistory = [];
|
||||
this.notifyEnvironment();
|
||||
}
|
||||
},
|
||||
|
||||
// [ end of public interface ]
|
||||
|
||||
// Update the document with a given set of chains, return its
|
||||
// shadow. updateFunc should be "applyChain" or "linkChain". In the
|
||||
// second case, the chains are taken to correspond the the current
|
||||
// document, and only the state of the line data is updated. In the
|
||||
// first case, the content of the chains is also pushed iinto the
|
||||
// document.
|
||||
updateTo: function(chains, updateFunc) {
|
||||
var shadows = [], dirty = [];
|
||||
for (var i = 0; i < chains.length; i++) {
|
||||
shadows.push(this.shadowChain(chains[i]));
|
||||
dirty.push(this[updateFunc](chains[i]));
|
||||
}
|
||||
if (updateFunc == "applyChain")
|
||||
this.notifyDirty(dirty);
|
||||
return shadows;
|
||||
},
|
||||
|
||||
// Notify the editor that some nodes have changed.
|
||||
notifyDirty: function(nodes) {
|
||||
forEach(nodes, method(this.editor, "addDirtyNode"))
|
||||
this.editor.scheduleHighlight();
|
||||
},
|
||||
|
||||
notifyEnvironment: function() {
|
||||
if (this.onChange) this.onChange(this.editor);
|
||||
// Used by the line-wrapping line-numbering code.
|
||||
if (window.frameElement && window.frameElement.CodeMirror.updateNumbers)
|
||||
window.frameElement.CodeMirror.updateNumbers();
|
||||
},
|
||||
|
||||
// Link a chain into the DOM nodes (or the first/last links for null
|
||||
// nodes).
|
||||
linkChain: function(chain) {
|
||||
for (var i = 0; i < chain.length; i++) {
|
||||
var line = chain[i];
|
||||
if (line.from) line.from.historyAfter = line;
|
||||
else this.first = line;
|
||||
if (line.to) line.to.historyBefore = line;
|
||||
else this.last = line;
|
||||
}
|
||||
},
|
||||
|
||||
// Get the line object after/before a given node.
|
||||
after: function(node) {
|
||||
return node ? node.historyAfter : this.first;
|
||||
},
|
||||
before: function(node) {
|
||||
return node ? node.historyBefore : this.last;
|
||||
},
|
||||
|
||||
// Mark a node as touched if it has not already been marked.
|
||||
setTouched: function(node) {
|
||||
if (node) {
|
||||
if (!node.historyTouched) {
|
||||
this.touched.push(node);
|
||||
node.historyTouched = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.firstTouched = true;
|
||||
}
|
||||
},
|
||||
|
||||
// Store a new set of undo info, throw away info if there is more of
|
||||
// it than allowed.
|
||||
addUndoLevel: function(diffs) {
|
||||
this.history.push(diffs);
|
||||
if (this.history.length > this.maxDepth) {
|
||||
this.history.shift();
|
||||
lostundo += 1;
|
||||
}
|
||||
},
|
||||
|
||||
// Build chains from a set of touched nodes.
|
||||
touchedChains: function() {
|
||||
var self = this;
|
||||
|
||||
// The temp system is a crummy hack to speed up determining
|
||||
// whether a (currently touched) node has a line object associated
|
||||
// with it. nullTemp is used to store the object for the first
|
||||
// line, other nodes get it stored in their historyTemp property.
|
||||
var nullTemp = null;
|
||||
function temp(node) {return node ? node.historyTemp : nullTemp;}
|
||||
function setTemp(node, line) {
|
||||
if (node) node.historyTemp = line;
|
||||
else nullTemp = line;
|
||||
}
|
||||
|
||||
function buildLine(node) {
|
||||
var text = [];
|
||||
for (var cur = node ? node.nextSibling : self.container.firstChild;
|
||||
cur && (!isBR(cur) || cur.hackBR); cur = cur.nextSibling)
|
||||
if (!cur.hackBR && cur.currentText) text.push(cur.currentText);
|
||||
return {from: node, to: cur, text: cleanText(text.join(""))};
|
||||
}
|
||||
|
||||
// Filter out unchanged lines and nodes that are no longer in the
|
||||
// document. Build up line objects for remaining nodes.
|
||||
var lines = [];
|
||||
if (self.firstTouched) self.touched.push(null);
|
||||
forEach(self.touched, function(node) {
|
||||
if (node && (node.parentNode != self.container || node.hackBR)) return;
|
||||
|
||||
if (node) node.historyTouched = false;
|
||||
else self.firstTouched = false;
|
||||
|
||||
var line = buildLine(node), shadow = self.after(node);
|
||||
if (!shadow || shadow.text != line.text || shadow.to != line.to) {
|
||||
lines.push(line);
|
||||
setTemp(node, line);
|
||||
}
|
||||
});
|
||||
|
||||
// Get the BR element after/before the given node.
|
||||
function nextBR(node, dir) {
|
||||
var link = dir + "Sibling", search = node[link];
|
||||
while (search && !isBR(search))
|
||||
search = search[link];
|
||||
return search;
|
||||
}
|
||||
|
||||
// Assemble line objects into chains by scanning the DOM tree
|
||||
// around them.
|
||||
var chains = []; self.touched = [];
|
||||
forEach(lines, function(line) {
|
||||
// Note that this makes the loop skip line objects that have
|
||||
// been pulled into chains by lines before them.
|
||||
if (!temp(line.from)) return;
|
||||
|
||||
var chain = [], curNode = line.from, safe = true;
|
||||
// Put any line objects (referred to by temp info) before this
|
||||
// one on the front of the array.
|
||||
while (true) {
|
||||
var curLine = temp(curNode);
|
||||
if (!curLine) {
|
||||
if (safe) break;
|
||||
else curLine = buildLine(curNode);
|
||||
}
|
||||
chain.unshift(curLine);
|
||||
setTemp(curNode, null);
|
||||
if (!curNode) break;
|
||||
safe = self.after(curNode);
|
||||
curNode = nextBR(curNode, "previous");
|
||||
}
|
||||
curNode = line.to; safe = self.before(line.from);
|
||||
// Add lines after this one at end of array.
|
||||
while (true) {
|
||||
if (!curNode) break;
|
||||
var curLine = temp(curNode);
|
||||
if (!curLine) {
|
||||
if (safe) break;
|
||||
else curLine = buildLine(curNode);
|
||||
}
|
||||
chain.push(curLine);
|
||||
setTemp(curNode, null);
|
||||
safe = self.before(curNode);
|
||||
curNode = nextBR(curNode, "next");
|
||||
}
|
||||
chains.push(chain);
|
||||
});
|
||||
|
||||
return chains;
|
||||
},
|
||||
|
||||
// Find the 'shadow' of a given chain by following the links in the
|
||||
// DOM nodes at its start and end.
|
||||
shadowChain: function(chain) {
|
||||
var shadows = [], next = this.after(chain[0].from), end = chain[chain.length - 1].to;
|
||||
while (true) {
|
||||
shadows.push(next);
|
||||
var nextNode = next.to;
|
||||
if (!nextNode || nextNode == end)
|
||||
break;
|
||||
else
|
||||
next = nextNode.historyAfter || this.before(end);
|
||||
// (The this.before(end) is a hack -- FF sometimes removes
|
||||
// properties from BR nodes, in which case the best we can hope
|
||||
// for is to not break.)
|
||||
}
|
||||
return shadows;
|
||||
},
|
||||
|
||||
// Update the DOM tree to contain the lines specified in a given
|
||||
// chain, link this chain into the DOM nodes.
|
||||
applyChain: function(chain) {
|
||||
// Some attempt is made to prevent the cursor from jumping
|
||||
// randomly when an undo or redo happens. It still behaves a bit
|
||||
// strange sometimes.
|
||||
var cursor = select.cursorPos(this.container, false), self = this;
|
||||
|
||||
// Remove all nodes in the DOM tree between from and to (null for
|
||||
// start/end of container).
|
||||
function removeRange(from, to) {
|
||||
var pos = from ? from.nextSibling : self.container.firstChild;
|
||||
while (pos != to) {
|
||||
var temp = pos.nextSibling;
|
||||
removeElement(pos);
|
||||
pos = temp;
|
||||
}
|
||||
}
|
||||
|
||||
var start = chain[0].from, end = chain[chain.length - 1].to;
|
||||
// Clear the space where this change has to be made.
|
||||
removeRange(start, end);
|
||||
|
||||
// Insert the content specified by the chain into the DOM tree.
|
||||
for (var i = 0; i < chain.length; i++) {
|
||||
var line = chain[i];
|
||||
// The start and end of the space are already correct, but BR
|
||||
// tags inside it have to be put back.
|
||||
if (i > 0)
|
||||
self.container.insertBefore(line.from, end);
|
||||
|
||||
// Add the text.
|
||||
var node = makePartSpan(fixSpaces(line.text));
|
||||
self.container.insertBefore(node, end);
|
||||
// See if the cursor was on this line. Put it back, adjusting
|
||||
// for changed line length, if it was.
|
||||
if (cursor && cursor.node == line.from) {
|
||||
var cursordiff = 0;
|
||||
var prev = this.after(line.from);
|
||||
if (prev && i == chain.length - 1) {
|
||||
// Only adjust if the cursor is after the unchanged part of
|
||||
// the line.
|
||||
for (var match = 0; match < cursor.offset &&
|
||||
line.text.charAt(match) == prev.text.charAt(match); match++){}
|
||||
if (cursor.offset > match)
|
||||
cursordiff = line.text.length - prev.text.length;
|
||||
}
|
||||
select.setCursorPos(this.container, {node: line.from, offset: Math.max(0, cursor.offset + cursordiff)});
|
||||
}
|
||||
// Cursor was in removed line, this is last new line.
|
||||
else if (cursor && (i == chain.length - 1) && cursor.node && cursor.node.parentNode != this.container) {
|
||||
select.setCursorPos(this.container, {node: line.from, offset: line.text.length});
|
||||
}
|
||||
}
|
||||
|
||||
// Anchor the chain in the DOM tree.
|
||||
this.linkChain(chain);
|
||||
return start;
|
||||
}
|
||||
};
|
||||
44
includes/js/codemirror/unittests.js
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Test Harness for CodeMirror
|
||||
* JS-unit compatible tests here. The two available assertions are
|
||||
* assertEquals (strict equality) and assertEquivalent (looser equivalency).
|
||||
*
|
||||
* 'editor' is a global object for the CodeMirror editor shared between all
|
||||
* tests. After manipulating it in each test, try to restore it to
|
||||
* approximately its original state.
|
||||
*/
|
||||
|
||||
function testSetGet() {
|
||||
var code = 'It was the best of times.\nIt was the worst of times.';
|
||||
editor.setCode(code);
|
||||
assertEquals(code, editor.getCode());
|
||||
editor.setCode('');
|
||||
assertEquals('', editor.getCode());
|
||||
}
|
||||
|
||||
function testSetStylesheet() {
|
||||
function cssStatus() {
|
||||
// Returns a list of tuples, for each CSS link return the filename and
|
||||
// whether it is enabled.
|
||||
links = editor.win.document.getElementsByTagName('link');
|
||||
css = [];
|
||||
for (var x = 0, link; link = links[x]; x++) {
|
||||
if (link.rel.indexOf("stylesheet") !== -1) {
|
||||
css.push([link.href.substring(link.href.lastIndexOf('/') + 1),
|
||||
!link.disabled])
|
||||
}
|
||||
}
|
||||
return css;
|
||||
}
|
||||
assertEquivalent([], cssStatus());
|
||||
editor.setStylesheet('css/jscolors.css');
|
||||
assertEquivalent([['jscolors.css', true]], cssStatus());
|
||||
editor.setStylesheet(['css/csscolors.css', 'css/xmlcolors.css']);
|
||||
assertEquivalent([['jscolors.css', false], ['csscolors.css', true], ['xmlcolors.css', true]], cssStatus());
|
||||
editor.setStylesheet([]);
|
||||
assertEquivalent([['jscolors.css', false], ['csscolors.css', false], ['xmlcolors.css', false]], cssStatus());
|
||||
}
|
||||
|
||||
// Update this list of tests as new ones are added.
|
||||
var tests = ['testSetGet', 'testSetStylesheet'];
|
||||
|
||||
133
includes/js/codemirror/util.js
Normal file
@@ -0,0 +1,133 @@
|
||||
/* A few useful utility functions. */
|
||||
|
||||
// Capture a method on an object.
|
||||
function method(obj, name) {
|
||||
return function() {obj[name].apply(obj, arguments);};
|
||||
}
|
||||
|
||||
// The value used to signal the end of a sequence in iterators.
|
||||
var StopIteration = {toString: function() {return "StopIteration"}};
|
||||
|
||||
// Apply a function to each element in a sequence.
|
||||
function forEach(iter, f) {
|
||||
if (iter.next) {
|
||||
try {while (true) f(iter.next());}
|
||||
catch (e) {if (e != StopIteration) throw e;}
|
||||
}
|
||||
else {
|
||||
for (var i = 0; i < iter.length; i++)
|
||||
f(iter[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Map a function over a sequence, producing an array of results.
|
||||
function map(iter, f) {
|
||||
var accum = [];
|
||||
forEach(iter, function(val) {accum.push(f(val));});
|
||||
return accum;
|
||||
}
|
||||
|
||||
// Create a predicate function that tests a string againsts a given
|
||||
// regular expression. No longer used but might be used by 3rd party
|
||||
// parsers.
|
||||
function matcher(regexp){
|
||||
return function(value){return regexp.test(value);};
|
||||
}
|
||||
|
||||
// Test whether a DOM node has a certain CSS class.
|
||||
function hasClass(element, className) {
|
||||
var classes = element.className;
|
||||
return classes && new RegExp("(^| )" + className + "($| )").test(classes);
|
||||
}
|
||||
function removeClass(element, className) {
|
||||
element.className = element.className.replace(new RegExp(" " + className + "\\b", "g"), "");
|
||||
return element;
|
||||
}
|
||||
|
||||
// Insert a DOM node after another node.
|
||||
function insertAfter(newNode, oldNode) {
|
||||
var parent = oldNode.parentNode;
|
||||
parent.insertBefore(newNode, oldNode.nextSibling);
|
||||
return newNode;
|
||||
}
|
||||
|
||||
function removeElement(node) {
|
||||
if (node.parentNode)
|
||||
node.parentNode.removeChild(node);
|
||||
}
|
||||
|
||||
function clearElement(node) {
|
||||
while (node.firstChild)
|
||||
node.removeChild(node.firstChild);
|
||||
}
|
||||
|
||||
// Check whether a node is contained in another one.
|
||||
function isAncestor(node, child) {
|
||||
while (child = child.parentNode) {
|
||||
if (node == child)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// The non-breaking space character.
|
||||
var nbsp = "\u00a0";
|
||||
var matching = {"{": "}", "[": "]", "(": ")",
|
||||
"}": "{", "]": "[", ")": "("};
|
||||
|
||||
// Standardize a few unportable event properties.
|
||||
function normalizeEvent(event) {
|
||||
if (!event.stopPropagation) {
|
||||
event.stopPropagation = function() {this.cancelBubble = true;};
|
||||
event.preventDefault = function() {this.returnValue = false;};
|
||||
}
|
||||
if (!event.stop) {
|
||||
event.stop = function() {
|
||||
this.stopPropagation();
|
||||
this.preventDefault();
|
||||
};
|
||||
}
|
||||
|
||||
if (event.type == "keypress") {
|
||||
event.code = (event.charCode == null) ? event.keyCode : event.charCode;
|
||||
event.character = String.fromCharCode(event.code);
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
// Portably register event handlers.
|
||||
function addEventHandler(node, type, handler, removeFunc) {
|
||||
function wrapHandler(event) {
|
||||
handler(normalizeEvent(event || window.event));
|
||||
}
|
||||
if (typeof node.addEventListener == "function") {
|
||||
node.addEventListener(type, wrapHandler, false);
|
||||
if (removeFunc) return function() {node.removeEventListener(type, wrapHandler, false);};
|
||||
}
|
||||
else {
|
||||
node.attachEvent("on" + type, wrapHandler);
|
||||
if (removeFunc) return function() {node.detachEvent("on" + type, wrapHandler);};
|
||||
}
|
||||
}
|
||||
|
||||
function nodeText(node) {
|
||||
return node.textContent || node.innerText || node.nodeValue || "";
|
||||
}
|
||||
|
||||
function nodeTop(node) {
|
||||
var top = 0;
|
||||
while (node.offsetParent) {
|
||||
top += node.offsetTop;
|
||||
node = node.offsetParent;
|
||||
}
|
||||
return top;
|
||||
}
|
||||
|
||||
function isBR(node) {
|
||||
var nn = node.nodeName;
|
||||
return nn == "BR" || nn == "br";
|
||||
}
|
||||
function isSpan(node) {
|
||||
var nn = node.nodeName;
|
||||
return nn == "SPAN" || nn == "span";
|
||||
}
|
||||
16
includes/js/scripts.js
Normal file
@@ -0,0 +1,16 @@
|
||||
jQuery.noConflict();
|
||||
|
||||
jQuery(document).ready(function(){
|
||||
|
||||
jQuery("#tabs").tabs();
|
||||
|
||||
// var editor = CodeMirror.fromTextArea('content', {
|
||||
// height: "350px",
|
||||
// parserfile: "parsexml.js",
|
||||
// stylesheet: "../wp-content/themes/roots/includes/css/codemirror/xmlcolors.css",
|
||||
// path: "../wp-content/themes/roots/includes/js/codemirror/",
|
||||
// continuousScanning: 500,
|
||||
// lineNumbers: false
|
||||
// });
|
||||
|
||||
});
|
||||
78
includes/roots-activation.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
// http://foolswisdom.com/wp-activate-theme-actio/
|
||||
|
||||
global $pagenow;
|
||||
if (is_admin() && 'themes.php' === $pagenow && isset( $_GET['activated'])) {
|
||||
|
||||
// on theme activation make sure there's a Home page
|
||||
// create it if there isn't and set the Home page menu order to -1
|
||||
// set WordPress to have the front page display the Home page as a static page
|
||||
$default_pages = array('Home');
|
||||
$existing_pages = get_pages();
|
||||
|
||||
foreach ($existing_pages as $page) {
|
||||
$temp[] = $page->post_title;
|
||||
}
|
||||
|
||||
$pages_to_create = array_diff($default_pages, $temp);
|
||||
|
||||
foreach ($pages_to_create as $new_page_title) {
|
||||
|
||||
// create post object
|
||||
$add_default_pages = array();
|
||||
$add_default_pages['post_title'] = $new_page_title;
|
||||
$add_default_pages['post_content'] = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat, orci ac laoreet cursus, dolor sem luctus lorem, eget consequat magna felis a magna. Aliquam scelerisque condimentum ante, eget facilisis tortor lobortis in. In interdum venenatis justo eget consequat. Morbi commodo rhoncus mi nec pharetra. Aliquam erat volutpat. Mauris non lorem eu dolor hendrerit dapibus. Mauris mollis nisl quis sapien posuere consectetur. Nullam in sapien at nisi ornare bibendum at ut lectus. Pellentesque ut magna mauris. Nam viverra suscipit ligula, sed accumsan enim placerat nec. Cras vitae metus vel dolor ultrices sagittis. Duis venenatis augue sed risus laoreet congue ac ac leo. Donec fermentum accumsan libero sit amet iaculis. Duis tristique dictum enim, ac fringilla risus bibendum in. Nunc ornare, quam sit amet ultricies gravida, tortor mi malesuada urna, quis commodo dui nibh in lacus. Nunc vel tortor mi. Pellentesque vel urna a arcu adipiscing imperdiet vitae sit amet neque. Integer eu lectus et nunc dictum sagittis. Curabitur commodo vulputate fringilla. Sed eleifend, arcu convallis adipiscing congue, dui turpis commodo magna, et vehicula sapien turpis sit amet nisi.';
|
||||
$add_default_pages['post_status'] = 'publish';
|
||||
$add_default_pages['post_type'] = 'page';
|
||||
|
||||
// insert the post into the database
|
||||
$result = wp_insert_post($add_default_pages);
|
||||
}
|
||||
|
||||
$home = get_page_by_title('Home');
|
||||
update_option('show_on_front', 'page');
|
||||
update_option('page_on_front', $home->ID);
|
||||
|
||||
$home_menu_order = array();
|
||||
$home_menu_order['ID'] = $home->ID;
|
||||
$home_menu_order['menu_order'] = -1;
|
||||
wp_update_post($home_menu_order);
|
||||
|
||||
// set the permalink structure
|
||||
if (get_option('permalink_structure') != '/%year%/%postname%/') {
|
||||
update_option('permalink_structure', '/%year%/%postname%/');
|
||||
}
|
||||
|
||||
$wp_rewrite->init();
|
||||
$wp_rewrite->flush_rules();
|
||||
|
||||
// don't organize uploads by year and month
|
||||
update_option('uploads_use_yearmonth_folders', 0);
|
||||
update_option('upload_path', 'assets');
|
||||
|
||||
// automatically create menus and set their locations
|
||||
// add all pages to the Primary Navigation
|
||||
$primary_nav_id = wp_create_nav_menu('Primary Navigation', array('slug' => 'primary_navigation'));
|
||||
$utility_nav_id = wp_create_nav_menu('Utility Navigation', array('slug' => 'utility_navigation'));
|
||||
set_theme_mod('nav_menu_locations', array(
|
||||
'primary_navigation' => $primary_nav_id,
|
||||
'utility_navigation' => $utility_nav_id
|
||||
));
|
||||
|
||||
$primary_nav = wp_get_nav_menu_object('Primary Navigation');
|
||||
$primary_nav_term_id = (int) $primary_nav->term_id;
|
||||
$pages = get_pages();
|
||||
foreach($pages as $page) {
|
||||
$item = array(
|
||||
'menu-item-object-id' => $page->ID,
|
||||
'menu-item-object' => 'page',
|
||||
'menu-item-type' => 'post_type',
|
||||
'menu-item-status' => 'publish'
|
||||
);
|
||||
wp_update_nav_menu_item($primary_nav_term_id, 0, $item);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
43
includes/roots-admin.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
// admin CSS and JS
|
||||
add_action('admin_init', 'roots_admin_init');
|
||||
|
||||
function roots_admin_init() {
|
||||
$site_url = site_url();
|
||||
|
||||
//wp_register_script('roots_codemirror', "$site_url/wp-content/themes/roots/includes/js/codemirror/codemirror.js");
|
||||
//wp_enqueue_script('roots_codemirror');
|
||||
|
||||
wp_enqueue_script('jquery-ui-tabs');
|
||||
wp_register_style('roots_admin', "$site_url/wp-content/themes/roots/includes/css/admin.css");
|
||||
wp_register_script('roots_admin', "$site_url/wp-content/themes/roots/includes/js/scripts.js");
|
||||
wp_enqueue_style('roots_admin');
|
||||
wp_enqueue_script('roots_admin');
|
||||
}
|
||||
|
||||
// check to see if the tagline is set to default
|
||||
// show an admin notice to update if it hasn't been changed
|
||||
// you want to change this or remove it because it's used as the description in the RSS feed
|
||||
if (get_option('blogdescription') === 'Just another WordPress site') {
|
||||
add_action('admin_notices', create_function('', "echo '<div class=\"error\"><p>" . sprintf(__('Please update your <a href="%s">site tagline</a>', 'roots'), admin_url('options-general.php')) . "</p></div>';"));
|
||||
};
|
||||
|
||||
// set the post revisions to 5 unless the constant
|
||||
// was set in wp-config.php to avoid DB bloat
|
||||
if (!defined('WP_POST_REVISIONS')) define('WP_POST_REVISIONS', 5);
|
||||
|
||||
// allow more tags in TinyMCE including iframes
|
||||
function roots_change_mce_options($options) {
|
||||
$ext = 'pre[id|name|class|style],iframe[align|longdesc|name|width|height|frameborder|scrolling|marginheight|marginwidth|src]';
|
||||
if (isset($initArray['extended_valid_elements'])) {
|
||||
$options['extended_valid_elements'] .= ',' . $ext;
|
||||
} else {
|
||||
$options['extended_valid_elements'] = $ext;
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
add_filter('tiny_mce_before_init', 'roots_change_mce_options');
|
||||
|
||||
?>
|
||||
306
includes/roots-cleanup.php
Normal file
@@ -0,0 +1,306 @@
|
||||
<?php
|
||||
|
||||
// rewrite /wp-content/themes/roots/css/ to /css/
|
||||
// rewrite /wp-content/themes/roots/js/ to /js/
|
||||
// rewrite /wp-content/themes/roots/img/ to /js/
|
||||
// rewrite /wp-content/plugins/ to /plugins/
|
||||
|
||||
function roots_flush_rewrites() {
|
||||
global $wp_rewrite;
|
||||
$wp_rewrite->flush_rules();
|
||||
}
|
||||
|
||||
function roots_add_rewrites() {
|
||||
global $wp_rewrite;
|
||||
$roots_new_non_wp_rules = array(
|
||||
'css/(.*)' => 'wp-content/themes/roots/css/$1',
|
||||
'js/(.*)' => 'wp-content/themes/roots/js/$1',
|
||||
'img/(.*)' => 'wp-content/themes/roots/img/$1',
|
||||
'plugins/(.*)' => 'wp-content/plugins/$1'
|
||||
);
|
||||
$wp_rewrite->non_wp_rules = $roots_new_non_wp_rules . $wp_rewrite->non_wp_rules;
|
||||
}
|
||||
|
||||
add_action('generate_rewrite_rules', 'roots_add_rewrites');
|
||||
add_action('admin_init', 'roots_flush_rewrites');
|
||||
|
||||
function roots_clean_assets($content) {
|
||||
$current_path = '/wp-content/themes/roots';
|
||||
$new_path = '';
|
||||
$content = str_replace($current_path, $new_path, $content);
|
||||
return $content;
|
||||
}
|
||||
add_filter('bloginfo', 'roots_clean_assets');
|
||||
add_filter('stylesheet_directory_uri', 'roots_clean_assets');
|
||||
|
||||
function roots_clean_plugins($content) {
|
||||
$current_path = '/wp-content/plugins';
|
||||
$new_path = '/plugins';
|
||||
$content = str_replace($current_path, $new_path, $content);
|
||||
return $content;
|
||||
}
|
||||
add_filter('plugins_url', 'roots_clean_plugins');
|
||||
|
||||
// redirect /?s to /search/
|
||||
// http://txfx.net/wordpress-plugins/nice-search/
|
||||
function roots_nice_search_redirect() {
|
||||
if (is_search() && strpos($_SERVER['REQUEST_URI'], '/wp-admin/') === false && strpos($_SERVER['REQUEST_URI'], '/search/') === false) {
|
||||
wp_redirect(home_url('/search/' . str_replace( array(' ', '%20'), array('+', '+'), get_query_var( 's' ))));
|
||||
exit();
|
||||
}
|
||||
}
|
||||
add_action('template_redirect', 'roots_nice_search_redirect');
|
||||
|
||||
// root relative URLs for everything
|
||||
// inspired by http://www.456bereastreet.com/archive/201010/how_to_make_wordpress_urls_root_relative/
|
||||
// thanks to Scott Walkinshaw (scottwalkinshaw.com)
|
||||
function roots_root_relative_url($input) {
|
||||
return preg_replace('!' . get_home_url() . '/!', '/', $input);
|
||||
}
|
||||
|
||||
//add_filter('site_url', 'roots_root_relative_url'); // this will break URLs sent out in emails, possibly more
|
||||
add_filter('bloginfo_url', 'roots_root_relative_url');
|
||||
add_filter('theme_root_uri', 'roots_root_relative_url');
|
||||
add_filter('stylesheet_directory_uri', 'roots_root_relative_url');
|
||||
add_filter('the_permalink', 'roots_root_relative_url');
|
||||
add_filter('wp_list_pages', 'roots_root_relative_url');
|
||||
add_filter('wp_list_categories', 'roots_root_relative_url');
|
||||
add_filter('wp_nav_menu', 'roots_root_relative_url');
|
||||
add_filter('wp_get_attachment_url', 'roots_root_relative_url');
|
||||
add_filter('wp_get_attachment_link', 'roots_root_relative_url');
|
||||
add_filter('the_content_more_link', 'roots_root_relative_url');
|
||||
add_filter('the_tags', 'roots_root_relative_url');
|
||||
add_filter('get_pagenum_link', 'roots_root_relative_url');
|
||||
add_filter('get_comment_link', 'roots_root_relative_url');
|
||||
add_filter('plugins_url', 'roots_root_relative_url');
|
||||
add_filter('month_link', 'roots_root_relative_url');
|
||||
add_filter('day_link', 'roots_root_relative_url');
|
||||
add_filter('year_link', 'roots_root_relative_url');
|
||||
add_filter('tag_link', 'roots_root_relative_url');
|
||||
// add_filter('post_link', 'roots_root_relative_url');
|
||||
|
||||
// remove root relative URLs on any attachments in the feed
|
||||
function roots_relative_feed_urls() {
|
||||
global $wp_query;
|
||||
if (is_feed()) {
|
||||
remove_filter('wp_get_attachment_url', 'roots_root_relative_url');
|
||||
remove_filter('wp_get_attachment_link', 'roots_root_relative_url');
|
||||
}
|
||||
}
|
||||
|
||||
add_action('pre_get_posts', 'roots_relative_feed_urls' );
|
||||
|
||||
// remove WordPress version from RSS feed
|
||||
function roots_no_generator() { return ''; }
|
||||
add_filter('the_generator', 'roots_no_generator');
|
||||
|
||||
|
||||
// cleanup wp_head
|
||||
function roots_head_cleanup() {
|
||||
// http://wpengineer.com/1438/wordpress-header/
|
||||
remove_action('wp_head', 'feed_links', 2);
|
||||
remove_action('wp_head', 'feed_links_extra', 3);
|
||||
remove_action('wp_head', 'rsd_link');
|
||||
remove_action('wp_head', 'wlwmanifest_link');
|
||||
remove_action('wp_head', 'index_rel_link');
|
||||
remove_action('wp_head', 'parent_post_rel_link', 10, 0);
|
||||
remove_action('wp_head', 'start_post_rel_link', 10, 0);
|
||||
remove_action('wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0);
|
||||
remove_action('wp_head', 'wp_generator');
|
||||
remove_action('wp_head', 'wp_shortlink_wp_head', 10, 0);
|
||||
|
||||
remove_action('wp_head', 'noindex', 1);
|
||||
function roots_noindex() {
|
||||
if ('0' == get_option('blog_public'))
|
||||
echo "<meta name=\"robots\" content=\"noindex,nofollow\">\n";
|
||||
}
|
||||
add_action('wp_head', 'roots_noindex');
|
||||
|
||||
remove_action('wp_head', 'rel_canonical');
|
||||
function roots_rel_canonical() {
|
||||
if (!is_singular())
|
||||
return;
|
||||
global $wp_the_query;
|
||||
if (!$id = $wp_the_query->get_queried_object_id())
|
||||
return;
|
||||
$link = get_permalink($id);
|
||||
echo " <link rel=\"canonical\" href=\"$link\">\n";
|
||||
}
|
||||
add_action('wp_head', 'roots_rel_canonical');
|
||||
|
||||
// stop Gravity Forms from outputting CSS since it's linked in header.php
|
||||
if (class_exists('RGForms')) {
|
||||
update_option('rg_gforms_disable_css', 1);
|
||||
}
|
||||
|
||||
// deregister l10n.js (new since WordPress 3.1)
|
||||
// why you might want to keep it: http://wordpress.stackexchange.com/questions/5451/what-does-l10n-js-do-in-wordpress-3-1-and-how-do-i-remove-it/5484#5484
|
||||
if (!is_admin()) {
|
||||
wp_deregister_script('l10n');
|
||||
}
|
||||
|
||||
// don't load jQuery through WordPress since it's linked in header.php
|
||||
if (!is_admin()) {
|
||||
wp_deregister_script('jquery');
|
||||
wp_register_script('jquery', '', '', '', true);
|
||||
}
|
||||
|
||||
// remove CSS from recent comments widget
|
||||
function roots_recent_comments_style() {
|
||||
global $wp_widget_factory;
|
||||
remove_action( 'wp_head', array($wp_widget_factory->widgets['WP_Widget_Recent_Comments'], 'recent_comments_style') );
|
||||
}
|
||||
|
||||
add_action('wp_head', 'roots_recent_comments_style', 1);
|
||||
|
||||
// remove CSS from gallery
|
||||
function roots_gallery_style($css) {
|
||||
return preg_replace("#<style type='text/css'>(.*?)</style>#s", '', $css);
|
||||
}
|
||||
|
||||
add_filter('gallery_style', 'roots_gallery_style');
|
||||
}
|
||||
|
||||
add_action('init', 'roots_head_cleanup');
|
||||
|
||||
// cleanup gallery_shortcode()
|
||||
remove_shortcode('gallery');
|
||||
|
||||
function roots_gallery_shortcode($attr) {
|
||||
global $post, $wp_locale;
|
||||
|
||||
static $instance = 0;
|
||||
$instance++;
|
||||
|
||||
// Allow plugins/themes to override the default gallery template.
|
||||
$output = apply_filters('post_gallery', '', $attr);
|
||||
if ( $output != '' )
|
||||
return $output;
|
||||
|
||||
// We're trusting author input, so let's at least make sure it looks like a valid orderby statement
|
||||
if ( isset( $attr['orderby'] ) ) {
|
||||
$attr['orderby'] = sanitize_sql_orderby( $attr['orderby'] );
|
||||
if ( !$attr['orderby'] )
|
||||
unset( $attr['orderby'] );
|
||||
}
|
||||
|
||||
extract(shortcode_atts(array(
|
||||
'order' => 'ASC',
|
||||
'orderby' => 'menu_order ID',
|
||||
'id' => $post->ID,
|
||||
'icontag' => 'figure',
|
||||
'captiontag' => 'figcaption',
|
||||
'columns' => 3,
|
||||
'size' => 'thumbnail',
|
||||
'include' => '',
|
||||
'exclude' => ''
|
||||
), $attr));
|
||||
|
||||
$id = intval($id);
|
||||
if ( 'RAND' == $order )
|
||||
$orderby = 'none';
|
||||
|
||||
if ( !empty($include) ) {
|
||||
$include = preg_replace( '/[^0-9,]+/', '', $include );
|
||||
$_attachments = get_posts( array('include' => $include, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );
|
||||
|
||||
$attachments = array();
|
||||
foreach ( $_attachments as $key => $val ) {
|
||||
$attachments[$val->ID] = $_attachments[$key];
|
||||
}
|
||||
} elseif ( !empty($exclude) ) {
|
||||
$exclude = preg_replace( '/[^0-9,]+/', '', $exclude );
|
||||
$attachments = get_children( array('post_parent' => $id, 'exclude' => $exclude, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );
|
||||
} else {
|
||||
$attachments = get_children( array('post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );
|
||||
}
|
||||
|
||||
if ( empty($attachments) )
|
||||
return '';
|
||||
|
||||
if ( is_feed() ) {
|
||||
$output = "\n";
|
||||
foreach ( $attachments as $att_id => $attachment )
|
||||
$output .= wp_get_attachment_link($att_id, $size, true) . "\n";
|
||||
return $output;
|
||||
}
|
||||
|
||||
$captiontag = tag_escape($captiontag);
|
||||
$columns = intval($columns);
|
||||
$itemwidth = $columns > 0 ? floor(100/$columns) : 100;
|
||||
$float = is_rtl() ? 'right' : 'left';
|
||||
|
||||
$selector = "gallery-{$instance}";
|
||||
|
||||
$gallery_style = $gallery_div = '';
|
||||
if ( apply_filters( 'use_default_gallery_style', true ) )
|
||||
$gallery_style = "";
|
||||
$size_class = sanitize_html_class( $size );
|
||||
$gallery_div = "<section id='$selector' class='clearfix gallery galleryid-{$id} gallery-columns-{$columns} gallery-size-{$size_class}'>";
|
||||
$output = apply_filters( 'gallery_style', $gallery_style . "\n\t\t" . $gallery_div );
|
||||
|
||||
$i = 0;
|
||||
foreach ( $attachments as $id => $attachment ) {
|
||||
// make the gallery link to the file by default instead of the attachment
|
||||
// thanks to Matt Price (countingrows.com)
|
||||
switch($attr['link']) {
|
||||
case 'file' :
|
||||
$link = wp_get_attachment_link($id, $size, false, false);
|
||||
break;
|
||||
case 'attachment' :
|
||||
$link = wp_get_attachment_link($id, $size, true, false);
|
||||
break;
|
||||
default :
|
||||
$link = wp_get_attachment_link($id, $size, false, false);
|
||||
break;
|
||||
}
|
||||
$output .= "
|
||||
<{$icontag} class=\"gallery-item\">
|
||||
$link
|
||||
";
|
||||
if ( $captiontag && trim($attachment->post_excerpt) ) {
|
||||
$output .= "
|
||||
<{$captiontag} class=\"gallery-caption\">
|
||||
" . wptexturize($attachment->post_excerpt) . "
|
||||
</{$captiontag}>";
|
||||
}
|
||||
$output .= "</{$icontag}>";
|
||||
if ( $columns > 0 && ++$i % $columns == 0 )
|
||||
$output .= '';
|
||||
}
|
||||
|
||||
$output .= "</section>\n";
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_shortcode('gallery', 'roots_gallery_shortcode');
|
||||
|
||||
|
||||
// http://www.deluxeblogtips.com/2011/01/remove-dashboard-widgets-in-wordpress.html
|
||||
function roots_remove_dashboard_widgets() {
|
||||
remove_meta_box('dashboard_incoming_links', 'dashboard', 'normal');
|
||||
remove_meta_box('dashboard_plugins', 'dashboard', 'normal');
|
||||
remove_meta_box('dashboard_primary', 'dashboard', 'normal');
|
||||
remove_meta_box('dashboard_secondary', 'dashboard', 'normal');
|
||||
}
|
||||
|
||||
add_action('admin_init', 'roots_remove_dashboard_widgets');
|
||||
|
||||
// excerpt cleanup
|
||||
function roots_excerpt_length($length) {
|
||||
return 40;
|
||||
}
|
||||
|
||||
function roots_continue_reading_link() {
|
||||
return ' <a href="' . get_permalink() . '">' . __( 'Continue…', 'roots' ) . '</a>';
|
||||
}
|
||||
|
||||
function roots_auto_excerpt_more($more) {
|
||||
return ' …' . roots_continue_reading_link();
|
||||
}
|
||||
|
||||
add_filter('excerpt_length', 'roots_excerpt_length');
|
||||
add_filter('excerpt_more', 'roots_auto_excerpt_more');
|
||||
|
||||
?>
|
||||
166
includes/roots-htaccess.php
Normal file
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
function roots_get_home_path() {
|
||||
$home = get_option( 'home' );
|
||||
$siteurl = get_option( 'siteurl' );
|
||||
if ( $home != '' && $home != $siteurl ) {
|
||||
$wp_path_rel_to_home = str_replace($home, '', $siteurl); /* $siteurl - $home */
|
||||
$pos = strpos($_SERVER["SCRIPT_FILENAME"], $wp_path_rel_to_home);
|
||||
$home_path = substr($_SERVER["SCRIPT_FILENAME"], 0, $pos);
|
||||
$home_path = trailingslashit( $home_path );
|
||||
} else {
|
||||
$home_path = ABSPATH;
|
||||
}
|
||||
return $home_path;
|
||||
}
|
||||
|
||||
$home_path = roots_get_home_path();
|
||||
|
||||
if (!is_writable($home_path . '.htaccess')) {
|
||||
add_action('admin_notices', create_function('', "echo '<div class=\"error\"><p>" . sprintf(__('Please make sure your <a href="%s">htaccess</a> file is writeable ', 'roots'), admin_url('options-permalink.php')) . "</p></div>';"));
|
||||
};
|
||||
|
||||
// thanks to Scott Walkinshaw (scottwalkinshaw.com)
|
||||
|
||||
function roots_add_htaccess($rules) {
|
||||
|
||||
$rules .= "\n# ----------------------------------------------------------------------";
|
||||
$rules .= "\n# Better website experience for IE users";
|
||||
$rules .= "\n# ----------------------------------------------------------------------";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n# Force the latest IE version, in various cases when it may fall back to IE7 mode";
|
||||
$rules .= "\n# github.com/rails/rails/commit/123eb25#commitcomment-118920";
|
||||
$rules .= "\n# Use ChromeFrame if it's installed for a better experience for the poor IE folk";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n<IfModule mod_setenvif.c>";
|
||||
$rules .= "\n<IfModule mod_headers.c>";
|
||||
$rules .= "\nBrowserMatch MSIE ie";
|
||||
$rules .= "\nHeader set X-UA-Compatible \"IE=Edge,chrome=1\" env=ie";
|
||||
$rules .= "\n</IfModule>";
|
||||
$rules .= "\n</IfModule>";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n<IfModule mod_headers.c>";
|
||||
$rules .= "\n# Because X-UA-Compatible isn't sent to non-IE (to save header bytes),";
|
||||
$rules .= "\n# We need to inform proxies that content changes based on UA";
|
||||
$rules .= "\nHeader append Vary User-Agent";
|
||||
$rules .= "\n# Cache control is set only if mod_headers is enabled, so that's unncessary to declare";
|
||||
$rules .= "\n</IfModule>";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n# ----------------------------------------------------------------------";
|
||||
$rules .= "\n# Cross-domain AJAX requests";
|
||||
$rules .= "\n# ----------------------------------------------------------------------";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n# Serve cross-domain ajax requests, disabled. ";
|
||||
$rules .= "\n# enable-cors.org";
|
||||
$rules .= "\n# code.google.com/p/html5security/wiki/CrossOriginRequestSecurity";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n# <IfModule mod_headers.c>";
|
||||
$rules .= "\n# Header set Access-Control-Allow-Origin "*"";
|
||||
$rules .= "\n# </IfModule>";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n# ----------------------------------------------------------------------";
|
||||
$rules .= "\n# Webfont access";
|
||||
$rules .= "\n# ----------------------------------------------------------------------";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n# allow access from all domains for webfonts";
|
||||
$rules .= "\n# alternatively you could only whitelist";
|
||||
$rules .= "\n# your subdomains like \"sub.domain.com\"";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n<FilesMatch \"\.(ttf|otf|eot|woff|font.css)$\">";
|
||||
$rules .= "\n<IfModule mod_headers.c>";
|
||||
$rules .= "\nHeader set Access-Control-Allow-Origin "*"";
|
||||
$rules .= "\n</IfModule>";
|
||||
$rules .= "\n</FilesMatch>";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n# ----------------------------------------------------------------------";
|
||||
$rules .= "\n# Proper MIME type for all files";
|
||||
$rules .= "\n# ----------------------------------------------------------------------";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n# audio";
|
||||
$rules .= "\nAddType audio/ogg oga ogg";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n# video";
|
||||
$rules .= "\nAddType video/ogg ogv";
|
||||
$rules .= "\nAddType video/mp4 mp4";
|
||||
$rules .= "\nAddType video/webm webm";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n# Proper svg serving. Required for svg webfonts on iPad";
|
||||
$rules .= "\n# twitter.com/FontSquirrel/status/14855840545";
|
||||
$rules .= "\nAddType image/svg+xml svg svgz ";
|
||||
$rules .= "\nAddEncoding gzip svgz";
|
||||
$rules .= "\n ";
|
||||
$rules .= "\n# webfonts ";
|
||||
$rules .= "\nAddType application/vnd.ms-fontobject eot";
|
||||
$rules .= "\nAddType font/truetype ttf";
|
||||
$rules .= "\nAddType font/opentype otf";
|
||||
$rules .= "\nAddType application/x-font-woff woff";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n# assorted types ";
|
||||
$rules .= "\nAddType image/x-icon ico";
|
||||
$rules .= "\nAddType image/webp webp";
|
||||
$rules .= "\nAddType text/cache-manifest appcache manifest";
|
||||
$rules .= "\nAddType text/x-component htc";
|
||||
$rules .= "\nAddType application/x-chrome-extension crx";
|
||||
$rules .= "\nAddType application/x-xpinstall xpi";
|
||||
$rules .= "\nAddType application/octet-stream safariextz";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n# ----------------------------------------------------------------------";
|
||||
$rules .= "\n# gzip compression";
|
||||
$rules .= "\n# ----------------------------------------------------------------------";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n<IfModule mod_deflate.c>";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n# force deflate for mangled headers developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping/";
|
||||
$rules .= "\n<IfModule mod_setenvif.c>";
|
||||
$rules .= "\n<IfModule mod_headers.c>";
|
||||
$rules .= "\nSetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s,?\s(gzip|deflate)?|X{4,13}|~{4,13}|-{4,13})$ HAVE_Accept-Encoding";
|
||||
$rules .= "\nRequestHeader append Accept-Encoding \"gzip,deflate\" env=HAVE_Accept-Encoding";
|
||||
$rules .= "\n</IfModule>";
|
||||
$rules .= "\n</IfModule>";
|
||||
$rules .= "\n# html, txt, css, js, json, xml, htc:";
|
||||
$rules .= "\n<IfModule filter_module>";
|
||||
$rules .= "\nFilterDeclare COMPRESS";
|
||||
$rules .= "\nFilterProvider COMPRESS DEFLATE resp=Content-Type /text/(html|css|javascript|plain|x(ml|-component))/";
|
||||
$rules .= "\nFilterProvider COMPRESS DEFLATE resp=Content-Type /application/(javascript|json|xml|x-javascript)/";
|
||||
$rules .= "\nFilterChain COMPRESS";
|
||||
$rules .= "\nFilterProtocol COMPRESS change=yes;byteranges=no";
|
||||
$rules .= "\n</IfModule>";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n<IfModule !mod_filter.c>";
|
||||
$rules .= "\n# Legacy versions of Apache";
|
||||
$rules .= "\nAddOutputFilterByType DEFLATE text/html text/plain text/css application/json";
|
||||
$rules .= "\nAddOutputFilterByType DEFLATE text/javascript application/javascript application/x-javascript ";
|
||||
$rules .= "\nAddOutputFilterByType DEFLATE text/xml application/xml text/x-component";
|
||||
$rules .= "\n</IfModule>";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n# webfonts and svg:";
|
||||
$rules .= "\n<FilesMatch \"\.(ttf|otf|eot|svg)$\" >";
|
||||
$rules .= "\nSetOutputFilter DEFLATE";
|
||||
$rules .= "\n</FilesMatch>";
|
||||
$rules .= "\n</IfModule>";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n# ----------------------------------------------------------------------";
|
||||
$rules .= "\n# UTF-8 encoding";
|
||||
$rules .= "\n# ----------------------------------------------------------------------";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n# use utf-8 encoding for anything served text/plain or text/html";
|
||||
$rules .= "\nAddDefaultCharset utf-8";
|
||||
$rules .= "\n";
|
||||
$rules .= "\n# force utf-8 for a number of file formats";
|
||||
$rules .= "\nAddCharset utf-8 .html .css .js .xml .json .rss";
|
||||
$rules .= "\n";
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
add_action('mod_rewrite_rules', 'roots_add_htaccess');
|
||||
?>
|
||||
25
includes/roots-ob.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
// http://www.dagondesign.com/articles/wordpress-hook-for-entire-page-using-output-buffering/
|
||||
|
||||
function roots_callback($buffer) {
|
||||
if (class_exists('All_in_One_SEO_Pack')) {
|
||||
$temp = preg_replace('/<!-- All in One[^>]+?>\s+/', '', $buffer);
|
||||
return preg_replace('/<!-- \/all in one seo pack -->\n/', '', $temp);
|
||||
} else {
|
||||
return $buffer;
|
||||
}
|
||||
}
|
||||
|
||||
function roots_buffer_start() {
|
||||
ob_start('roots_callback');
|
||||
}
|
||||
|
||||
function roots_buffer_end() {
|
||||
ob_end_flush();
|
||||
}
|
||||
|
||||
add_action('wp_head', 'roots_buffer_start', -999);
|
||||
add_action('wp_footer', 'roots_buffer_end');
|
||||
|
||||
?>
|
||||
112
includes/roots-options.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
// create custom plugin settings menu
|
||||
add_action('admin_menu', 'roots_create_menu');
|
||||
|
||||
function roots_create_menu() {
|
||||
$icon = get_template_directory_uri() . '/includes/images/icon-roots.png';
|
||||
|
||||
// create menu
|
||||
add_object_page('Roots Settings', 'Roots', 'administrator', 'roots', 'roots_settings_page', $icon);
|
||||
|
||||
// call register settings function
|
||||
add_action('admin_init', 'roots_register_settings');
|
||||
|
||||
}
|
||||
|
||||
function roots_register_settings() {
|
||||
// register our settings
|
||||
register_setting('roots-settings-group', 'roots_main_class');
|
||||
register_setting('roots-settings-group', 'roots_sidebar_class');
|
||||
register_setting('roots-settings-group', 'roots_google_analytics');
|
||||
register_setting('roots-settings-group', 'roots_post_author');
|
||||
register_setting('roots-settings-group', 'roots_post_tweet');
|
||||
register_setting('roots-settings-group', 'roots_footer_social_share');
|
||||
register_setting('roots-settings-group', 'roots_vcard_street-address');
|
||||
register_setting('roots-settings-group', 'roots_vcard_locality');
|
||||
register_setting('roots-settings-group', 'roots_vcard_region');
|
||||
register_setting('roots-settings-group', 'roots_vcard_postal-code');
|
||||
register_setting('roots-settings-group', 'roots_vcard_tel');
|
||||
register_setting('roots-settings-group', 'roots_vcard_email');
|
||||
register_setting('roots-settings-group', 'roots_footer_vcard');
|
||||
|
||||
// add default settings
|
||||
add_option('roots_main_class', 'span-14 append-1');
|
||||
add_option('roots_sidebar_class', 'span-8 prepend-1 last');
|
||||
add_option('roots_google_analytics', '');
|
||||
}
|
||||
|
||||
function roots_settings_page() { ?>
|
||||
|
||||
<div class="wrap">
|
||||
<div id="icon-options-general" class="icon32"></div>
|
||||
<h2>Roots Settings</h2>
|
||||
|
||||
<?php if ($_GET['settings-updated'] === 'true') { ?>
|
||||
<div id="setting-error-settings_updated" class="updated settings-error"><p><strong>Settings saved.</strong></p></div>
|
||||
<?php } ?>
|
||||
|
||||
<form method="post" action="options.php">
|
||||
|
||||
<?php settings_fields('roots-settings-group'); ?>
|
||||
|
||||
<div id="tabs">
|
||||
<ul>
|
||||
<li><a href="#general">General</a></li>
|
||||
</ul>
|
||||
<div id="general">
|
||||
<ul class="options clearfix">
|
||||
<li>
|
||||
<label class="settings-label">Class for #main</label>
|
||||
<input name="roots_main_class" type="text" value="<?php echo get_option('roots_main_class'); ?>" class="text" />
|
||||
<span class="note">Enter your Blueprint CSS grid classes (use <a href="http://ianli.com/labs/blueprinter/">Blueprinter</a> to create a non-default grid)</span>
|
||||
</li>
|
||||
<li>
|
||||
<label class="settings-label">Class for #sidebar</label>
|
||||
<input name="roots_sidebar_class" type="text" value="<?php echo get_option('roots_sidebar_class'); ?>" class="text" />
|
||||
<span class="note">Enter your Blueprint CSS grid classes (use <a href="http://ianli.com/labs/blueprinter/">Blueprinter</a> to create a non-default grid)</span>
|
||||
</li>
|
||||
<li>
|
||||
<label class="settings-label">Google Analytics Tracking ID</label>
|
||||
<input name="roots_google_analytics" type="text" value="<?php echo get_option('roots_google_analytics'); ?>" class="text" />
|
||||
<span class="note">Enter your UA-XXXXX-X ID</span>
|
||||
</li>
|
||||
<li>
|
||||
<label class="settings-label">Display Post Author</label>
|
||||
<input id="roots_post_author" name="roots_post_author" type="checkbox" <?php echo get_option('roots_post_author') === 'checked' ? 'checked' : ''; ?> value="checked" /> <label for="roots_post_author">Show the post author</label>
|
||||
</li>
|
||||
<li>
|
||||
<label class="settings-label">Post Tweet Button</label>
|
||||
<input id="roots_post_tweet" name="roots_post_tweet" type="checkbox" <?php echo get_option('roots_post_tweet') === 'checked' ? 'checked' : ''; ?> value="checked" /> <label for="roots_post_tweet">Enable Tweet button on posts</label>
|
||||
</li>
|
||||
<li>
|
||||
<label class="settings-label">Footer Social Share Buttons</label>
|
||||
<input id="roots_footer_social_share" name="roots_footer_social_share" type="checkbox" <?php echo get_option('roots_footer_social_share') === 'checked' ? 'checked' : ''; ?> value="checked" /> <label for="roots_footer_social_share">Enable official Twitter and Facebook buttons in the footer</label>
|
||||
</li>
|
||||
<li>
|
||||
<label class="settings-label">Footer vCard</label>
|
||||
<input id="roots_footer_vcard" name="roots_footer_vcard" type="checkbox" <?php echo get_option('roots_footer_vcard') === 'checked' ? 'checked' : ''; ?> value="checked" /> <label for="roots_footer_vcard">Enable vCard in the footer</label>
|
||||
</li>
|
||||
<li class="clearfix">
|
||||
<label class="settings-label">vCard Information</label>
|
||||
<div class="address">
|
||||
<label for="roots_vcard_street-address">Street Address</label> <input id="roots_vcard_street-address" name="roots_vcard_street-address" type="text" value="<?php echo get_option('roots_vcard_street-address'); ?>" class="text" />
|
||||
<label for="roots_vcard_locality">City</label> <input id="roots_vcard_locality" name="roots_vcard_locality" type="text" value="<?php echo get_option('roots_vcard_locality'); ?>" class="text" />
|
||||
<label for="roots_vcard_region">State</label> <input id="roots_vcard_region" name="roots_vcard_region" type="text" value="<?php echo get_option('roots_vcard_region'); ?>" class="text" />
|
||||
<label for="roots_vcard_postal-code">Zipcode</label> <input id="roots_vcard_postal-code" name="roots_vcard_postal-code" type="text" value="<?php echo get_option('roots_vcard_postal-code'); ?>" class="text" />
|
||||
<label for="roots_vcard_tel">Telephone Number</label> <input id="roots_vcard_tel" name="roots_vcard_tel" type="text" value="<?php echo get_option('roots_vcard_tel'); ?>" class="text" />
|
||||
<label for="roots_vcard_email">Email Address</label> <input id="roots_vcard_email" name="roots_vcard_email" type="text" value="<?php echo get_option('roots_vcard_email'); ?>" class="text" />
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="submit">
|
||||
<input type="submit" class="button-primary" value="Save Changes" />
|
||||
</p>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php } ?>
|
||||
15
index.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php get_header(); ?>
|
||||
<div id="content" class="span-24">
|
||||
<div id="main" class="<?php echo get_option('roots_main_class'); ?>" role="main">
|
||||
<div class="container">
|
||||
<h1>Latest Posts</h1>
|
||||
<?php get_template_part('loop', 'index'); ?>
|
||||
</div>
|
||||
</div><!-- /#main -->
|
||||
<aside id="sidebar" class="<?php echo get_option('roots_sidebar_class'); ?>" role="complementary">
|
||||
<div class="container">
|
||||
<?php get_sidebar(); ?>
|
||||
</div>
|
||||
</aside><!-- /#sidebar -->
|
||||
</div><!-- /#content -->
|
||||
<?php get_footer(); ?>
|
||||
1
js/jquery.cycle.lite.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
(function(D){var A="Lite-1.0";D.fn.cycle=function(E){return this.each(function(){E=E||{};if(this.cycleTimeout){clearTimeout(this.cycleTimeout)}this.cycleTimeout=0;this.cyclePause=0;var I=D(this);var J=E.slideExpr?D(E.slideExpr,this):I.children();var G=J.get();if(G.length<2){if(window.console&&window.console.log){window.console.log("terminating; too few slides: "+G.length)}return }var H=D.extend({},D.fn.cycle.defaults,E||{},D.metadata?I.metadata():D.meta?I.data():{});H.before=H.before?[H.before]:[];H.after=H.after?[H.after]:[];H.after.unshift(function(){H.busy=0});var F=this.className;H.width=parseInt((F.match(/w:(\d+)/)||[])[1])||H.width;H.height=parseInt((F.match(/h:(\d+)/)||[])[1])||H.height;H.timeout=parseInt((F.match(/t:(\d+)/)||[])[1])||H.timeout;if(I.css("position")=="static"){I.css("position","relative")}if(H.width){I.width(H.width)}if(H.height&&H.height!="auto"){I.height(H.height)}var K=0;J.css({position:"absolute",top:0,left:0}).hide().each(function(M){D(this).css("z-index",G.length-M)});D(G[K]).css("opacity",1).show();if(D.browser.msie){G[K].style.removeAttribute("filter")}if(H.fit&&H.width){J.width(H.width)}if(H.fit&&H.height&&H.height!="auto"){J.height(H.height)}if(H.pause){I.hover(function(){this.cyclePause=1},function(){this.cyclePause=0})}D.fn.cycle.transitions.fade(I,J,H);J.each(function(){var M=D(this);this.cycleH=(H.fit&&H.height)?H.height:M.height();this.cycleW=(H.fit&&H.width)?H.width:M.width()});J.not(":eq("+K+")").css({opacity:0});if(H.cssFirst){D(J[K]).css(H.cssFirst)}if(H.timeout){if(H.speed.constructor==String){H.speed={slow:600,fast:200}[H.speed]||400}if(!H.sync){H.speed=H.speed/2}while((H.timeout-H.speed)<250){H.timeout+=H.speed}}H.speedIn=H.speed;H.speedOut=H.speed;H.slideCount=G.length;H.currSlide=K;H.nextSlide=1;var L=J[K];if(H.before.length){H.before[0].apply(L,[L,L,H,true])}if(H.after.length>1){H.after[1].apply(L,[L,L,H,true])}if(H.click&&!H.next){H.next=H.click}if(H.next){D(H.next).bind("click",function(){return C(G,H,H.rev?-1:1)})}if(H.prev){D(H.prev).bind("click",function(){return C(G,H,H.rev?1:-1)})}if(H.timeout){this.cycleTimeout=setTimeout(function(){B(G,H,0,!H.rev)},H.timeout+(H.delay||0))}})};function B(J,E,I,K){if(E.busy){return }var H=J[0].parentNode,M=J[E.currSlide],L=J[E.nextSlide];if(H.cycleTimeout===0&&!I){return }if(I||!H.cyclePause){if(E.before.length){D.each(E.before,function(N,O){O.apply(L,[M,L,E,K])})}var F=function(){if(D.browser.msie){this.style.removeAttribute("filter")}D.each(E.after,function(N,O){O.apply(L,[M,L,E,K])})};if(E.nextSlide!=E.currSlide){E.busy=1;D.fn.cycle.custom(M,L,E,F)}var G=(E.nextSlide+1)==J.length;E.nextSlide=G?0:E.nextSlide+1;E.currSlide=G?J.length-1:E.nextSlide-1}if(E.timeout){H.cycleTimeout=setTimeout(function(){B(J,E,0,!E.rev)},E.timeout)}}function C(E,F,I){var H=E[0].parentNode,G=H.cycleTimeout;if(G){clearTimeout(G);H.cycleTimeout=0}F.nextSlide=F.currSlide+I;if(F.nextSlide<0){F.nextSlide=E.length-1}else{if(F.nextSlide>=E.length){F.nextSlide=0}}B(E,F,1,I>=0);return false}D.fn.cycle.custom=function(K,H,I,E){var J=D(K),G=D(H);G.css({opacity:0});var F=function(){G.animate({opacity:1},I.speedIn,I.easeIn,E)};J.animate({opacity:0},I.speedOut,I.easeOut,function(){J.css({display:"none"});if(!I.sync){F()}});if(I.sync){F()}};D.fn.cycle.transitions={fade:function(F,G,E){G.not(":eq(0)").css("opacity",0);E.before.push(function(){D(this).show()})}};D.fn.cycle.ver=function(){return A};D.fn.cycle.defaults={timeout:4000,speed:1000,next:null,prev:null,before:null,after:null,height:"auto",sync:1,fit:0,pause:0,delay:0,slideExpr:null}})(jQuery)
|
||||
10
js/jquery.cycle.min.js
vendored
Normal file
46
js/jquery.fancybox-1.3.4.pack.js
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* FancyBox - jQuery Plugin
|
||||
* Simple and fancy lightbox alternative
|
||||
*
|
||||
* Examples and documentation at: http://fancybox.net
|
||||
*
|
||||
* Copyright (c) 2008 - 2010 Janis Skarnelis
|
||||
* That said, it is hardly a one-person project. Many people have submitted bugs, code, and offered their advice freely. Their support is greatly appreciated.
|
||||
*
|
||||
* Version: 1.3.4 (11/11/2010)
|
||||
* Requires: jQuery v1.3+
|
||||
*
|
||||
* Dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*/
|
||||
|
||||
;(function(b){var m,t,u,f,D,j,E,n,z,A,q=0,e={},o=[],p=0,d={},l=[],G=null,v=new Image,J=/\.(jpg|gif|png|bmp|jpeg)(.*)?$/i,W=/[^\.]\.(swf)\s*$/i,K,L=1,y=0,s="",r,i,h=false,B=b.extend(b("<div/>")[0],{prop:0}),M=b.browser.msie&&b.browser.version<7&&!window.XMLHttpRequest,N=function(){t.hide();v.onerror=v.onload=null;G&&G.abort();m.empty()},O=function(){if(false===e.onError(o,q,e)){t.hide();h=false}else{e.titleShow=false;e.width="auto";e.height="auto";m.html('<p id="fancybox-error">The requested content cannot be loaded.<br />Please try again later.</p>');
|
||||
F()}},I=function(){var a=o[q],c,g,k,C,P,w;N();e=b.extend({},b.fn.fancybox.defaults,typeof b(a).data("fancybox")=="undefined"?e:b(a).data("fancybox"));w=e.onStart(o,q,e);if(w===false)h=false;else{if(typeof w=="object")e=b.extend(e,w);k=e.title||(a.nodeName?b(a).attr("title"):a.title)||"";if(a.nodeName&&!e.orig)e.orig=b(a).children("img:first").length?b(a).children("img:first"):b(a);if(k===""&&e.orig&&e.titleFromAlt)k=e.orig.attr("alt");c=e.href||(a.nodeName?b(a).attr("href"):a.href)||null;if(/^(?:javascript)/i.test(c)||
|
||||
c=="#")c=null;if(e.type){g=e.type;if(!c)c=e.content}else if(e.content)g="html";else if(c)g=c.match(J)?"image":c.match(W)?"swf":b(a).hasClass("iframe")?"iframe":c.indexOf("#")===0?"inline":"ajax";if(g){if(g=="inline"){a=c.substr(c.indexOf("#"));g=b(a).length>0?"inline":"ajax"}e.type=g;e.href=c;e.title=k;if(e.autoDimensions)if(e.type=="html"||e.type=="inline"||e.type=="ajax"){e.width="auto";e.height="auto"}else e.autoDimensions=false;if(e.modal){e.overlayShow=true;e.hideOnOverlayClick=false;e.hideOnContentClick=
|
||||
false;e.enableEscapeButton=false;e.showCloseButton=false}e.padding=parseInt(e.padding,10);e.margin=parseInt(e.margin,10);m.css("padding",e.padding+e.margin);b(".fancybox-inline-tmp").unbind("fancybox-cancel").bind("fancybox-change",function(){b(this).replaceWith(j.children())});switch(g){case "html":m.html(e.content);F();break;case "inline":if(b(a).parent().is("#fancybox-content")===true){h=false;break}b('<div class="fancybox-inline-tmp" />').hide().insertBefore(b(a)).bind("fancybox-cleanup",function(){b(this).replaceWith(j.children())}).bind("fancybox-cancel",
|
||||
function(){b(this).replaceWith(m.children())});b(a).appendTo(m);F();break;case "image":h=false;b.fancybox.showActivity();v=new Image;v.onerror=function(){O()};v.onload=function(){h=true;v.onerror=v.onload=null;e.width=v.width;e.height=v.height;b("<img />").attr({id:"fancybox-img",src:v.src,alt:e.title}).appendTo(m);Q()};v.src=c;break;case "swf":e.scrolling="no";C='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="'+e.width+'" height="'+e.height+'"><param name="movie" value="'+c+
|
||||
'"></param>';P="";b.each(e.swf,function(x,H){C+='<param name="'+x+'" value="'+H+'"></param>';P+=" "+x+'="'+H+'"'});C+='<embed src="'+c+'" type="application/x-shockwave-flash" width="'+e.width+'" height="'+e.height+'"'+P+"></embed></object>";m.html(C);F();break;case "ajax":h=false;b.fancybox.showActivity();e.ajax.win=e.ajax.success;G=b.ajax(b.extend({},e.ajax,{url:c,data:e.ajax.data||{},error:function(x){x.status>0&&O()},success:function(x,H,R){if((typeof R=="object"?R:G).status==200){if(typeof e.ajax.win==
|
||||
"function"){w=e.ajax.win(c,x,H,R);if(w===false){t.hide();return}else if(typeof w=="string"||typeof w=="object")x=w}m.html(x);F()}}}));break;case "iframe":Q()}}else O()}},F=function(){var a=e.width,c=e.height;a=a.toString().indexOf("%")>-1?parseInt((b(window).width()-e.margin*2)*parseFloat(a)/100,10)+"px":a=="auto"?"auto":a+"px";c=c.toString().indexOf("%")>-1?parseInt((b(window).height()-e.margin*2)*parseFloat(c)/100,10)+"px":c=="auto"?"auto":c+"px";m.wrapInner('<div style="width:'+a+";height:"+c+
|
||||
";overflow: "+(e.scrolling=="auto"?"auto":e.scrolling=="yes"?"scroll":"hidden")+';position:relative;"></div>');e.width=m.width();e.height=m.height();Q()},Q=function(){var a,c;t.hide();if(f.is(":visible")&&false===d.onCleanup(l,p,d)){b.event.trigger("fancybox-cancel");h=false}else{h=true;b(j.add(u)).unbind();b(window).unbind("resize.fb scroll.fb");b(document).unbind("keydown.fb");f.is(":visible")&&d.titlePosition!=="outside"&&f.css("height",f.height());l=o;p=q;d=e;if(d.overlayShow){u.css({"background-color":d.overlayColor,
|
||||
opacity:d.overlayOpacity,cursor:d.hideOnOverlayClick?"pointer":"auto",height:b(document).height()});if(!u.is(":visible")){M&&b("select:not(#fancybox-tmp select)").filter(function(){return this.style.visibility!=="hidden"}).css({visibility:"hidden"}).one("fancybox-cleanup",function(){this.style.visibility="inherit"});u.show()}}else u.hide();i=X();s=d.title||"";y=0;n.empty().removeAttr("style").removeClass();if(d.titleShow!==false){if(b.isFunction(d.titleFormat))a=d.titleFormat(s,l,p,d);else a=s&&s.length?
|
||||
d.titlePosition=="float"?'<table id="fancybox-title-float-wrap" cellpadding="0" cellspacing="0"><tr><td id="fancybox-title-float-left"></td><td id="fancybox-title-float-main">'+s+'</td><td id="fancybox-title-float-right"></td></tr></table>':'<div id="fancybox-title-'+d.titlePosition+'">'+s+"</div>":false;s=a;if(!(!s||s==="")){n.addClass("fancybox-title-"+d.titlePosition).html(s).appendTo("body").show();switch(d.titlePosition){case "inside":n.css({width:i.width-d.padding*2,marginLeft:d.padding,marginRight:d.padding});
|
||||
y=n.outerHeight(true);n.appendTo(D);i.height+=y;break;case "over":n.css({marginLeft:d.padding,width:i.width-d.padding*2,bottom:d.padding}).appendTo(D);break;case "float":n.css("left",parseInt((n.width()-i.width-40)/2,10)*-1).appendTo(f);break;default:n.css({width:i.width-d.padding*2,paddingLeft:d.padding,paddingRight:d.padding}).appendTo(f)}}}n.hide();if(f.is(":visible")){b(E.add(z).add(A)).hide();a=f.position();r={top:a.top,left:a.left,width:f.width(),height:f.height()};c=r.width==i.width&&r.height==
|
||||
i.height;j.fadeTo(d.changeFade,0.3,function(){var g=function(){j.html(m.contents()).fadeTo(d.changeFade,1,S)};b.event.trigger("fancybox-change");j.empty().removeAttr("filter").css({"border-width":d.padding,width:i.width-d.padding*2,height:e.autoDimensions?"auto":i.height-y-d.padding*2});if(c)g();else{B.prop=0;b(B).animate({prop:1},{duration:d.changeSpeed,easing:d.easingChange,step:T,complete:g})}})}else{f.removeAttr("style");j.css("border-width",d.padding);if(d.transitionIn=="elastic"){r=V();j.html(m.contents());
|
||||
f.show();if(d.opacity)i.opacity=0;B.prop=0;b(B).animate({prop:1},{duration:d.speedIn,easing:d.easingIn,step:T,complete:S})}else{d.titlePosition=="inside"&&y>0&&n.show();j.css({width:i.width-d.padding*2,height:e.autoDimensions?"auto":i.height-y-d.padding*2}).html(m.contents());f.css(i).fadeIn(d.transitionIn=="none"?0:d.speedIn,S)}}}},Y=function(){if(d.enableEscapeButton||d.enableKeyboardNav)b(document).bind("keydown.fb",function(a){if(a.keyCode==27&&d.enableEscapeButton){a.preventDefault();b.fancybox.close()}else if((a.keyCode==
|
||||
37||a.keyCode==39)&&d.enableKeyboardNav&&a.target.tagName!=="INPUT"&&a.target.tagName!=="TEXTAREA"&&a.target.tagName!=="SELECT"){a.preventDefault();b.fancybox[a.keyCode==37?"prev":"next"]()}});if(d.showNavArrows){if(d.cyclic&&l.length>1||p!==0)z.show();if(d.cyclic&&l.length>1||p!=l.length-1)A.show()}else{z.hide();A.hide()}},S=function(){if(!b.support.opacity){j.get(0).style.removeAttribute("filter");f.get(0).style.removeAttribute("filter")}e.autoDimensions&&j.css("height","auto");f.css("height","auto");
|
||||
s&&s.length&&n.show();d.showCloseButton&&E.show();Y();d.hideOnContentClick&&j.bind("click",b.fancybox.close);d.hideOnOverlayClick&&u.bind("click",b.fancybox.close);b(window).bind("resize.fb",b.fancybox.resize);d.centerOnScroll&&b(window).bind("scroll.fb",b.fancybox.center);if(d.type=="iframe")b('<iframe id="fancybox-frame" name="fancybox-frame'+(new Date).getTime()+'" frameborder="0" hspace="0" '+(b.browser.msie?'allowtransparency="true""':"")+' scrolling="'+e.scrolling+'" src="'+d.href+'"></iframe>').appendTo(j);
|
||||
f.show();h=false;b.fancybox.center();d.onComplete(l,p,d);var a,c;if(l.length-1>p){a=l[p+1].href;if(typeof a!=="undefined"&&a.match(J)){c=new Image;c.src=a}}if(p>0){a=l[p-1].href;if(typeof a!=="undefined"&&a.match(J)){c=new Image;c.src=a}}},T=function(a){var c={width:parseInt(r.width+(i.width-r.width)*a,10),height:parseInt(r.height+(i.height-r.height)*a,10),top:parseInt(r.top+(i.top-r.top)*a,10),left:parseInt(r.left+(i.left-r.left)*a,10)};if(typeof i.opacity!=="undefined")c.opacity=a<0.5?0.5:a;f.css(c);
|
||||
j.css({width:c.width-d.padding*2,height:c.height-y*a-d.padding*2})},U=function(){return[b(window).width()-d.margin*2,b(window).height()-d.margin*2,b(document).scrollLeft()+d.margin,b(document).scrollTop()+d.margin]},X=function(){var a=U(),c={},g=d.autoScale,k=d.padding*2;c.width=d.width.toString().indexOf("%")>-1?parseInt(a[0]*parseFloat(d.width)/100,10):d.width+k;c.height=d.height.toString().indexOf("%")>-1?parseInt(a[1]*parseFloat(d.height)/100,10):d.height+k;if(g&&(c.width>a[0]||c.height>a[1]))if(e.type==
|
||||
"image"||e.type=="swf"){g=d.width/d.height;if(c.width>a[0]){c.width=a[0];c.height=parseInt((c.width-k)/g+k,10)}if(c.height>a[1]){c.height=a[1];c.width=parseInt((c.height-k)*g+k,10)}}else{c.width=Math.min(c.width,a[0]);c.height=Math.min(c.height,a[1])}c.top=parseInt(Math.max(a[3]-20,a[3]+(a[1]-c.height-40)*0.5),10);c.left=parseInt(Math.max(a[2]-20,a[2]+(a[0]-c.width-40)*0.5),10);return c},V=function(){var a=e.orig?b(e.orig):false,c={};if(a&&a.length){c=a.offset();c.top+=parseInt(a.css("paddingTop"),
|
||||
10)||0;c.left+=parseInt(a.css("paddingLeft"),10)||0;c.top+=parseInt(a.css("border-top-width"),10)||0;c.left+=parseInt(a.css("border-left-width"),10)||0;c.width=a.width();c.height=a.height();c={width:c.width+d.padding*2,height:c.height+d.padding*2,top:c.top-d.padding-20,left:c.left-d.padding-20}}else{a=U();c={width:d.padding*2,height:d.padding*2,top:parseInt(a[3]+a[1]*0.5,10),left:parseInt(a[2]+a[0]*0.5,10)}}return c},Z=function(){if(t.is(":visible")){b("div",t).css("top",L*-40+"px");L=(L+1)%12}else clearInterval(K)};
|
||||
b.fn.fancybox=function(a){if(!b(this).length)return this;b(this).data("fancybox",b.extend({},a,b.metadata?b(this).metadata():{})).unbind("click.fb").bind("click.fb",function(c){c.preventDefault();if(!h){h=true;b(this).blur();o=[];q=0;c=b(this).attr("rel")||"";if(!c||c==""||c==="nofollow")o.push(this);else{o=b("a[rel="+c+"], area[rel="+c+"]");q=o.index(this)}I()}});return this};b.fancybox=function(a,c){var g;if(!h){h=true;g=typeof c!=="undefined"?c:{};o=[];q=parseInt(g.index,10)||0;if(b.isArray(a)){for(var k=
|
||||
0,C=a.length;k<C;k++)if(typeof a[k]=="object")b(a[k]).data("fancybox",b.extend({},g,a[k]));else a[k]=b({}).data("fancybox",b.extend({content:a[k]},g));o=jQuery.merge(o,a)}else{if(typeof a=="object")b(a).data("fancybox",b.extend({},g,a));else a=b({}).data("fancybox",b.extend({content:a},g));o.push(a)}if(q>o.length||q<0)q=0;I()}};b.fancybox.showActivity=function(){clearInterval(K);t.show();K=setInterval(Z,66)};b.fancybox.hideActivity=function(){t.hide()};b.fancybox.next=function(){return b.fancybox.pos(p+
|
||||
1)};b.fancybox.prev=function(){return b.fancybox.pos(p-1)};b.fancybox.pos=function(a){if(!h){a=parseInt(a);o=l;if(a>-1&&a<l.length){q=a;I()}else if(d.cyclic&&l.length>1){q=a>=l.length?0:l.length-1;I()}}};b.fancybox.cancel=function(){if(!h){h=true;b.event.trigger("fancybox-cancel");N();e.onCancel(o,q,e);h=false}};b.fancybox.close=function(){function a(){u.fadeOut("fast");n.empty().hide();f.hide();b.event.trigger("fancybox-cleanup");j.empty();d.onClosed(l,p,d);l=e=[];p=q=0;d=e={};h=false}if(!(h||f.is(":hidden"))){h=
|
||||
true;if(d&&false===d.onCleanup(l,p,d))h=false;else{N();b(E.add(z).add(A)).hide();b(j.add(u)).unbind();b(window).unbind("resize.fb scroll.fb");b(document).unbind("keydown.fb");j.find("iframe").attr("src",M&&/^https/i.test(window.location.href||"")?"javascript:void(false)":"about:blank");d.titlePosition!=="inside"&&n.empty();f.stop();if(d.transitionOut=="elastic"){r=V();var c=f.position();i={top:c.top,left:c.left,width:f.width(),height:f.height()};if(d.opacity)i.opacity=1;n.empty().hide();B.prop=1;
|
||||
b(B).animate({prop:0},{duration:d.speedOut,easing:d.easingOut,step:T,complete:a})}else f.fadeOut(d.transitionOut=="none"?0:d.speedOut,a)}}};b.fancybox.resize=function(){u.is(":visible")&&u.css("height",b(document).height());b.fancybox.center(true)};b.fancybox.center=function(a){var c,g;if(!h){g=a===true?1:0;c=U();!g&&(f.width()>c[0]||f.height()>c[1])||f.stop().animate({top:parseInt(Math.max(c[3]-20,c[3]+(c[1]-j.height()-40)*0.5-d.padding)),left:parseInt(Math.max(c[2]-20,c[2]+(c[0]-j.width()-40)*0.5-
|
||||
d.padding))},typeof a=="number"?a:200)}};b.fancybox.init=function(){if(!b("#fancybox-wrap").length){b("body").append(m=b('<div id="fancybox-tmp"></div>'),t=b('<div id="fancybox-loading"><div></div></div>'),u=b('<div id="fancybox-overlay"></div>'),f=b('<div id="fancybox-wrap"></div>'));D=b('<div id="fancybox-outer"></div>').append('<div class="fancybox-bg" id="fancybox-bg-n"></div><div class="fancybox-bg" id="fancybox-bg-ne"></div><div class="fancybox-bg" id="fancybox-bg-e"></div><div class="fancybox-bg" id="fancybox-bg-se"></div><div class="fancybox-bg" id="fancybox-bg-s"></div><div class="fancybox-bg" id="fancybox-bg-sw"></div><div class="fancybox-bg" id="fancybox-bg-w"></div><div class="fancybox-bg" id="fancybox-bg-nw"></div>').appendTo(f);
|
||||
D.append(j=b('<div id="fancybox-content"></div>'),E=b('<a id="fancybox-close"></a>'),n=b('<div id="fancybox-title"></div>'),z=b('<a href="javascript:;" id="fancybox-left"><span class="fancy-ico" id="fancybox-left-ico"></span></a>'),A=b('<a href="javascript:;" id="fancybox-right"><span class="fancy-ico" id="fancybox-right-ico"></span></a>'));E.click(b.fancybox.close);t.click(b.fancybox.cancel);z.click(function(a){a.preventDefault();b.fancybox.prev()});A.click(function(a){a.preventDefault();b.fancybox.next()});
|
||||
b.fn.mousewheel&&f.bind("mousewheel.fb",function(a,c){if(h)a.preventDefault();else if(b(a.target).get(0).clientHeight==0||b(a.target).get(0).scrollHeight===b(a.target).get(0).clientHeight){a.preventDefault();b.fancybox[c>0?"prev":"next"]()}});b.support.opacity||f.addClass("fancybox-ie");if(M){t.addClass("fancybox-ie6");f.addClass("fancybox-ie6");b('<iframe id="fancybox-hide-sel-frame" src="'+(/^https/i.test(window.location.href||"")?"javascript:void(false)":"about:blank")+'" scrolling="no" border="0" frameborder="0" tabindex="-1"></iframe>').prependTo(D)}}};
|
||||
b.fn.fancybox.defaults={padding:10,margin:40,opacity:false,modal:false,cyclic:false,scrolling:"auto",width:560,height:340,autoScale:true,autoDimensions:true,centerOnScroll:false,ajax:{},swf:{wmode:"transparent"},hideOnOverlayClick:true,hideOnContentClick:false,overlayShow:true,overlayOpacity:0.7,overlayColor:"#777",titleShow:true,titlePosition:"float",titleFormat:null,titleFromAlt:false,transitionIn:"fade",transitionOut:"fade",speedIn:300,speedOut:300,changeSpeed:300,changeFade:"fast",easingIn:"swing",
|
||||
easingOut:"swing",showCloseButton:true,showNavArrows:true,enableEscapeButton:true,enableKeyboardNav:true,onStart:function(){},onCancel:function(){},onComplete:function(){},onCleanup:function(){},onClosed:function(){},onError:function(){}};b(document).ready(function(){b.fancybox.init()})})(jQuery);
|
||||
6
js/jquery.placeholder.min.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* HTML5 Placeholder jQuery Plugin v1.8
|
||||
* @link http://github.com/mathiasbynens/Placeholder-jQuery-Plugin
|
||||
* @author Mathias Bynens <http://mathiasbynens.be/>
|
||||
*/
|
||||
(function(f){var e='placeholder' in document.createElement('input'),a='placeholder' in document.createElement('textarea');if(e&&a){f.fn.placeholder=function(){return this}}else{f.fn.placeholder=function(){return this.filter((e?'textarea':':input')+'[placeholder]').bind('focus.placeholder',b).bind('blur.placeholder',d).trigger('blur.placeholder').end()}}function c(h){var g={},i=/^jQuery\d+$/;f.each(h.attributes,function(k,j){if(j.specified&&!i.test(j.name)){g[j.name]=j.value}});return g}function b(){var g=f(this);if(g.val()===g.attr('placeholder')&&g.hasClass('placeholder')){if(g.data('placeholder-password')){g.hide().next().show().focus()}else{g.val('').removeClass('placeholder')}}}function d(i){var l,k=f(this),h=k,g=k.data('placeholder-init');if(k.val()===''||(!g&&k.val()===k.attr('placeholder'))){if(k.is(':password')){if(!k.data('placeholder-textinput')){try{l=k.clone().attr({type:'text'})}catch(j){l=f('<input>').attr(f.extend(c(k[0]),{type:'text'}))}l.removeAttr('name').data('placeholder-password',true).bind('focus.placeholder',b);k.data('placeholder-textinput',l).before(l)}k=k.hide().prev().show()}k.addClass('placeholder').val(k.attr('placeholder'))}else{k.removeClass('placeholder')}if(!g){h.data('placeholder-init',true)}}f(function(){f('form').bind('submit.placeholder',function(){var g=f('.placeholder',this).each(b);setTimeout(function(){g.each(d)},10)})});f(window).bind('unload.placeholder',function(){f('.placeholder').val('')})}(jQuery));
|
||||
16
js/libs/jquery-1.5.1.min.js
vendored
Normal file
2
js/libs/modernizr-1.7.min.js
vendored
Normal file
10
js/scripts.js
Normal file
@@ -0,0 +1,10 @@
|
||||
$(document).ready(function() {
|
||||
|
||||
// $("#cycle").cycle({
|
||||
// fx: "fade"
|
||||
// });
|
||||
|
||||
// $("dl.gallery-item a").attr("rel","gallery");
|
||||
// $("dl.gallery-item a[rel='gallery']").fancybox();
|
||||
|
||||
});
|
||||
10
loop-page.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php /* Start loop */ ?>
|
||||
<?php while (have_posts()) : the_post(); ?>
|
||||
|
||||
<?php if (function_exists('yoast_breadcrumb')) { if (is_page() && $post->post_parent) { yoast_breadcrumb('<p id="breadcrumbs">','</p>'); } } ?>
|
||||
<h1><?php the_title(); ?></h1>
|
||||
<?php the_content(); ?>
|
||||
<?php wp_link_pages(array('before' => '<nav id="page-nav"><p>' . __('Pages:', 'roots'), 'after' => '</p></nav>' )); ?>
|
||||
|
||||
<?php endwhile; // End the loop ?>
|
||||
|
||||
45
loop-search.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php /* If there are no posts to display, such as an empty archive page */ ?>
|
||||
<?php if (!have_posts()) : ?>
|
||||
<div class="notice">
|
||||
<p class="bottom">Sorry, no results were found.</p>
|
||||
</div>
|
||||
<?php get_search_form(); ?>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<?php /* Start loop */ ?>
|
||||
<?php while (have_posts()) : the_post(); ?>
|
||||
|
||||
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
|
||||
<header>
|
||||
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
|
||||
<time pubdate datetime="<?php the_time('c'); ?>">Posted on <?php the_time('l, F jS, Y') ?> at <?php the_time() ?>.</time>
|
||||
<?php if (get_option('roots_post_author') == 'checked') { ?>
|
||||
<p class="byline author vcard">
|
||||
Written by <span class="fn"><?php the_author(); ?></span>
|
||||
</p>
|
||||
<?php } ?>
|
||||
</header>
|
||||
<div class="entry-content">
|
||||
<?php if (is_archive() || is_search()) : // Only display excerpts for archives and search ?>
|
||||
<?php the_excerpt(); ?>
|
||||
<?php else : ?>
|
||||
<?php the_content('Continue…'); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<footer>
|
||||
<?php $tag = get_the_tags(); if (!$tag) { } else { ?><p><?php the_tags(); ?></p><?php } ?>
|
||||
</footer>
|
||||
</article>
|
||||
|
||||
<?php comments_template('', true); ?>
|
||||
|
||||
<?php endwhile; // End the loop ?>
|
||||
|
||||
<?php /* Display navigation to next/previous pages when applicable */ ?>
|
||||
<?php if ($wp_query->max_num_pages > 1) : ?>
|
||||
<nav id="post-nav">
|
||||
<div class="post-previous"><?php next_posts_link( __( '← Older posts', 'roots' ) ); ?></div>
|
||||
<div class="post-next"><?php previous_posts_link( __( 'Newer posts →', 'roots' ) ); ?></div>
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
28
loop-single.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php /* Start loop */ ?>
|
||||
<?php while (have_posts()) : the_post(); ?>
|
||||
|
||||
<article <?php post_class() ?> id="post-<?php the_ID(); ?>">
|
||||
<header>
|
||||
<h1 class="entry-title"><?php the_title(); ?></h1>
|
||||
<time class="updated" datetime="<?php the_time('c'); ?>" pubdate>Posted on <?php the_time('l, F jS, Y') ?> at <?php the_time() ?>.</time>
|
||||
<?php if (get_option('roots_post_author') == 'checked') { ?>
|
||||
<p class="byline author vcard">
|
||||
Written by <span class="fn"><?php the_author(); ?></span>
|
||||
</p>
|
||||
<?php } ?>
|
||||
<?php if (get_option('roots_post_tweet') == 'checked') { ?>
|
||||
<a href="http://twitter.com/share" class="twitter-share-button" data-count="horizontal">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>
|
||||
<?php } ?>
|
||||
</header>
|
||||
<div class="entry-content">
|
||||
<?php the_content('<p>Read the rest of this entry »</p>'); ?>
|
||||
</div>
|
||||
<footer>
|
||||
<?php wp_link_pages(array('before' => '<nav id="page-nav"><p>' . __('Pages:', 'roots'), 'after' => '</p></nav>' )); ?>
|
||||
<p><?php the_tags(); ?></p>
|
||||
</footer>
|
||||
<?php comments_template(); ?>
|
||||
</article>
|
||||
|
||||
<?php endwhile; // End the loop ?>
|
||||
|
||||
45
loop.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php /* If there are no posts to display, such as an empty archive page */ ?>
|
||||
<?php if (!have_posts()) : ?>
|
||||
<div class="notice">
|
||||
<p class="bottom">Sorry, no results were found.</p>
|
||||
</div>
|
||||
<?php get_search_form(); ?>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<?php /* Start loop */ ?>
|
||||
<?php while (have_posts()) : the_post(); ?>
|
||||
|
||||
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
|
||||
<header>
|
||||
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
|
||||
<time pubdate datetime="<?php the_time('c'); ?>">Posted on <?php the_time('l, F jS, Y') ?> at <?php the_time() ?>.</time>
|
||||
<?php if (get_option('roots_post_author') == 'checked') { ?>
|
||||
<p class="byline author vcard">
|
||||
Written by <span class="fn"><?php the_author(); ?></span>
|
||||
</p>
|
||||
<?php } ?>
|
||||
</header>
|
||||
<div class="entry-content">
|
||||
<?php if (is_archive() || is_search()) : // Only display excerpts for archives and search ?>
|
||||
<?php the_excerpt(); ?>
|
||||
<?php else : ?>
|
||||
<?php the_content('Continue…'); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<footer>
|
||||
<?php $tag = get_the_tags(); if (!$tag) { } else { ?><p><?php the_tags(); ?></p><?php } ?>
|
||||
</footer>
|
||||
</article>
|
||||
|
||||
<?php comments_template('', true); ?>
|
||||
|
||||
<?php endwhile; // End the loop ?>
|
||||
|
||||
<?php /* Display navigation to next/previous pages when applicable */ ?>
|
||||
<?php if ($wp_query->max_num_pages > 1) : ?>
|
||||
<nav id="post-nav">
|
||||
<div class="post-previous"><?php next_posts_link( __( '← Older posts', 'roots' ) ); ?></div>
|
||||
<div class="post-next"><?php previous_posts_link( __( 'Newer posts →', 'roots' ) ); ?></div>
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
18
page-custom.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
/*
|
||||
Template Name: Custom
|
||||
*/
|
||||
get_header(); ?>
|
||||
<div id="content" class="span-24">
|
||||
<div id="main" class="<?php echo get_option('roots_main_class'); ?>" role="main">
|
||||
<div class="container">
|
||||
<?php get_template_part('loop', 'page'); ?>
|
||||
</div>
|
||||
</div><!-- /#main -->
|
||||
<aside id="sidebar" class="<?php echo get_option('roots_sidebar_class'); ?>" role="complementary">
|
||||
<div class="container">
|
||||
<?php get_sidebar(); ?>
|
||||
</div>
|
||||
</aside><!-- /#sidebar -->
|
||||
</div><!-- /#content -->
|
||||
<?php get_footer(); ?>
|
||||
13
page-full.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
/*
|
||||
Template Name: Full Width
|
||||
*/
|
||||
get_header(); ?>
|
||||
<div id="content" class="span-24">
|
||||
<div id="main" class="span-24" role="main">
|
||||
<div class="container">
|
||||
<?php get_template_part('loop', 'page'); ?>
|
||||
</div>
|
||||
</div><!-- /#main -->
|
||||
</div><!-- /#content -->
|
||||
<?php get_footer(); ?>
|
||||
24
page-sitemap.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
Template Name: Sitemap
|
||||
*/
|
||||
get_header(); ?>
|
||||
<div id="content" class="span-24">
|
||||
<div id="main" class="<?php echo get_option('roots_main_class'); ?>" role="main">
|
||||
<div class="container">
|
||||
<?php get_template_part('loop', 'page'); ?>
|
||||
<h2>Pages</h2>
|
||||
<ul><?php wp_list_pages('sort_column=menu_order&depth=0&title_li='); ?></ul>
|
||||
<h2>Posts</h2>
|
||||
<ul><?php wp_list_categories('title_li=&hierarchical=0&show_count=1'); ?></ul>
|
||||
<h2>Archives</h2>
|
||||
<ul><?php wp_get_archives('type=monthly&limit=12'); ?></ul>
|
||||
</div>
|
||||
</div><!-- /#main -->
|
||||
<aside id="sidebar" class="<?php echo get_option('roots_sidebar_class'); ?>" role="complementary">
|
||||
<div class="container">
|
||||
<?php get_sidebar(); ?>
|
||||
</div>
|
||||
</aside><!-- /#sidebar -->
|
||||
</div><!-- /#content -->
|
||||
<?php get_footer(); ?>
|
||||
25
page-subpages.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/*
|
||||
Template Name: List Subpages
|
||||
*/
|
||||
get_header(); ?>
|
||||
<div id="content" class="span-24">
|
||||
<div id="main" class="<?php echo get_option('roots_main_class'); ?>" role="main">
|
||||
<div class="container">
|
||||
<?php get_template_part('loop', 'page'); ?>
|
||||
<?php
|
||||
$children = wp_list_pages('title_li=&child_of='.$post->ID.'&echo=0');
|
||||
if ($children) { ?>
|
||||
<ul>
|
||||
<?php echo $children; ?>
|
||||
</ul>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div><!-- /#main -->
|
||||
<aside id="sidebar" class="<?php echo get_option('roots_sidebar_class'); ?>" role="complementary">
|
||||
<div class="container">
|
||||
<?php get_sidebar(); ?>
|
||||
</div>
|
||||
</aside><!-- /#sidebar -->
|
||||
</div><!-- /#content -->
|
||||
<?php get_footer(); ?>
|
||||
14
page.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php get_header(); ?>
|
||||
<div id="content" class="span-24">
|
||||
<div id="main" class="<?php echo get_option('roots_main_class'); ?>" role="main">
|
||||
<div class="container">
|
||||
<?php get_template_part('loop', 'page'); ?>
|
||||
</div>
|
||||
</div><!-- /#main -->
|
||||
<aside id="sidebar" class="<?php echo get_option('roots_sidebar_class'); ?>" role="complementary">
|
||||
<div class="container">
|
||||
<?php get_sidebar(); ?>
|
||||
</div>
|
||||
</aside><!-- /#sidebar -->
|
||||
</div><!-- /#content -->
|
||||
<?php get_footer(); ?>
|
||||
BIN
screenshot.png
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
15
search.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php get_header(); ?>
|
||||
<div id="content" class="span-24">
|
||||
<div id="main" class="<?php echo get_option('roots_main_class'); ?>">
|
||||
<div class="container">
|
||||
<h1>Search Results for <?php echo get_search_query(); ?></h1>
|
||||
<?php get_template_part('loop', 'search'); ?>
|
||||
</div>
|
||||
</div><!-- /#main -->
|
||||
<aside id="sidebar" class="<?php echo get_option('roots_sidebar_class'); ?>" role="complementary">
|
||||
<div class="container">
|
||||
<?php get_sidebar(); ?>
|
||||
</div>
|
||||
</aside><!-- /#sidebar -->
|
||||
</div><!-- /#content -->
|
||||
<?php get_footer(); ?>
|
||||
5
searchform.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<form role="search" method="get" id="searchform" action="<?php echo home_url('/'); ?>">
|
||||
<label class="screen-reader-text" for="s">Search for:</label>
|
||||
<input type="search" value="" name="s" id="s" placeholder="Search <?php bloginfo('name'); ?>">
|
||||
<input type="submit" id="searchsubmit" value="Search" class="button">
|
||||
</form>
|
||||
3
sidebar.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar("Sidebar") ) : ?>
|
||||
|
||||
<?php endif; ?>
|
||||
14
single.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php get_header(); ?>
|
||||
<div id="content" class="span-24">
|
||||
<div id="main" class="<?php echo get_option('roots_main_class'); ?>" role="main">
|
||||
<div class="container">
|
||||
<?php get_template_part('loop', 'single'); ?>
|
||||
</div>
|
||||
</div><!-- /#main -->
|
||||
<aside id="sidebar" class="<?php echo get_option('roots_sidebar_class'); ?>" role="complementary">
|
||||
<div class="container">
|
||||
<?php get_sidebar(); ?>
|
||||
</div>
|
||||
</aside><!-- /#sidebar -->
|
||||
</div><!-- /#content -->
|
||||
<?php get_footer(); ?>
|
||||
34
style.css
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
Theme Name: Roots
|
||||
Theme URI: http://www.rootstheme.com/
|
||||
Description: Starting theme based on HTML5 Boilerplate, Blueprint CSS and Starkers
|
||||
Version: 3.0.0
|
||||
Author: Ben Word
|
||||
Author URI: http://benword.com/
|
||||
Tags: roots, boilerplate, blueprint, starkers
|
||||
|
||||
License: The Unlicense
|
||||
License URI: http://unlicense.org/
|
||||
|
||||
Updated: March 28 2011
|
||||
|
||||
Changelog:
|
||||
3.0.0 [03-28-2011] Changed name from BB to Roots, updated various areas to match the latest changes to HTML5 Boilerplate, changed the theme
|
||||
markup based on hCard/Readability Guidelines and work by Jonathan Neal, theme activation now creates the navigation menus and
|
||||
automatically sets their locations, permalink structure is now set to /%year%/%postname%/ for performance reasons, uploads
|
||||
folder is now /assets/ and not organized by month and date, all static folders in /wp-content/themes/roots/ (css/, js/, img/)
|
||||
now rewrite to the root (/css/, /js/, /img/), /wp-content/plugins/ now rewrites to /plugins/, more root relative URLs on
|
||||
WordPress functions, search results (/?s=query) now rewrites to /search/query/, l10n.js is deregistered, gallery shortcode has
|
||||
been changed to output <figure> and <figcaption> and now links to the file by default, added more loop.php templates, made the
|
||||
HTML editor have a monospaced font, added front-page.php, updated CSS for Gravity Forms 1.5, added searchform.php template
|
||||
2.4.0 [01-25-2011] Added a notification when saving the theme settings, added support for navigation menus, created function that makes sure there
|
||||
is a Home page on theme activation, updated various areas to match the latest changes to HTML5 Boilerplate
|
||||
2.3.0 [12-08-2010] Logo is no longer an <h1>, added ARIA roles again, changed ul#nav to nav#nav-main, added vCard to footer, made all URL's root
|
||||
relative, added Twitter and Facebook widgets to footer, added SEO optimized robots.txt from WordPress codex
|
||||
2.2.0 [09-20-2010] Added asynchronous Google Analytics, updated .htaccess with latest changes from HTML5 Boilerplate
|
||||
2.1.0 [08-19-2010] Removed optimizeLegibility from headings, updated jQuery to latest version, implemented HTML5 Boilerplate .htaccess
|
||||
2.0.1 [08-02-2010] Added some presentational CSS classes, added footer widget, more Gravity Forms default styling
|
||||
2.0.0 [07-19-2010] Added HTML5 Boilerplate changes, implemented loop.php, wp_head cleanup, added page-subpages.php template
|
||||
1.5.0 [04-15-2010] Integrated Paul Irish's frontend-pro-template (the original HTML5 Boilerplate)
|
||||
1.0.0 [12-18-2009] Added Blueprint CSS to Starkers
|
||||
*/
|
||||