From e159b846846f9701e1c3f671e7514130f9b3606c Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Mon, 10 Feb 2014 21:28:44 -0500 Subject: [PATCH 01/35] First pass at nginx support - Automatic detection of whether Docs directories are protected from direct file download - Automatic server detection - Swap out attachment URLs for links to download script when protection is enabled See #378 --- includes/attachments.php | 189 +++++++++++++++++++++++++++++++++++++- includes/templatetags.php | 56 +++++++++-- 2 files changed, 233 insertions(+), 12 deletions(-) diff --git a/includes/attachments.php b/includes/attachments.php index b7136ef4..0cf18cc7 100644 --- a/includes/attachments.php +++ b/includes/attachments.php @@ -13,9 +13,10 @@ function __construct() { } add_action( 'template_redirect', array( $this, 'catch_attachment_request' ), 20 ); + add_filter( 'redirect_canonical', array( $this, 'redirect_canonical' ), 10, 2 ); add_filter( 'upload_dir', array( $this, 'filter_upload_dir' ) ); add_action( 'bp_docs_doc_saved', array( $this, 'check_privacy' ) ); - add_filter( 'wp_handle_upload_prefilter', array( $this, 'maybe_create_htaccess' ) ); + add_filter( 'wp_handle_upload_prefilter', array( $this, 'maybe_create_rewrites' ) ); add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); add_action( 'pre_get_posts', array( $this, 'filter_gallery_posts' ) ); @@ -35,6 +36,9 @@ function __construct() { // Ensure that all logged-in users have the 'upload_files' cap add_filter( 'map_meta_cap', array( __CLASS__, 'map_meta_cap' ), 10, 4 ); + // Admin notice about directory accessibility + add_action( 'admin_init', array( $this, 'admin_notice_init' ) ); + require( dirname( __FILE__ ) . '/attachments-ajax.php' ); } @@ -85,6 +89,23 @@ function catch_attachment_request() { } } + /** + * If redirecting from a 'p' URL to a rewritten URL, retain 'bp-attachment' param + * + * @since 1.6.0 + * + * @param string $redirect_url URL as calculated by redirect_canonical + * @param string $requested_url Originally requested URL. + * @return string + */ + public function redirect_canonical( $redirect_url, $requested_url ) { + if ( isset( $_GET['p'] ) && isset( $_GET['bp-attachment'] ) && false !== strpos( $requested_url, 'bp-attachments' ) ) { + $redirect_url = add_query_arg( 'bp-attachment', $_GET['bp-attachment'], $redirect_url ); + } + + return $redirect_url; + } + /** * Attempts to customize upload_dir with our attachment paths * @@ -146,12 +167,38 @@ public function delete_htaccess() { } /** - * Creates an .htaccess file in the appropriate upload dir, if appropriate + * Create rewrite rules for upload directory, if appropriate. * * As a hack, we've hooked to wp_handle_upload_prefilter. We don't * actually do anything with the passed value; we just need a place * to hook in reliably before the file is written. * + * @since 1.6.0 + * + * @param $file + * @return $file + */ + public function maybe_create_rewrites( $file ) { + global $is_apache, $is_nginx; + + if ( ! $this->get_doc_id() ) { + return $file; + } + + if ( ! $this->get_is_private() ) { + return $file; + } + + if ( $is_apache ) { + $this->create_htaccess(); + } + + return $file; + } + + /** + * Creates an .htaccess file in the appropriate upload dir, if appropriate + * * @since 1.4 * @param $file * @return $file @@ -621,6 +668,137 @@ public static function map_meta_cap_supp( $caps, $cap, $user_id, $args ) { return array( 'exist' ); } + + public function admin_notice_init() { + if ( ! current_user_can( 'delete_users' ) ) { + return; + } + + // If the notice is being disabled, mark it as such and bail + if ( isset( $_GET['bpdocs-disable-attachment-notice'] ) ) { + check_admin_referer( 'bpdocs-disable-attachment-notice' ); + bp_update_option( 'bp_docs_disable_attachment_notice', 1 ); + return; + } + + // If the notice has already been disabled, bail + if ( 1 == bp_get_option( 'bp_docs_disable_attachment_notice' ) ) { + return; + } + + // Nothing to see here + if ( $this->check_is_protected() ) { + return; + } + + add_action( 'admin_notices', array( $this, 'admin_notice' ) ); + } + + public function admin_notice() { + global $is_apache, $is_nginx, $is_IIS, $is_iis7; + + $dismiss_url = add_query_arg( 'bpdocs-disable-attachment-notice', '1', $_SERVER['REQUEST_URI'] ); + $dismiss_url = wp_nonce_url( $dismiss_url, 'bpdocs-disable-attachment-notice' ); + + if ( $is_nginx ) { + $help_url = 'https://github.com/boonebgorges/buddypress-docs/wiki/Attachment-Privacy#wiki-nginx'; + + $help_p = __( 'It looks like you are running nginx. We recommend the following setting in your site configuration file:', 'bp-docs' ); + $help_p .= '
location /wp-content/uploads/bp-attachments/ {
+    rewrite ^.*uploads/bp-attachments/([0-9]+)/(.*) /?p=$1&bp-attachment=$2 permanent;
+}
+
'; + } + + ?> + +
+

Your BuddyPress Docs attachments directory is publicly accessible. Doc attachments will not be properly protected from direct viewing, even if the parent Docs are non-public.', 'bp-docs' ) ?>

+ + +

+ + + +

this wiki page for more information.', 'bp-docs' ), $help_url ) ?>

+ + +

+
+ doc_id = 0; + + $rules = array( + 'RewriteEngine On', + 'RewriteBase /', + 'RewriteRule (.+) ?bp-attachment=$1 [R=302,NC]', + ); + + if ( ! empty( $rules ) ) { + if ( ! file_exists( 'insert_with_markers' ) ) { + require_once( ABSPATH . 'wp-admin/includes/misc.php' ); + } + insert_with_markers( $test_dir . DIRECTORY_SEPARATOR . '.htaccess', 'BuddyPress Docs', $rules ); + } + } + + // Make a dummy file + file_put_contents( $test_dir . DIRECTORY_SEPARATOR . 'test.txt', $test_text ); + } + + $test_url = $uploads['baseurl'] . '/bp-attachments/0/test.txt'; + $r = wp_remote_get( $test_url ); + + // If the response body includes our test text, we have a problem + $is_protected = true; + if ( $r['body'] === $test_text ) { + $is_protected = false; + } + + // Cache + $cache = $is_protected ? '1' : '0'; + bp_update_option( 'bp_docs_attachment_protection', $cache ); + + return $is_protected; + } } /** @@ -633,3 +811,10 @@ function bp_docs_enable_attachments() { $enabled = get_option( 'bp-docs-enable-attachments', 'yes' ); return apply_filters( 'bp_docs_enable_attachments', 'yes' === $enabled ); } + +/** + * Are attachment downloads protected? + */ +function bp_docs_attachment_protection( $force_check = false ) { + return buddypress()->bp_docs->attachments->check_is_protected( $force_check ); +} diff --git a/includes/templatetags.php b/includes/templatetags.php index 6dd91477..570f4463 100644 --- a/includes/templatetags.php +++ b/includes/templatetags.php @@ -1922,20 +1922,56 @@ function bp_docs_get_doc_attachments( $doc_id = null ) { return apply_filters( 'bp_docs_get_doc_attachments', $atts, $doc_id ); } +/** + * Get the URL for an attachment download. + * + * Is sensitive to whether Docs can be directly downloaded. + * + * @param int $attachment_id + */ +function bp_docs_attachment_url( $attachment_id ) { + echo bp_docs_get_attachment_url( $attachment_id ); +} + /** + * Get the URL for an attachment download. + * + * Is sensitive to whether Docs can be directly downloaded. + * + * @param int $attachment_id + */ + function bp_docs_get_attachment_url( $attachment_id ) { + $attachment = get_post( $attachment_id ); + + if ( bp_docs_attachment_protection() ) { + $attachment = get_post( $attachment_id ); + $att_data = wp_get_attachment_metadata( $attachment_id ); + $att_base = basename( $att_data['file'] ); + $doc_url = bp_docs_get_doc_link( $attachment->post_parent ); + $att_url = add_query_arg( 'bp-attachment', $att_base, $doc_url ); + } else { + $att_url = wp_get_attachment_url( $attachment_id ); + } + + return apply_filters( 'bp_docs_attachment_url_base', $att_url, $attachment ); + } + + // @todo make
  • optional? function bp_docs_attachment_item_markup( $attachment_id, $format = 'full' ) { $markup = ''; + $att_url = bp_docs_get_attachment_url( $attachment_id ); + $attachment = get_post( $attachment_id ); - $attachment_url = apply_filters( 'bp_docs_attachment_url_base', wp_get_attachment_url( $attachment->ID ), $attachment ); + $att_data = wp_get_attachment_metadata( $attachment_id ); + $att_base = basename( $att_data['file'] ); + $doc_url = bp_docs_get_doc_link( $attachment->post_parent ); - $attachment_ext = preg_replace( '/^.+?\.([^.]+)$/', '$1', $attachment_url ); - $attachment_filename = basename( $attachment_url ); + $attachment_ext = preg_replace( '/^.+?\.([^.]+)$/', '$1', $att_url ); if ( 'full' === $format ) { $attachment_delete_html = ''; if ( bp_docs_current_user_can( 'edit' ) && ( bp_docs_is_doc_edit() || bp_docs_is_doc_create() ) ) { - $doc_url = bp_docs_get_doc_link( $attachment->post_parent ); $attachment_delete_url = wp_nonce_url( $doc_url, 'bp_docs_delete_attachment_' . $attachment_id ); $attachment_delete_url = add_query_arg( array( 'delete_attachment' => $attachment_id, @@ -1951,18 +1987,18 @@ function bp_docs_attachment_item_markup( $attachment_id, $format = 'full' ) { '
  • %s%s
  • ', $attachment_id, $attachment_ext, - $attachment_url, - esc_attr( $attachment_filename ), - esc_html( $attachment_filename ), + $att_url, + esc_attr( $att_base ), + esc_html( $att_base ), $attachment_delete_html ); } else { $markup = sprintf( '
  • %s
  • ', $attachment_id, - $attachment_url, - esc_attr( $attachment_filename ), - esc_html( $attachment_filename ) + $att_url, + esc_attr( $att_base ), + esc_html( $att_base ) ); } From 9909b1605d24dd112b5a9d6e254ec1c83a3bb040 Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Mon, 10 Mar 2014 15:52:24 -0400 Subject: [PATCH 02/35] Use get_attached_file() to build URLs for attachments. See e159b --- includes/templatetags.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/includes/templatetags.php b/includes/templatetags.php index 570f4463..6d5a2e86 100644 --- a/includes/templatetags.php +++ b/includes/templatetags.php @@ -1944,8 +1944,7 @@ function bp_docs_get_attachment_url( $attachment_id ) { if ( bp_docs_attachment_protection() ) { $attachment = get_post( $attachment_id ); - $att_data = wp_get_attachment_metadata( $attachment_id ); - $att_base = basename( $att_data['file'] ); + $att_base = basename( get_attached_file( $attachment_id ) ); $doc_url = bp_docs_get_doc_link( $attachment->post_parent ); $att_url = add_query_arg( 'bp-attachment', $att_base, $doc_url ); } else { @@ -1963,8 +1962,7 @@ function bp_docs_attachment_item_markup( $attachment_id, $format = 'full' ) { $att_url = bp_docs_get_attachment_url( $attachment_id ); $attachment = get_post( $attachment_id ); - $att_data = wp_get_attachment_metadata( $attachment_id ); - $att_base = basename( $att_data['file'] ); + $att_base = basename( get_attached_file( $attachment_id ) ); $doc_url = bp_docs_get_doc_link( $attachment->post_parent ); $attachment_ext = preg_replace( '/^.+?\.([^.]+)$/', '$1', $att_url ); From e125ff40319e10a4c262d58ca6fb98287a83dbaf Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Mon, 10 Mar 2014 15:54:53 -0400 Subject: [PATCH 03/35] Test document for attachment access should be .html, not .txt Should provide broader support across environments --- includes/attachments.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/attachments.php b/includes/attachments.php index 0cf18cc7..75188f02 100644 --- a/includes/attachments.php +++ b/includes/attachments.php @@ -781,10 +781,10 @@ public function check_is_protected( $force_check = true ) { } // Make a dummy file - file_put_contents( $test_dir . DIRECTORY_SEPARATOR . 'test.txt', $test_text ); + file_put_contents( $test_dir . DIRECTORY_SEPARATOR . 'test.html', $test_text ); } - $test_url = $uploads['baseurl'] . '/bp-attachments/0/test.txt'; + $test_url = $uploads['baseurl'] . '/bp-attachments/0/test.html'; $r = wp_remote_get( $test_url ); // If the response body includes our test text, we have a problem From 850f48337d8fa7d3a598427e0c35d316c10a2d8c Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Mon, 10 Mar 2014 16:18:51 -0400 Subject: [PATCH 04/35] No-access redirect to wp-login.php --- bp-docs.php | 30 +++++------------------------- includes/attachments.php | 2 +- 2 files changed, 6 insertions(+), 26 deletions(-) diff --git a/bp-docs.php b/bp-docs.php index f4c08202..83fa7388 100644 --- a/bp-docs.php +++ b/bp-docs.php @@ -541,32 +541,12 @@ function protect_doc_access() { } if ( ! bp_docs_current_user_can( $action ) ) { - $redirect_to = wp_get_referer(); + $redirect_to = wp_login_url( bp_docs_get_doc_link() ); - if ( ! $redirect_to || trailingslashit( $redirect_to ) == trailingslashit( wp_guess_url() ) ) { - $redirect_to = bp_get_root_domain(); - } - - switch ( $action ) { - case 'read' : - $message = __( 'You are not allowed to read that Doc.', 'bp-docs' ); - break; - - case 'create' : - $message = __( 'You are not allowed to create Docs.', 'bp-docs' ); - break; - - case 'edit' : - $message = __( 'You are not allowed to edit that Doc.', 'bp-docs' ); - break; - - case 'view_history' : - $message = __( 'You are not allowed to view that Doc\'s history.', 'bp-docs' ); - break; - } - - bp_core_add_message( $message, 'error' ); - bp_core_redirect( $redirect_to ); + bp_core_no_access( array( + 'mode' => 2, + 'redirect' => $redirect_to, + ) ); } } diff --git a/includes/attachments.php b/includes/attachments.php index 75188f02..baad74e7 100644 --- a/includes/attachments.php +++ b/includes/attachments.php @@ -752,7 +752,7 @@ public function check_is_protected( $force_check = true ) { $uploads = wp_upload_dir(); $test_dir = $uploads['basedir'] . DIRECTORY_SEPARATOR . 'bp-attachments' . DIRECTORY_SEPARATOR . '0'; - $test_file_dir = $test_dir . DIRECTORY_SEPARATOR . 'test.txt'; + $test_file_dir = $test_dir . DIRECTORY_SEPARATOR . 'test.html'; $test_text = 'This is a test of the Protected Attachment feature of BuddyPress Docs. Please do not remove.'; if ( ! file_exists( $test_file_dir ) ) { From 07e5347f0e981624495737100b4d3a19bb61c1d3 Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Tue, 11 Mar 2014 11:07:22 -0400 Subject: [PATCH 05/35] Don't use DIRECTORY_SEPARATOR to filter upload directory The value of DIRECTORY_SEPARATOR in IIS is '\', which is the MySQL escape character. As such, it was not being written properly to the database when recording _wp_attached_file and wp_attachment_metadata postmeta, resulting in malformed attachment URLs. By using '/' across platforms, we allow IIS to do its own internal path translations. See #363 Props @dcavins --- includes/attachments.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/attachments.php b/includes/attachments.php index baad74e7..0e6b71e3 100644 --- a/includes/attachments.php +++ b/includes/attachments.php @@ -370,7 +370,7 @@ public static function get_doc_id_from_url( $url ) { * @return array $uploads */ function mod_upload_dir( $uploads ) { - $subdir = DIRECTORY_SEPARATOR . 'bp-attachments' . DIRECTORY_SEPARATOR . $this->doc_id; + $subdir = '/bp-attachments/' . $this->doc_id; $uploads['subdir'] = $subdir; $uploads['path'] = $uploads['basedir'] . $subdir; From ebc751e870896fc5c7fc6bcb851d61651f35865e Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Tue, 11 Mar 2014 11:17:15 -0400 Subject: [PATCH 06/35] Backward compatibility fix for existing IIS URLs. See #363 --- includes/templatetags.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/includes/templatetags.php b/includes/templatetags.php index 6d5a2e86..9c64fff8 100644 --- a/includes/templatetags.php +++ b/includes/templatetags.php @@ -1951,6 +1951,10 @@ function bp_docs_get_attachment_url( $attachment_id ) { $att_url = wp_get_attachment_url( $attachment_id ); } + // Backward compatibility: fix IIS URLs that were broken by a + // previous implementation + $att_url = preg_replace( '|bp\-attachments([0-9])|', 'bp-attachments/$1', $att_url ); + return apply_filters( 'bp_docs_attachment_url_base', $att_url, $attachment ); } From 6b2bd624c4454b8db2fb1d1ca305375651b78ee7 Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Tue, 11 Mar 2014 13:21:55 -0400 Subject: [PATCH 07/35] Coding standards --- includes/addon-taxonomy.php | 76 +++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 36 deletions(-) diff --git a/includes/addon-taxonomy.php b/includes/addon-taxonomy.php index 2a6929f7..53d536a3 100644 --- a/includes/addon-taxonomy.php +++ b/includes/addon-taxonomy.php @@ -110,7 +110,7 @@ function register_taxonomy() { function register_with_post_type() { $this->taxonomies = array( /* 'category', */ $this->docs_tag_tax_name ); - foreach( $this->taxonomies as $tax ) { + foreach ( $this->taxonomies as $tax ) { register_taxonomy_for_object_type( $tax, bp_docs_get_post_type_name() ); } } @@ -125,7 +125,7 @@ function register_with_post_type() { * @return int $post_id Returns the doc's post_id on success */ function save_post( $query ) { - foreach( $this->taxonomies as $tax_name ) { + foreach ( $this->taxonomies as $tax_name ) { if ( $tax_name == 'category' ) $tax_name = 'post_category'; @@ -154,7 +154,6 @@ function save_post( $query ) { // Store these terms in the item term cache, to be used for tag clouds etc $this->cache_terms_for_item( $terms, $query->doc_id ); - } do_action( 'bp_docs_taxonomy_saved', $query ); @@ -180,11 +179,11 @@ function delete_post( $new_status, $old_status, $post ) { $doc_id = $post->ID; // Terms for the item (group, user, etc) - $item_terms = $this->get_item_terms(); + $item_terms = $this->get_item_terms(); // Terms for the doc - $doc_terms = wp_get_post_terms( $doc_id, $this->docs_tag_tax_name ); + $doc_terms = wp_get_post_terms( $doc_id, $this->docs_tag_tax_name ); - foreach( $doc_terms as $doc_term ) { + foreach ( $doc_terms as $doc_term ) { $term_name = $doc_term->name; // If the term is currently used (should always be true - this is a @@ -212,21 +211,21 @@ function delete_post( $new_status, $old_status, $post ) { * @since 1.0-beta */ function show_terms() { - foreach( $this->taxonomies as $tax_name ) { + foreach ( $this->taxonomies as $tax_name ) { $html = ''; - $tagtext = array(); - $tags = wp_get_post_terms( get_the_ID(), $tax_name ); + $tagtext = array(); + $tags = wp_get_post_terms( get_the_ID(), $tax_name ); - foreach( $tags as $tag ) { - $tagtext[] = bp_docs_get_tag_link( array( 'tag' => $tag->name ) ); - } + foreach ( $tags as $tag ) { + $tagtext[] = bp_docs_get_tag_link( array( 'tag' => $tag->name ) ); + } if ( ! empty( $tagtext ) ) { $html = '

    ' . sprintf( __( 'Tags: %s', 'bp-docs' ), implode( ', ', $tagtext ) ) . '

    '; } - echo apply_filters( 'bp_docs_taxonomy_show_terms', $html, $tagtext ); - } + echo apply_filters( 'bp_docs_taxonomy_show_terms', $html, $tagtext ); + } } /** @@ -269,10 +268,10 @@ function cache_terms_for_item( $terms = array(), $doc_id ) { if ( empty( $docs ) ) { // If there are no more docs associated with the term, we can remove // it from the array - unset( $existing_terms[$existing_term] ); + unset( $existing_terms[ $existing_term ] ); } else { // Othewise, store the docs back in the existing terms array - $existing_terms[$existing_term] = $docs; + $existing_terms[ $existing_term ] = $docs; } } @@ -322,23 +321,24 @@ function save_item_terms( $terms ) { function modify_tax_query( $tax_query ) { // Check for the existence tag filters in the request URL - if ( !empty( $_REQUEST['bpd_tag'] ) ) { + if ( ! empty( $_REQUEST['bpd_tag'] ) ) { // The bpd_tag argument may be comma-separated $tags = explode( ',', urldecode( $_REQUEST['bpd_tag'] ) ); // Clean up the tag input - foreach( $tags as $key => $value ) { + foreach ( $tags as $key => $value ) { $tags[$key] = esc_attr( $value ); } $tax_query[] = array( 'taxonomy' => $this->docs_tag_tax_name, 'terms' => $tags, - 'field' => 'slug' + 'field' => 'slug', ); - if ( !empty( $_REQUEST['bool'] ) && $_REQUEST['bool'] == 'and' ) + if ( !empty( $_REQUEST['bool'] ) && $_REQUEST['bool'] == 'and' ) { $tax_query['operator'] = 'AND'; + } } return apply_filters( 'bp_docs_modify_tax_query_for_tax', $tax_query ); @@ -367,11 +367,11 @@ function tags_th() { */ function tags_td() { - $tags = get_the_terms( get_the_ID(), $this->docs_tag_tax_name ); - $tagtext = array(); + $tags = get_the_terms( get_the_ID(), $this->docs_tag_tax_name ); + $tagtext = array(); - foreach( (array)$tags as $tag ) { - if ( !empty( $tag->name ) ) { + foreach ( (array) $tags as $tag ) { + if ( ! empty( $tag->name ) ) { $tagtext[] = bp_docs_get_tag_link( array( 'tag' => $tag->name ) ); } } @@ -399,10 +399,10 @@ function tags_td() { function info_header_message( $message, $filters ) { $this->current_filters = $filters; - if ( !empty( $filters['tags'] ) ) { + if ( ! empty( $filters['tags'] ) ) { $tagtext = array(); - foreach( $filters['tags'] as $tag ) { + foreach ( $filters['tags'] as $tag ) { $tagtext[] = bp_docs_get_tag_link( array( 'tag' => $tag ) ); } @@ -436,8 +436,8 @@ function filter_markup() {
      - - $posts ) : ?> + + $posts ) : ?>
    • @@ -474,10 +474,10 @@ function filter_markup() { * @since 1.0-beta */ function handle_filters( $redirect_url ) { - if ( !empty( $_POST['filter_terms'] ) ) { + if ( ! empty( $_POST['filter_terms'] ) ) { $tags = array(); - foreach( $_POST['filter_terms'] as $term => $value ) { + foreach ( $_POST['filter_terms'] as $term => $value ) { $tags[] = urlencode( $term ); } @@ -512,7 +512,7 @@ function bp_docs_get_tag_link( $args = array() ) { $defaults = array( 'tag' => false, - 'type' => 'html' + 'type' => 'html', ); $r = wp_parse_args( $args, $defaults ); @@ -543,15 +543,19 @@ function bp_docs_post_tags_meta_box() { require_once(ABSPATH . '/wp-admin/includes/taxonomy.php'); - $defaults = array('taxonomy' => $bp->bp_docs->docs_tag_tax_name); - if ( !isset($box['args']) || !is_array($box['args']) ) + $defaults = array( + 'taxonomy' => $bp->bp_docs->docs_tag_tax_name, + ); + + if ( ! isset( $box['args'] ) || !is_array( $box['args'] ) ) $args = array(); else $args = $box['args']; - extract( wp_parse_args($args, $defaults), EXTR_SKIP ); - $tax_name = esc_attr($taxonomy); - $taxonomy = get_taxonomy($taxonomy); + extract( wp_parse_args( $args, $defaults ), EXTR_SKIP ); + + $tax_name = esc_attr( $taxonomy ); + $taxonomy = get_taxonomy( $taxonomy ); $terms = bp_docs_is_existing_doc() ? get_terms_to_edit( get_the_ID(), $bp->bp_docs->docs_tag_tax_name ) : ''; ?> From 7fa93d0c318c64e25471139702c47e7b0b453ee1 Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Tue, 11 Mar 2014 14:19:13 -0400 Subject: [PATCH 08/35] Overhaul user- and group-specific tag cloud treatment Previously, these items had been cached in groupmeta/usermeta, and then reassembled when the page was loaded. This process was complex and full of bugs, to the extent that it didn't work with users at all. The new technique involves using WP_Query to pull up associated documents inline, rather than attempting to cache them. This technique is more reliable, and shouldn't cause overhead, since the same queries need to be performed later on the directory page anyway (and are thus non-persistently cached by WP). See #379 Props @dcavins for an initial patch --- includes/addon-taxonomy.php | 70 ------------------------- includes/integration-groups.php | 92 +++++++++++++++++++++++---------- includes/integration-users.php | 56 +++++++++++++++----- includes/query-builder.php | 11 +++- 4 files changed, 117 insertions(+), 112 deletions(-) diff --git a/includes/addon-taxonomy.php b/includes/addon-taxonomy.php index 53d536a3..b6204518 100644 --- a/includes/addon-taxonomy.php +++ b/includes/addon-taxonomy.php @@ -151,9 +151,6 @@ function save_post( $query ) { } wp_set_post_terms( $query->doc_id, $terms, $tax_name ); - - // Store these terms in the item term cache, to be used for tag clouds etc - $this->cache_terms_for_item( $terms, $query->doc_id ); } do_action( 'bp_docs_taxonomy_saved', $query ); @@ -200,8 +197,6 @@ function delete_post( $new_status, $old_status, $post ) { } } } - - $this->save_item_terms( $item_terms ); } /** @@ -228,57 +223,6 @@ function show_terms() { } } - /** - * Store taxonomy terms and their use count for a given item - * - * @package BuddyPress Docs - * @since 1.0-beta - * - * @param array $terms The terms submitted in the most recent save - * @param int $doc_id The unique id of the doc - */ - function cache_terms_for_item( $terms = array(), $doc_id ) { - $existing_terms = $this->get_item_terms(); - - // First, make sure that each submitted term is recorded - foreach ( $terms as $term ) { - if ( empty( $existing_terms[$term] ) || ! is_array( $existing_terms[$term] ) ) - $existing_terms[$term] = array(); - - if ( ! in_array( $doc_id, $existing_terms[$term] ) ) - $existing_terms[$term][] = $doc_id; - } - - // Then, loop through to see if any existing terms have been deleted - foreach ( $existing_terms as $existing_term => $docs ) { - // If the existing term is not in the list of submitted terms... - if ( ! in_array( $existing_term, $terms ) ) { - // ... check to see whether the current doc is listed under that - // term. If so, that indicates that the term has been removed from - // the doc - $key = array_search( $doc_id, $docs ); - if ( $key !== false ) { - unset( $docs[$key] ); - } - } - - // Reset the array keys for the term's docs - $docs = array_values( $docs ); - - if ( empty( $docs ) ) { - // If there are no more docs associated with the term, we can remove - // it from the array - unset( $existing_terms[ $existing_term ] ); - } else { - // Othewise, store the docs back in the existing terms array - $existing_terms[ $existing_term ] = $docs; - } - } - - // Save the terms back to the item - $this->save_item_terms( $existing_terms ); - } - /** * Gets the list of terms used by an item's docs * @@ -441,20 +385,6 @@ function filter_markup() {
    • - - - current_filters ) || ( !empty( $this->current_filters['tags'] ) && in_array( $term, $this->current_filters['tags'] ) ) ? true : false; - - ?> - - */ ?>
    • diff --git a/includes/integration-groups.php b/includes/integration-groups.php index afce5810..3fc0d3eb 100644 --- a/includes/integration-groups.php +++ b/includes/integration-groups.php @@ -43,7 +43,6 @@ function __construct() { // Taxonomy helpers add_filter( 'bp_docs_taxonomy_get_item_terms', array( $this, 'get_group_terms' ) ); - add_action( 'bp_docs_taxonomy_save_item_terms', array( $this, 'save_group_terms' ) ); // Filter the core user_can_edit function for group-specific functionality add_filter( 'bp_docs_user_can', array( $this, 'user_can' ), 10, 4 ); @@ -176,19 +175,40 @@ function get_current_view( $view, $item_type ) { */ function pre_query_args( $query_args, $bp_docs_query ) { if ( ! empty( $bp_docs_query->query_args['group_id'] ) ) { - $terms = array(); - foreach ( (array) $bp_docs_query->query_args['group_id'] as $gid ) { - $terms[] = bp_docs_get_term_slug_from_group_id( $gid ); - } - $query_args['tax_query'][] = array( - 'taxonomy' => bp_docs_get_associated_item_tax_name(), - 'field' => 'slug', - 'terms' => $terms, - ); + $query_args['tax_query'][] = self::tax_query_arg_for_groups( $bp_docs_query->query_args['group_id'] ); } return $query_args; } + /** + * Generate the tax_query param for limiting to groups. + * + * @since 1.6.0 + * + * @param int|array $group_ids IDs of groups. + * @return array + */ + public static function tax_query_arg_for_groups( $group_ids ) { + $group_ids = wp_parse_id_list( $group_ids ); + + $terms = array(); + foreach ( $group_ids as $gid ) { + $terms[] = bp_docs_get_term_slug_from_group_id( $gid ); + } + + if ( empty( $terms ) ) { + $terms = array( 0 ); + } + + $arg = array( + 'taxonomy' => bp_docs_get_associated_item_tax_name(), + 'field' => 'slug', + 'terms' => $terms, + ); + + return $arg; + } + /** * Gets the list of terms used by a group's docs * @@ -212,11 +232,39 @@ function get_group_terms( $terms = array() ) { } } - if ( $group_id ) { - $terms = groups_get_groupmeta( $group_id, 'bp_docs_terms' ); + if ( ! $group_id ) { + return $terms; + } - if ( empty( $terms ) ) - $terms = array(); + $query_args = array( + 'post_type' => bp_docs_get_post_type_name(), + 'update_meta_cache' => false, + 'update_term_cache' => true, + 'showposts' => '-1', + 'posts_per_page' => '-1', + 'tax_query' => array( + self::tax_query_arg_for_groups( $group_id ), + ), + ); + + $group_doc_query = new WP_Query( $query_args ); + + $terms = array(); + foreach ( $group_doc_query->posts as $p ) { + $p_terms = wp_get_post_terms( $p->ID, buddypress()->bp_docs->docs_tag_tax_name ); + foreach ( $p_terms as $p_term ) { + if ( ! isset( $terms[ $p_term->name ] ) ) { + $terms[ $p_term->name ] = array(); + } + + if ( ! in_array( $p->ID, $terms[ $p_term->name ] ) ) { + $terms[ $p_term->name ][] = $p->ID; + } + } + } + + if ( empty( $terms ) ) { + $terms = array(); } return apply_filters( 'bp_docs_taxonomy_get_group_terms', $terms ); @@ -225,24 +273,14 @@ function get_group_terms( $terms = array() ) { /** * Saves the list of terms used by a group's docs * + * No longer used. + * * @package BuddyPress Docs * @since 1.0-beta * * @param array $terms The terms to be saved to groupmeta */ - function save_group_terms( $terms ) { - $doc = get_post(); - - if ( ! isset( $doc->post_type ) || $doc->post_type !== bp_docs_get_post_type_name() ) { - return $terms; - } - - $group_id = bp_docs_get_associated_group_id( $doc->ID, $doc ); - - if ( $group_id ) { - groups_update_groupmeta( $group_id, 'bp_docs_terms', $terms ); - } - } + function save_group_terms( $terms ) {} /** * Determine whether a user can edit the group doc in question diff --git a/includes/integration-users.php b/includes/integration-users.php index b3a03790..eab48aa5 100644 --- a/includes/integration-users.php +++ b/includes/integration-users.php @@ -24,7 +24,6 @@ function __construct() { // Taxonomy helpers add_filter( 'bp_docs_taxonomy_get_item_terms', array( &$this, 'get_user_terms' ) ); - add_action( 'bp_docs_taxonomy_save_item_terms', array( &$this, 'save_user_terms' ) ); } /** @@ -124,7 +123,7 @@ function setup_single_doc_subnav() { 'parent_slug' => bp_docs_get_docs_slug(), 'screen_function' => array( $bp->bp_docs, 'template_loader' ), 'position' => 30, - 'user_has_access' => true // todo + 'user_has_access' => true, // todo ) ); } } @@ -152,12 +151,47 @@ function update_doc_count() { * @return array $terms */ function get_user_terms( $terms = array() ) { + global $wpdb; - if ( bp_is_user() ) { - $terms = get_user_meta( bp_displayed_user_id(), 'bp_docs_terms', true ); + if ( ! bp_is_user() ) { + return $terms; + } + + $query_args = array( + 'post_type' => bp_docs_get_post_type_name(), + 'update_meta_cache' => false, + 'update_term_cache' => true, + 'showposts' => '-1', + 'posts_per_page' => '-1', + ); + + if ( bp_docs_is_edited_by() ) { + $query_args['post__in'] = BP_Docs_Query::get_edited_by_post_ids_for_user( bp_displayed_user_id() ); + } else if ( bp_docs_is_started_by() ) { + $query_args['post_author'] = bp_displayed_user_id(); + } else { + // Just in case + $query_args['post__in'] = array( 0 ); + } - if ( empty( $terms ) ) - $terms = array(); + $user_doc_query = new WP_Query( $query_args ); + + $terms = array(); + foreach ( $user_doc_query->posts as $p ) { + $p_terms = wp_get_post_terms( $p->ID, buddypress()->bp_docs->docs_tag_tax_name ); + foreach ( $p_terms as $p_term ) { + if ( ! isset( $terms[ $p_term->name ] ) ) { + $terms[ $p_term->name ] = array(); + } + + if ( ! in_array( $p->ID, $terms[ $p_term->name ] ) ) { + $terms[ $p_term->name ][] = $p->ID; + } + } + } + + if ( empty( $terms ) ) { + $terms = array(); } return apply_filters( 'bp_docs_taxonomy_get_user_terms', $terms ); @@ -166,19 +200,15 @@ function get_user_terms( $terms = array() ) { /** * Saves the list of terms used by a user's docs * + * No longer used. + * * @package BuddyPress_Docs * @subpackage Users * @since 1.2 * * @param array $terms The terms to be saved to usermeta */ - function save_user_terms( $terms ) { - - // bp_is_user isn't true at doc edit. (So neither is bp_displayed_user) - if ( bp_docs_is_docs_component() ) { - update_user_meta( bp_loggedin_user_id(), 'bp_docs_terms', $terms ); - } - } + function save_user_terms( $terms ) {} } diff --git a/includes/query-builder.php b/includes/query-builder.php index f71398a3..9414c97c 100644 --- a/includes/query-builder.php +++ b/includes/query-builder.php @@ -255,8 +255,8 @@ function get_wp_query() { /** * */ - function get_edited_by_post_ids() { - $editor_ids = wp_parse_id_list( $this->query_args['edited_by_id'] ); + public static function get_edited_by_post_ids_for_user( $editor_ids ) { + $editor_ids = wp_parse_id_list( $editor_ids ); $post_ids = array(); foreach ( $editor_ids as $editor_id ) { @@ -291,6 +291,13 @@ function get_edited_by_post_ids() { return array_unique( $post_ids ); } + /** + * + */ + function get_edited_by_post_ids() { + return self::get_edited_by_post_ids_for_user( $this->query_args['edited_by_id'] ); + } + /** */ function get_access_tax_query() { From 8f112438ee124c130845999882c6b3dd65e02c1e Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Tue, 11 Mar 2014 14:22:05 -0400 Subject: [PATCH 09/35] Update readme --- readme.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/readme.txt b/readme.txt index d92f392c..6a328652 100755 --- a/readme.txt +++ b/readme.txt @@ -33,6 +33,10 @@ This plugin is in active development. For feature requests and bug reports, visi == Changelog == += 1.6.0 = +* Overhaul of the way group/user tag clouds work +* Improved support for attachments on nginx and IIS + = 1.5.7 = * Improve appearance of row actions on mobile devices * Improve appearance of tags filter on IE < 9 From c52c86a2d65c46ef3cb15624795e0bc0c03b7642 Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Tue, 11 Mar 2014 14:26:41 -0400 Subject: [PATCH 10/35] Show group/user tag filters on group/user Docs directory --- includes/addon-taxonomy.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/includes/addon-taxonomy.php b/includes/addon-taxonomy.php index b6204518..fa64dda6 100644 --- a/includes/addon-taxonomy.php +++ b/includes/addon-taxonomy.php @@ -448,7 +448,11 @@ function bp_docs_get_tag_link( $args = array() ) { $r = wp_parse_args( $args, $defaults ); extract( $r, EXTR_SKIP ); - $item_docs_url = bp_docs_get_archive_link(); + if ( bp_is_user() || bp_is_group() ) { + $item_docs_url = $_SERVER['REQUEST_URI']; + } else { + $item_docs_url = bp_docs_get_archive_link(); + } $url = apply_filters( 'bp_docs_get_tag_link_url', add_query_arg( 'bpd_tag', urlencode( $tag ), $item_docs_url ), $args, $item_docs_url ); From f9d83e29fbc0501d14d5f6b14a771b69a2c16cd1 Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Tue, 11 Mar 2014 14:28:30 -0400 Subject: [PATCH 11/35] Strip query args better for View All Docs link --- includes/templatetags.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/templatetags.php b/includes/templatetags.php index 9c64fff8..ffdce4bd 100644 --- a/includes/templatetags.php +++ b/includes/templatetags.php @@ -204,7 +204,7 @@ function bp_docs_get_info_header() { $message = implode( "\n", $message ); // We are viewing a subset of docs, so we'll add a link to clear filters - $message .= ' - ' . sprintf( __( 'View All Docs', 'bp-docs' ), remove_query_arg( 'bpd_tag' ) ); + $message .= ' - ' . sprintf( __( 'View All Docs', 'bp-docs' ), remove_query_arg( array( 'bpd_tag', 's', 'search_submit' ) ) ); } ?> From b1a0d1e60df5807228ce4bc42696234875208c0f Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Tue, 11 Mar 2014 17:21:00 -0400 Subject: [PATCH 12/35] Better last_activity updating for groups when docs are updated and comments are posted Fixes #380 --- includes/integration-groups.php | 27 +++++++++--- includes/query-builder.php | 2 + tests/test-bp-docs.php | 74 +++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 5 deletions(-) diff --git a/includes/integration-groups.php b/includes/integration-groups.php index 3fc0d3eb..c6bb5fd6 100644 --- a/includes/integration-groups.php +++ b/includes/integration-groups.php @@ -67,8 +67,9 @@ function __construct() { add_filter( 'bp_docs_loop_additional_td', array( $this, 'groups_td' ), 5 ); // Update group last active metadata when a doc is created, updated, or saved - add_filter( 'bp_docs_doc_saved', array( $this, 'update_group_last_active' ) ); - add_filter( 'bp_docs_doc_deleted', array( $this, 'update_group_last_active' ) ); + add_filter( 'bp_docs_after_save', array( $this, 'update_group_last_active' ) ); + add_filter( 'bp_docs_before_doc_delete', array( $this, 'update_group_last_active' ) ); + add_filter( 'wp_insert_comment', array( $this, 'update_group_last_active_comment' ), 10, 2 ); // Sneak into the nav before it's rendered to insert the group Doc count. Hooking // to bp_actions because of the craptastic nature of the BP_Group_Extension loader @@ -758,9 +759,25 @@ function groups_td() { * @package BuddyPress Docs * @since 1.1.8 */ - function update_group_last_active() { - if ( bp_is_group() ) { - groups_update_groupmeta( bp_get_current_group_id(), 'last_activity', bp_core_current_time() ); + function update_group_last_active( $doc_id ) { + $group = intval( bp_docs_get_associated_group_id( $doc_id ) ); + + if ( $group ) { + groups_update_groupmeta( $group, 'last_activity', bp_core_current_time() ); + } + } + + /** + * Update group last activy date when a comment is posted to a group Doc. + * + * @since 1.6.0 + * + * @param int $comment_id + * @param object $comment + */ + public function update_group_last_active_comment( $comment_id, $comment ) { + if ( 1 == $comment->comment_approved ) { + $this->update_group_last_active( $comment->comment_post_ID ); } } diff --git a/includes/query-builder.php b/includes/query-builder.php index 9414c97c..7766f991 100644 --- a/includes/query-builder.php +++ b/includes/query-builder.php @@ -577,6 +577,8 @@ function save( $args = false ) { // the WP admin handles automatically) do_action( 'bp_docs_doc_saved', $this ); + do_action( 'bp_docs_after_save', $this->doc_id ); + $message_type = $result['redirect'] == 'single' ? 'success' : 'error'; $redirect_url = trailingslashit( bp_get_root_domain() . '/' . bp_docs_get_docs_slug() ); diff --git a/tests/test-bp-docs.php b/tests/test-bp-docs.php index 993678f7..f05d1db6 100644 --- a/tests/test-bp-docs.php +++ b/tests/test-bp-docs.php @@ -144,6 +144,80 @@ function test_bp_docs_get_doc_link() { } + /** + * @group last_activity + */ + function test_update_group_last_activity_on_new_doc() { + $g = $this->factory->group->create(); + $d = $this->factory->doc->create( array( + 'group' => $g, + ) ); + + $last_activity = date( 'Y-m-d H:i:s', time() - 100000 ); + groups_update_groupmeta( $g, 'last_activity', $last_activity ); + + // call manually because the hook is outside of the proper + // group document creation workflow + do_action( 'bp_docs_after_save', $d ); + + $this->assertNotEquals( $last_activity, groups_get_groupmeta( $g, 'last_activity' ) ); + } + + /** + * @group last_activity + */ + function test_update_group_last_activity_on_doc_delete() { + $g = $this->factory->group->create(); + $d = $this->factory->doc->create( array( + 'group' => $g, + ) ); + + $last_activity = date( 'Y-m-d H:i:s', time() - 100000 ); + groups_update_groupmeta( $g, 'last_activity', $last_activity ); + + bp_docs_trash_doc( $d ); + + $this->assertNotEquals( $last_activity, groups_get_groupmeta( $g, 'last_activity' ) ); + } + + /** + * @group last_activity + */ + function test_update_group_last_activity_on_doc_edit() { + $g = $this->factory->group->create(); + $d = $this->factory->doc->create( array( + 'group' => $g, + ) ); + + $last_activity = date( 'Y-m-d H:i:s', time() - 100000 ); + groups_update_groupmeta( $g, 'last_activity', $last_activity ); + + // call manually because the hook is outside of the proper + // group document creation workflow +// do_action( 'bp_docs_after_save', $d ); + + $this->assertNotEquals( $last_activity, groups_get_groupmeta( $g, 'last_activity' ) ); + } + + /** + * @group last_activity + */ + function test_update_group_last_activity_on_doc_comment() { + $g = $this->factory->group->create(); + $d = $this->factory->doc->create( array( + 'group' => $g, + ) ); + + $last_activity = date( 'Y-m-d H:i:s', time() - 100000 ); + groups_update_groupmeta( $g, 'last_activity', $last_activity ); + + $c = $this->factory->comment->create( array( + 'comment_post_ID' => $d, + ) ); + + $this->assertNotEquals( $last_activity, groups_get_groupmeta( $g, 'last_activity' ) ); + } + } From 2906fb0ad6b431581eea13ddcab01e3856a1c8ad Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Tue, 11 Mar 2014 20:17:10 -0400 Subject: [PATCH 13/35] Streamline edit styles and scripts --- includes/css/edit.css | 7 +++++++ includes/css/screen.css | 2 +- includes/js/bp-docs.js | 32 ++++++++++++++++---------------- includes/scss/screen.scss | 5 +++++ 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/includes/css/edit.css b/includes/css/edit.css index a826f632..09467f5f 100644 --- a/includes/css/edit.css +++ b/includes/css/edit.css @@ -62,6 +62,10 @@ td.content-column select { padding: inherit; } +.uploader-editor { + display: none; +} + /* Theme compat: Text mode editor */ #buddypress .standard-form textarea#doc_content { width: 100%; @@ -181,6 +185,9 @@ td.content-column select { #editorcontainer textarea { width: 99%; border: none; border-radius: 0; -webkit-border-radius: 0; -moz-border-radius: 0; margin-top: -1px; } +.wp-editor-container { + border: 1px solid #eaeaea; +} #edButtonHTML, #edButtonPreview { background-color: #F1F1F1; padding: 2px 10px; diff --git a/includes/css/screen.css b/includes/css/screen.css index 42d3276a..a9b5e97c 100644 --- a/includes/css/screen.css +++ b/includes/css/screen.css @@ -1 +1 @@ -.hide-if-no-js{display:none}.description{font-weight:normal;font-style:italic}.description code{font-style:normal;background:#eee;padding:2px 4px}#bp-create-doc-button{float:right;margin:5px 19px;font-weight:bold}body.bp-docs div.page ul{list-style-type:none}#bp-docs-all-docs{width:auto}.doc-tabs{overflow:hidden}.doc-tabs ul{padding-left:0}.doc-tabs li{float:left;margin:0 5px;list-style-type:none}.doc-tabs li:first-child{margin-left:0}.doc-tabs li a{background:#f1f1f1;text-decoration:none;display:block;padding:4px 10px;border-radius:5px 5px 0 0}.doc-tabs li.current a{background:#f3f3f3;color:#555;font-weight:bold}.doc-header h4{margin-bottom:15px !important}.docs-filter{display:block;width:400px;float:left;margin-bottom:15px}.doc-search{float:right;width:250px;text-align:right}.docs-filter-tags{width:100%}.docs-filter-tags ul li{display:block;width:120px;float:left;padding:6px}.doctable{border-collapse:separate;border-spacing:0}.doctable p{padding:0;margin:0}.doctable tr:hover .row-actions{visibility:visible}.doctable tr:nth-child(even){background-color:#f3f3f3}.doctable .bp-doc-trashed-doc .attachment-clip-cell{border-left:4px solid red}.bp-docs-trashed-doc-notice{color:red;font-size:.9em;font-style:italic}#buddypress #bp-docs-all-docs li{background:#eee}#buddypress div.doc-permissions{float:none;width:auto;margin-bottom:1em}#buddypress table.doctable td{vertical-align:top}#buddypress table.doctable tr:nth-child(even){background-color:#f3f3f3}#buddypress table.doctable tr th{background-color:#f3f3f3}.row-actions{visibility:hidden;padding:2px 0 0}body.mobile .row-actions{visibility:visible}.row-actions a{color:#999;font-size:11px}.row-actions a.delete{color:#f00}#docs-filter-submit{margin:10px 4px}.title-cell{width:30%}.author-cell,.created-date-cell,.edited-date-cell{text-align:center;width:100px}.current-orderby a{padding-left:20px}.asc a{background:url(../images/sort-col-asc.gif) no-repeat}.desc a{background:url(../images/sort-col-desc.gif) no-repeat}.doc-edit-link{margin:15px 0 20px 0}.doc-meta,#doc-meta,.docs #comments{padding-top:20px;border-top:1px solid #ddd}div.docs-info-header{background:#f3f3f3;padding:5px 10px;margin-bottom:10px}#associated_group_summary .item{padding-top:1em}#associated_group_summary .meta{font-size:11px;color:#888}#associated_group_summary img.avatar{margin-left:0}#doc-attachments-ul{margin-top:1em;list-style-type:none}#doc-attachments-ul li{margin:0px 5px 0px 0;padding:6px}#doc-attachments-ul li.even{background-color:#f3f3f3}#doc-attachments-ul .doc-attachment-delete{float:right;margin-top:.15em;margin-right:.3em}.bp-docs-attachment-clip{cursor:pointer;display:block;margin-top:10px}.doc-attachment-mime-icon{display:block;float:left;width:24px;height:24px;margin-right:5px;background:transparent url("../images/mime-type-sprites.png") no-repeat}.doc-attachment-mime-tar,.doc-attachment-mime-zip,.doc-attachment-mime-gz,.doc-attachment-mime-gzip,.doc-attachment-mime-rar,.doc-attachment-mime-7z{background-position:0 0px}.doc-attachment-mime-mp3,.doc-attachment-mime-m4a,.doc-attachment-mime-m4b,.doc-attachment-mime-ra,.doc-attachment-mime-ram,.doc-attachment-mime-wav,.doc-attachment-mime-ogg,.doc-attachment-mime-oga,.doc-attachment-mime-mid,.doc-attachment-mime-midi,.doc-attachment-mime-wma,.doc-attachment-mime-mka{background-position:0 -40px}.doc-attachment-mime-ics{background-position:0 -80px}.doc-attachment-mime-mdb,.doc-attachment-mime-odb{background-position:0 -120px}.doc-attachment-mime-odg{background-position:0 -160px}.doc-attachment-mime-jpg,.doc-attachment-mime-jpeg,.doc-attachment-mime-gif,.doc-attachment-mime-png,.doc-attachment-mime-bmp,.doc-attachment-mime-tif,.doc-attachment-mime-tiff,.doc-attachment-mime-ico{background-position:0 -200px}.doc-attachment-mime-pdf{background-position:0 -240px}.doc-attachment-mime-xla,.doc-attachment-mime-xls,.doc-attachment-mime-xlt,.doc-attachment-mime-xlw,.doc-attachment-mime-xlsx,.doc-attachment-mime-xlsm,.doc-attachment-mime-xlsb,.doc-attachment-mime-xlsb,.doc-attachment-mime-xlsx,.doc-attachment-mime-xlsm,.doc-attachment-mime-xlam,.doc-attachment-mime-ods,.doc-attachment-mime-odc{background-position:0 -280px}.doc-attachment-mime-txt,.doc-attachment-mime-asc,.doc-attachment-mime-c,.doc-attachment-mime-cc,.doc-attachment-mime-h,.doc-attachment-mime-csv,.doc-attachment-mime-tsv,.doc-attachment-mime-ics,.doc-attachment-mime-rtx,.doc-attachment-mime-css,.doc-attachment-mime-htm,.doc-attachment-mime-html{background-position:0 -320px}.doc-attachment-mime-asf,.doc-attachment-mime-asx,.doc-attachment-mime-wax,.doc-attachment-mime-wmv,.doc-attachment-mime-wmx,.doc-attachment-mime-avi,.doc-attachment-mime-divx,.doc-attachment-mime-flv,.doc-attachment-mime-mov,.doc-attachment-mime-qt,.doc-attachment-mime-mpeg,.doc-attachment-mime-mpg,.doc-attachment-mime-mpe,.doc-attachment-mime-mp4,.doc-attachment-mime-m4v,.doc-attachment-mime-ogv,.doc-attachment-mime-mkv{background-position:0 -360px}body.js .bp-docs-attachment-drawer{display:none}.bp-docs-attachment-drawer h4{margin:.5em 0}.bp-docs-attachment-drawer>ul{list-style-type:none}.bp-docs-attachment-drawer>ul>li{margin-left:0}.hide-pane,.show-pane,.paperclip-vertical,.paperclip-jaunty{background:url("../images/bp-docs-ui-sprites.png") no-repeat;display:block;float:left;margin-left:10px;margin-top:5px}.hide-pane{background-position:0 0;width:16px;height:16px}.show-pane{background-position:0 -28px;width:16px;height:16px}.paperclip-vertical{background-position:0 -55px;width:13px;height:36px}.paperclip-jaunty{background-position:0 -105px;width:17px;height:36px}.toggle-switch,.entry-content p.toggle-switch{display:block;font-size:1em;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;border:1px solid #ccc;background-color:#f3f3f3;padding:3px 0;text-indent:16px;margin:16px 0 0}.toggle-switch.active-switch,.entry-content p.toggle-switch.active-switch{-moz-border-radius-bottomleft:10px;-webkit-border-bottom-left-radius:10px;-moz-border-radius-bottomright:10px;-webkit-border-bottom-right-radius:10px;border-radius:3px 3px 0px 0px}.toggle-switch a,.entry-content p.toggle-switch a{color:#757575;text-decoration:none;display:block;width:100%;height:100%}.toggle-switch a:hover,.entry-content p.toggle-switch a:hover{font-weight:bold}.standard-form label.toggle-switch{margin:16px 0 0}.toggle-content{-moz-border-radius-bottomleft:2px;-webkit-border-bottom-left-radius:2px;-moz-border-radius-bottomright:2px;-webkit-border-bottom-right-radius:2px;border:1px solid #ccc;border-top:none;overflow:hidden}td.desc-column{width:300px;padding:0px 18px 12px}.docs-info-header .docs-filter{margin-bottom:0}#docs-filter-meta{font-size:.8em;color:#666;margin-bottom:0}a.docs-filter-title{margin:0 7px;text-decoration:none}a.docs-filter-title:visited{color:inherit}a.docs-filter-title.current{font-weight:bold}.docs-filter-section{border:1px solid #ccc;border-radius:2px;font-size:.8em;padding:6px 10px;margin-top:8px;transition:max-height 2s ease;overflow:hidden;position:relative}#docs-filter-section-tags a.tags-action-button,#docs-filter-section-tags a.tags-action-button:visited{display:inline;line-height:3em;text-decoration:none;background:#fff;background-opacity:.5;padding:5px 10px;border-radius:3px}body.js .docs-filter-section{display:none}body.js .docs-filter-section.docs-filter-section-open{display:block}p.currently-viewing{margin-bottom:5px;font-size:.8em;margin-top:8px}p#filter-by-tag{margin-bottom:0}.docs-info-header .toggle-switch{margin-top:8px}ul#tags-list{list-style-type:none;margin-bottom:0;padding:0;-moz-column-count:2;-moz-column-gap:10%;-webkit-column-count:2;-webkit-column-gap:10%;column-count:2;column-gap:10%}ul#tags-list li{margin-left:0}ul#tags-list li.hidden-tag{display:none}ul#tags-list li.tags-ellipses{font-style:italic}.groups-cell ul li img.avatar{float:none}.groups-cell ul li a{vertical-align:middle;font-size:.85em}.groups-cell ul{list-style-type:none;padding-left:0}.groups-cell ul li{margin-bottom:.5em}select#has-attachment{margin:8px 10px}div#bp-docs-pagination{position:relative;height:30px}div#bp-docs-pagination-count{position:absolute;left:0;top:5px;font-size:.9em;color:#999}div#bp-docs-paginate-links{position:absolute;right:0;top:5px}div#bp-docs-paginate-links a{padding:0 4px}div.doc-content{padding:20px;border:3px solid #f3f3f3}div.doc-content img{margin:10px}div.doc-content img.mceIcon{margin:0}#bp-docs-single-doc-header{overflow:hidden}body.trashed-doc #buddypress{border-left:4px solid red;padding-left:10px}div.doc-permissions{float:right;width:35%;background:#f0f0f0;border:1px solid #ddd;border-radius:3px;padding:4px}div.doc-permissions div:last-child{clear:both}#doc-permissions-summary,#doc-group-summary{font-size:1.0em;padding:3px 12px;border:1px solid}#doc-permissions-summary.doc-public{background:#b2ffb2;border-color:#00ff00}#doc-permissions-summary.doc-limited{background:#ffffe0;border-color:#e6db55}#doc-permissions-summary.doc-private{background:#ffebe8;border-color:#ff0000}a.doc-permissions-toggle{display:block;float:right;font-size:12px;cursor:hand}dl.doc-permissions-types dd,dl.doc-permissions-types dt{height:1.5em}dl.doc-permissions-types dt{width:50%;float:left;clear:left}#doc-group-summary{border-color:#f0f0f0}#doc-group-summary img.avatar{float:none}#doc-permissions-details ul{list-style-type:none;padding-left:0}#doc-permissions-details ul li{margin-bottom:.5em}span.bp-docs-level-icon{display:block;float:left;width:1.2em;height:1.2em;margin:3px 5px}.bp-docs-level-anyone span.bp-docs-level-icon{-moz-border-radius:.6em;-webkit-border-radius:.6em;border-radius:.6em;background:green}.bp-docs-level-friends span.bp-docs-level-icon,.bp-docs-level-loggedin span.bp-docs-level-icon,.bp-docs-level-group-members span.bp-docs-level-icon{width:0;height:0;border-left:.6em solid transparent;border-right:.6em solid transparent;border-bottom:1.2em solid yellow}.bp-docs-level-admins-mods span.bp-docs-level-icon,.bp-docs-level-no-one span.bp-docs-level-icon,.bp-docs-level-creator span.bp-docs-level-icon{background:red}div.doc-is-locked .toggle-switch{display:block;background:#bbb url(../images/padlock.gif) no-repeat;text-indent:25px;padding-top:3px}div.doc-is-locked .toggle-content{border:2px solid #f33;margin-top:5px;padding:7px 10px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}div.doc-meta p{margin-bottom:5px}a.nonexistent-doc{color:#f33}h2.doc-title{display:inline-block;width:50%}.comments-closed{padding:10px 20px;background:#f3f3f3;margin-top:10px}#respond{margin-top:20px}.doc-content ul{list-style:disc}.doc-content ol{list-style:decimal}.doc-content li{margin-left:20px}.doc-content blockquote{background:#f3f3f3;padding:5px;margin:10px 30px}div.hidden{display:none}table.group-docs-options td.label{width:200px}table.diff{width:100%}table.diff col.content{width:50%}table.diff tr{background-color:transparent}table.diff td,table.diff th{padding:.5em;font-family:Consolas, Monaco, Courier, monospace;border:none}table.diff .diff-deletedline del,table.diff .diff-addedline ins{text-decoration:none}table.diff .diff-deletedline{background-color:#fdd}table.diff .diff-deletedline del{background-color:#f99}table.diff .diff-addedline{background-color:#dfd}table.diff .diff-addedline ins{background-color:#9f9}#att-info{background-color:#E4F2FD}table#post-revisions{margin-top:20px}@media screen and (min-width: 4em){#docs-filter-section-tags a.tags-action-button,#docs-filter-section-tags a.tags-action-button:visited{display:block;margin-bottom:1em;padding:0;text-align:center}}@media screen and (min-width: 50em){.entry-content ul#tags-list{-moz-column-count:4;-moz-column-gap:5%;-webkit-column-count:4;-webkit-column-gap:5%;column-count:4;column-gap:5%}}@media screen and (min-width: 71em){.entry-content ul#tags-list{-moz-column-count:5;-moz-column-gap:5%;-webkit-column-count:5;-webkit-column-gap:5%;column-count:5;column-gap:5%}} +.hide-if-no-js{display:none}.description{font-weight:normal;font-style:italic}.description code{font-style:normal;background:#eee;padding:2px 4px}#bp-create-doc-button{float:right;margin:5px 19px;font-weight:bold}body.bp-docs div.page ul{list-style-type:none}#bp-docs-all-docs{width:auto}.doc-tabs{overflow:hidden}.doc-tabs ul{padding-left:0}.doc-tabs li{float:left;margin:0 5px;list-style-type:none}.doc-tabs li:first-child{margin-left:0}.doc-tabs li a{background:#f1f1f1;text-decoration:none;display:block;padding:4px 10px;border-radius:5px 5px 0 0}.doc-tabs li.current a{background:#f3f3f3;color:#555;font-weight:bold}.doc-header h4{margin-bottom:15px !important}.docs-filter{display:block;width:400px;float:left;margin-bottom:15px}.doc-search{float:right;width:250px;text-align:right}.docs-filter-tags{width:100%}.docs-filter-tags ul li{display:block;width:120px;float:left;padding:6px}.doctable{border-collapse:separate;border-spacing:0}.doctable p{padding:0;margin:0}.doctable tr:hover .row-actions{visibility:visible}.doctable tr:nth-child(even){background-color:#f3f3f3}.doctable .bp-doc-trashed-doc .attachment-clip-cell{border-left:4px solid red}.bp-docs-trashed-doc-notice{color:red;font-size:.9em;font-style:italic}#buddypress #bp-docs-all-docs li{background:#eee}#buddypress div.doc-permissions{float:none;width:auto;margin-bottom:1em}#buddypress table.doctable td{vertical-align:top}#buddypress table.doctable tr:nth-child(even){background-color:#f3f3f3}#buddypress table.doctable tr th{background-color:#f3f3f3}.row-actions{visibility:hidden;padding:2px 0 0}body.mobile .row-actions{visibility:visible}.row-actions a{color:#999;font-size:11px}.row-actions a.delete{color:#f00}#docs-filter-submit{margin:10px 4px}.title-cell{width:30%}.author-cell,.created-date-cell,.edited-date-cell{text-align:center;width:100px}.current-orderby a{padding-left:20px}.asc a{background:url(../images/sort-col-asc.gif) no-repeat}.desc a{background:url(../images/sort-col-desc.gif) no-repeat}.doc-edit-link{margin:15px 0 20px 0}.doc-meta,#doc-meta,.docs #comments{padding-top:20px;border-top:1px solid #ddd}div.docs-info-header{background:#f3f3f3;padding:5px 10px;margin-bottom:10px}#associated_group_summary .item{padding-top:1em}#associated_group_summary .meta{font-size:11px;color:#888}#associated_group_summary img.avatar{margin-left:0}#doc-attachments-ul{margin-top:1em;list-style-type:none}#doc-attachments-ul li{margin:0px 5px 0px 0;padding:6px}#doc-attachments-ul li.even{background-color:#f3f3f3}#doc-attachments-ul .doc-attachment-delete{float:right;margin-top:.15em;margin-right:.3em}.bp-docs-attachment-clip{cursor:pointer;display:block;margin-top:10px}.doc-attachment-mime-icon{display:block;float:left;width:24px;height:24px;margin-right:5px;background:transparent url("../images/mime-type-sprites.png") no-repeat}.doc-attachment-mime-tar,.doc-attachment-mime-zip,.doc-attachment-mime-gz,.doc-attachment-mime-gzip,.doc-attachment-mime-rar,.doc-attachment-mime-7z{background-position:0 0px}.doc-attachment-mime-mp3,.doc-attachment-mime-m4a,.doc-attachment-mime-m4b,.doc-attachment-mime-ra,.doc-attachment-mime-ram,.doc-attachment-mime-wav,.doc-attachment-mime-ogg,.doc-attachment-mime-oga,.doc-attachment-mime-mid,.doc-attachment-mime-midi,.doc-attachment-mime-wma,.doc-attachment-mime-mka{background-position:0 -40px}.doc-attachment-mime-ics{background-position:0 -80px}.doc-attachment-mime-mdb,.doc-attachment-mime-odb{background-position:0 -120px}.doc-attachment-mime-odg{background-position:0 -160px}.doc-attachment-mime-jpg,.doc-attachment-mime-jpeg,.doc-attachment-mime-gif,.doc-attachment-mime-png,.doc-attachment-mime-bmp,.doc-attachment-mime-tif,.doc-attachment-mime-tiff,.doc-attachment-mime-ico{background-position:0 -200px}.doc-attachment-mime-pdf{background-position:0 -240px}.doc-attachment-mime-xla,.doc-attachment-mime-xls,.doc-attachment-mime-xlt,.doc-attachment-mime-xlw,.doc-attachment-mime-xlsx,.doc-attachment-mime-xlsm,.doc-attachment-mime-xlsb,.doc-attachment-mime-xlsb,.doc-attachment-mime-xlsx,.doc-attachment-mime-xlsm,.doc-attachment-mime-xlam,.doc-attachment-mime-ods,.doc-attachment-mime-odc{background-position:0 -280px}.doc-attachment-mime-txt,.doc-attachment-mime-asc,.doc-attachment-mime-c,.doc-attachment-mime-cc,.doc-attachment-mime-h,.doc-attachment-mime-csv,.doc-attachment-mime-tsv,.doc-attachment-mime-ics,.doc-attachment-mime-rtx,.doc-attachment-mime-css,.doc-attachment-mime-htm,.doc-attachment-mime-html{background-position:0 -320px}.doc-attachment-mime-asf,.doc-attachment-mime-asx,.doc-attachment-mime-wax,.doc-attachment-mime-wmv,.doc-attachment-mime-wmx,.doc-attachment-mime-avi,.doc-attachment-mime-divx,.doc-attachment-mime-flv,.doc-attachment-mime-mov,.doc-attachment-mime-qt,.doc-attachment-mime-mpeg,.doc-attachment-mime-mpg,.doc-attachment-mime-mpe,.doc-attachment-mime-mp4,.doc-attachment-mime-m4v,.doc-attachment-mime-ogv,.doc-attachment-mime-mkv{background-position:0 -360px}body.js .bp-docs-attachment-drawer{display:none}.bp-docs-attachment-drawer h4{margin:.5em 0}.bp-docs-attachment-drawer>ul{list-style-type:none}.bp-docs-attachment-drawer>ul>li{margin-left:0}.toggleable.toggle-closed .toggle-content{display:none}.hide-pane,.show-pane,.paperclip-vertical,.paperclip-jaunty{background:url("../images/bp-docs-ui-sprites.png") no-repeat;display:block;float:left;margin-left:10px;margin-top:5px}.hide-pane{background-position:0 0;width:16px;height:16px}.show-pane{background-position:0 -28px;width:16px;height:16px}.paperclip-vertical{background-position:0 -55px;width:13px;height:36px}.paperclip-jaunty{background-position:0 -105px;width:17px;height:36px}.toggle-switch,.entry-content p.toggle-switch{display:block;font-size:1em;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;border:1px solid #ccc;background-color:#f3f3f3;padding:3px 0;text-indent:16px;margin:16px 0 0}.toggle-switch.active-switch,.entry-content p.toggle-switch.active-switch{-moz-border-radius-bottomleft:10px;-webkit-border-bottom-left-radius:10px;-moz-border-radius-bottomright:10px;-webkit-border-bottom-right-radius:10px;border-radius:3px 3px 0px 0px}.toggle-switch a,.entry-content p.toggle-switch a{color:#757575;text-decoration:none;display:block;width:100%;height:100%}.toggle-switch a:hover,.entry-content p.toggle-switch a:hover{font-weight:bold}.standard-form label.toggle-switch{margin:16px 0 0}.toggle-content{-moz-border-radius-bottomleft:2px;-webkit-border-bottom-left-radius:2px;-moz-border-radius-bottomright:2px;-webkit-border-bottom-right-radius:2px;border:1px solid #ccc;border-top:none;overflow:hidden}td.desc-column{width:300px;padding:0px 18px 12px}.docs-info-header .docs-filter{margin-bottom:0}#docs-filter-meta{font-size:.8em;color:#666;margin-bottom:0}a.docs-filter-title{margin:0 7px;text-decoration:none}a.docs-filter-title:visited{color:inherit}a.docs-filter-title.current{font-weight:bold}.docs-filter-section{border:1px solid #ccc;border-radius:2px;font-size:.8em;padding:6px 10px;margin-top:8px;transition:max-height 2s ease;overflow:hidden;position:relative}#docs-filter-section-tags a.tags-action-button,#docs-filter-section-tags a.tags-action-button:visited{display:inline;line-height:3em;text-decoration:none;background:#fff;background-opacity:.5;padding:5px 10px;border-radius:3px}body.js .docs-filter-section{display:none}body.js .docs-filter-section.docs-filter-section-open{display:block}p.currently-viewing{margin-bottom:5px;font-size:.8em;margin-top:8px}p#filter-by-tag{margin-bottom:0}.docs-info-header .toggle-switch{margin-top:8px}ul#tags-list{list-style-type:none;margin-bottom:0;padding:0;-moz-column-count:2;-moz-column-gap:10%;-webkit-column-count:2;-webkit-column-gap:10%;column-count:2;column-gap:10%}ul#tags-list li{margin-left:0}ul#tags-list li.hidden-tag{display:none}ul#tags-list li.tags-ellipses{font-style:italic}.groups-cell ul li img.avatar{float:none}.groups-cell ul li a{vertical-align:middle;font-size:.85em}.groups-cell ul{list-style-type:none;padding-left:0}.groups-cell ul li{margin-bottom:.5em}select#has-attachment{margin:8px 10px}div#bp-docs-pagination{position:relative;height:30px}div#bp-docs-pagination-count{position:absolute;left:0;top:5px;font-size:.9em;color:#999}div#bp-docs-paginate-links{position:absolute;right:0;top:5px}div#bp-docs-paginate-links a{padding:0 4px}div.doc-content{padding:20px;border:3px solid #f3f3f3}div.doc-content img{margin:10px}div.doc-content img.mceIcon{margin:0}#bp-docs-single-doc-header{overflow:hidden}body.trashed-doc #buddypress{border-left:4px solid red;padding-left:10px}div.doc-permissions{float:right;width:35%;background:#f0f0f0;border:1px solid #ddd;border-radius:3px;padding:4px}div.doc-permissions div:last-child{clear:both}#doc-permissions-summary,#doc-group-summary{font-size:1.0em;padding:3px 12px;border:1px solid}#doc-permissions-summary.doc-public{background:#b2ffb2;border-color:#00ff00}#doc-permissions-summary.doc-limited{background:#ffffe0;border-color:#e6db55}#doc-permissions-summary.doc-private{background:#ffebe8;border-color:#ff0000}a.doc-permissions-toggle{display:block;float:right;font-size:12px;cursor:hand}dl.doc-permissions-types dd,dl.doc-permissions-types dt{height:1.5em}dl.doc-permissions-types dt{width:50%;float:left;clear:left}#doc-group-summary{border-color:#f0f0f0}#doc-group-summary img.avatar{float:none}#doc-permissions-details ul{list-style-type:none;padding-left:0}#doc-permissions-details ul li{margin-bottom:.5em}span.bp-docs-level-icon{display:block;float:left;width:1.2em;height:1.2em;margin:3px 5px}.bp-docs-level-anyone span.bp-docs-level-icon{-moz-border-radius:.6em;-webkit-border-radius:.6em;border-radius:.6em;background:green}.bp-docs-level-friends span.bp-docs-level-icon,.bp-docs-level-loggedin span.bp-docs-level-icon,.bp-docs-level-group-members span.bp-docs-level-icon{width:0;height:0;border-left:.6em solid transparent;border-right:.6em solid transparent;border-bottom:1.2em solid yellow}.bp-docs-level-admins-mods span.bp-docs-level-icon,.bp-docs-level-no-one span.bp-docs-level-icon,.bp-docs-level-creator span.bp-docs-level-icon{background:red}div.doc-is-locked .toggle-switch{display:block;background:#bbb url(../images/padlock.gif) no-repeat;text-indent:25px;padding-top:3px}div.doc-is-locked .toggle-content{border:2px solid #f33;margin-top:5px;padding:7px 10px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}div.doc-meta p{margin-bottom:5px}a.nonexistent-doc{color:#f33}h2.doc-title{display:inline-block;width:50%}.comments-closed{padding:10px 20px;background:#f3f3f3;margin-top:10px}#respond{margin-top:20px}.doc-content ul{list-style:disc}.doc-content ol{list-style:decimal}.doc-content li{margin-left:20px}.doc-content blockquote{background:#f3f3f3;padding:5px;margin:10px 30px}div.hidden{display:none}table.group-docs-options td.label{width:200px}table.diff{width:100%}table.diff col.content{width:50%}table.diff tr{background-color:transparent}table.diff td,table.diff th{padding:.5em;font-family:Consolas, Monaco, Courier, monospace;border:none}table.diff .diff-deletedline del,table.diff .diff-addedline ins{text-decoration:none}table.diff .diff-deletedline{background-color:#fdd}table.diff .diff-deletedline del{background-color:#f99}table.diff .diff-addedline{background-color:#dfd}table.diff .diff-addedline ins{background-color:#9f9}#att-info{background-color:#E4F2FD}table#post-revisions{margin-top:20px}@media screen and (min-width: 4em){#docs-filter-section-tags a.tags-action-button,#docs-filter-section-tags a.tags-action-button:visited{display:block;margin-bottom:1em;padding:0;text-align:center}}@media screen and (min-width: 50em){.entry-content ul#tags-list{-moz-column-count:4;-moz-column-gap:5%;-webkit-column-count:4;-webkit-column-gap:5%;column-count:4;column-gap:5%}}@media screen and (min-width: 71em){.entry-content ul#tags-list{-moz-column-count:5;-moz-column-gap:5%;-webkit-column-count:5;-webkit-column-gap:5%;column-count:5;column-gap:5%}} diff --git a/includes/js/bp-docs.js b/includes/js/bp-docs.js index 61ee7f09..2ea45c55 100644 --- a/includes/js/bp-docs.js +++ b/includes/js/bp-docs.js @@ -27,10 +27,10 @@ jQuery(document).ready(function($){ /* When a toggle is clicked, show the toggle-content */ $('.toggle-link').click(function(){ // Traverse for some items - var toggleable = $(this).parents('.toggleable'); - var tc = $(toggleable).find('.toggle-content'); - var ts = $(toggleable).find('.toggle-switch'); - var pom = $(this).find('.plus-or-minus'); + var $toggleable = $(this).parents('.toggleable'); + var tc = $toggleable.find('.toggle-content'); + var ts = $toggleable.find('.toggle-switch'); + var $pom = $(this).find('.plus-or-minus'); // Toggle the active-content class if($(tc).hasClass('active-content')){ @@ -47,19 +47,19 @@ jQuery(document).ready(function($){ } // Slide the tags up or down - $(tc).slideToggle(400, function(){ - var rclass, aclass; - if ( $(pom).hasClass('show-pane') ) { - rclass = 'show-pane'; - aclass = 'hide-pane'; - } else { - rclass = 'hide-pane'; - aclass = 'show-pane'; - } + var rclass, aclass; + if ( $pom.hasClass('show-pane') ) { + rclass = 'show-pane'; + aclass = 'hide-pane'; + $toggleable.removeClass( 'toggle-open' ).addClass( 'toggle-closed' ); + } else { + rclass = 'hide-pane'; + aclass = 'show-pane'; + $toggleable.removeClass( 'toggle-closed' ).addClass( 'toggle-open' ); + } - $(pom).removeClass(rclass); - $(pom).addClass(aclass); - }); + $pom.removeClass(rclass); + $pom.addClass(aclass); return false; }); diff --git a/includes/scss/screen.scss b/includes/scss/screen.scss index f7f6917a..a2fa3936 100644 --- a/includes/scss/screen.scss +++ b/includes/scss/screen.scss @@ -402,6 +402,11 @@ body.js .bp-docs-attachment-drawer { } /* TOGGLES */ + +.toggleable.toggle-closed .toggle-content { + display: none; +} + .hide-pane, .show-pane, .paperclip-vertical, .paperclip-jaunty{ background: url('../images/bp-docs-ui-sprites.png') no-repeat; display: block; From 5f4af9927d5b4f13373885acbd47ea3f8800f886 Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Tue, 11 Mar 2014 20:26:57 -0400 Subject: [PATCH 14/35] Don't need a separate _edit() last_activity test --- tests/test-bp-docs.php | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/tests/test-bp-docs.php b/tests/test-bp-docs.php index f05d1db6..59345a5d 100644 --- a/tests/test-bp-docs.php +++ b/tests/test-bp-docs.php @@ -180,25 +180,6 @@ function test_update_group_last_activity_on_doc_delete() { $this->assertNotEquals( $last_activity, groups_get_groupmeta( $g, 'last_activity' ) ); } - /** - * @group last_activity - */ - function test_update_group_last_activity_on_doc_edit() { - $g = $this->factory->group->create(); - $d = $this->factory->doc->create( array( - 'group' => $g, - ) ); - - $last_activity = date( 'Y-m-d H:i:s', time() - 100000 ); - groups_update_groupmeta( $g, 'last_activity', $last_activity ); - - // call manually because the hook is outside of the proper - // group document creation workflow -// do_action( 'bp_docs_after_save', $d ); - - $this->assertNotEquals( $last_activity, groups_get_groupmeta( $g, 'last_activity' ) ); - } - /** * @group last_activity */ From a2c1b849a33ca098d0acfea652870ca2c41feeba Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Tue, 11 Mar 2014 20:45:09 -0400 Subject: [PATCH 15/35] Move most edit lock functionality to its own file --- bp-docs.php | 2 + includes/component.php | 20 ---- includes/edit-lock.php | 204 ++++++++++++++++++++++++++++++++++++++ includes/functions.php | 29 ------ includes/templatetags.php | 134 ------------------------- 5 files changed, 206 insertions(+), 183 deletions(-) create mode 100644 includes/edit-lock.php diff --git a/bp-docs.php b/bp-docs.php index 83fa7388..37650b13 100644 --- a/bp-docs.php +++ b/bp-docs.php @@ -108,6 +108,8 @@ function includes() { require( BP_DOCS_INCLUDES_PATH . 'theme-bridge.php' ); + require( BP_DOCS_INCLUDES_PATH . 'edit-lock.php' ); + // formatting.php contains filters and functions used to modify appearance only require( BP_DOCS_INCLUDES_PATH . 'formatting.php' ); diff --git a/includes/component.php b/includes/component.php index 4b1586e4..0358333a 100644 --- a/includes/component.php +++ b/includes/component.php @@ -120,9 +120,6 @@ function setup_hooks() { // Respect $activities_template->disable_blogforum_replies add_filter( 'bp_activity_can_comment', array( $this, 'activity_can_comment' ) ); - // AJAX handler for removing the edit lock when a user clicks away from Edit mode - add_action( 'wp_ajax_remove_edit_lock', array( $this, 'remove_edit_lock' ) ); - // Add body class add_filter( 'bp_get_the_body_class', array( $this, 'body_class' ) ); @@ -984,23 +981,6 @@ function handle_filters() { bp_core_redirect( $redirect_url ); } - /** - * AJAX handler for remove_edit_lock option - * - * This function is called when a user is editing a Doc and clicks a link to leave the page - * - * @package BuddyPress Docs - * @since 1.1 - */ - function remove_edit_lock() { - $doc_id = isset( $_POST['doc_id'] ) ? $_POST['doc_id'] : false; - - if ( !$doc_id ) - return false; - - delete_post_meta( $doc_id, '_edit_lock' ); - } - /** * Sets the includes URL for use when loading scripts and styles * diff --git a/includes/edit-lock.php b/includes/edit-lock.php new file mode 100644 index 00000000..87921733 --- /dev/null +++ b/includes/edit-lock.php @@ -0,0 +1,204 @@ +ID, '_edit_lock', true ) ) + return false; + + $lock = explode( ':', $lock ); + $time = $lock[0]; + $user = isset( $lock[1] ) ? $lock[1] : get_post_meta( $post->ID, '_edit_last', true ); + + $time_window = apply_filters( 'wp_check_post_lock_window', AUTOSAVE_INTERVAL * 2 ); + + if ( $time && $time > time() - $time_window && $user != get_current_user_id() ) + return $user; + return false; +} + +/** + * Get the lock status of a doc + * + * The function first tries to get the lock status out of $bp. If it has to look it up, it + * stores the data in $bp for future use. + * + * @package BuddyPress Docs + * @since 1.0-beta-2 + * + * @param int $doc_id Optional. Defaults to the doc currently being viewed + * @return int Returns 0 if there is no lock, otherwise returns the user_id of the locker + */ +function bp_docs_is_doc_edit_locked( $doc_id = false ) { + global $bp, $post; + + // Try to get the lock out of $bp first + if ( isset( $bp->bp_docs->current_doc_lock ) ) { + $is_edit_locked = $bp->bp_docs->current_doc_lock; + } else { + $is_edit_locked = 0; + + if ( empty( $doc_id ) ) + $doc_id = !empty( $post->ID ) ? $post->ID : false; + + if ( $doc_id ) { + // Because we're not using WP autosave at the moment, ensure that + // the lock interval always returns as in process + add_filter( 'wp_check_post_lock_window', create_function( false, 'return time();' ) ); + + $is_edit_locked = bp_docs_check_post_lock( $doc_id ); + } + + // Put into the $bp global to avoid extra lookups + $bp->bp_docs->current_doc_lock = $is_edit_locked; + } + + return apply_filters( 'bp_docs_is_doc_edit_locked', $is_edit_locked, $doc_id ); +} + +/** + * Echoes the output of bp_docs_get_current_doc_locker_name() + * + * @package BuddyPress Docs + * @since 1.0-beta-2 + */ +function bp_docs_current_doc_locker_name() { + echo bp_docs_get_current_doc_locker_name(); +} + /** + * Get the name of the user locking the current document, if any + * + * @package BuddyPress Docs + * @since 1.0-beta-2 + * + * @return string $locker_name The full name of the locking user + */ + function bp_docs_get_current_doc_locker_name() { + $locker_name = ''; + + $locker_id = bp_docs_is_doc_edit_locked(); + + if ( $locker_id ) + $locker_name = bp_core_get_user_displayname( $locker_id ); + + return apply_filters( 'bp_docs_get_current_doc_locker_name', $locker_name, $locker_id ); + } + +/** + * Echoes the output of bp_docs_get_force_cancel_edit_lock_link() + * + * @package BuddyPress Docs + * @since 1.0-beta-2 + */ +function bp_docs_force_cancel_edit_lock_link() { + echo bp_docs_get_force_cancel_edit_lock_link(); +} + /** + * Get the URL for canceling the edit lock on the current doc + * + * @package BuddyPress Docs + * @since 1.0-beta-2 + * + * @return string $cancel_link href for the cancel edit lock link + */ + function bp_docs_get_force_cancel_edit_lock_link() { + global $post; + + $doc_id = !empty( $post->ID ) ? $post->ID : false; + + if ( !$doc_id ) + return false; + + $doc_permalink = bp_docs_get_doc_link( $doc_id ); + + $cancel_link = wp_nonce_url( add_query_arg( 'bpd_action', 'cancel_edit_lock', $doc_permalink ), 'bp_docs_cancel_edit_lock' ); + + return apply_filters( 'bp_docs_get_force_cancel_edit_lock_link', $cancel_link, $doc_permalink ); + } + +/** + * Echoes the output of bp_docs_get_cancel_edit_link() + * + * @package BuddyPress Docs + * @since 1.0-beta-2 + */ +function bp_docs_cancel_edit_link() { + echo bp_docs_get_cancel_edit_link(); +} + /** + * Get the URL for canceling out of Edit mode on a doc + * + * This used to be a straight link back to non-edit mode, but something fancier is needed + * in order to detect the Cancel and to remove the edit lock. + * + * @package BuddyPress Docs + * @since 1.0-beta-2 + * + * @return string $cancel_link href for the cancel edit link + */ + function bp_docs_get_cancel_edit_link() { + global $bp, $post; + + $doc_id = !empty( $bp->bp_docs->current_post->ID ) ? $bp->bp_docs->current_post->ID : false; + + if ( !$doc_id ) + return false; + + $doc_permalink = bp_docs_get_doc_link( $doc_id ); + + $cancel_link = add_query_arg( 'bpd_action', 'cancel_edit', $doc_permalink ); + + return apply_filters( 'bp_docs_get_cancel_edit_link', $cancel_link, $doc_permalink ); + } + +/** + * AJAX handler for remove_edit_lock option + * + * This function is called when a user is editing a Doc and clicks a link to leave the page + * + * @package BuddyPress Docs + * @since 1.1 + */ +function bp_docs_remove_edit_lock() { + $doc_id = isset( $_POST['doc_id'] ) ? $_POST['doc_id'] : false; + + if ( !$doc_id ) + return false; + + delete_post_meta( $doc_id, '_edit_lock' ); +} +add_action( 'wp_ajax_remove_edit_lock', 'bp_docs_remove_edit_lock' ); + + diff --git a/includes/functions.php b/includes/functions.php index 7b9c7198..30b503b3 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -717,35 +717,6 @@ function bp_docs_hide_sitewide_for_doc( $doc_id ) { return apply_filters( 'bp_docs_hide_sitewide_for_doc', $hide_sitewide, $doc_id ); } -/** - * Check to see if the post is currently being edited by another user. - * - * This is a verbatim copy of wp_check_post_lock(), which is only available - * in the admin - * - * @since 1.2.8 - * - * @param int $post_id ID of the post to check for editing - * @return bool|int False: not locked or locked by current user. Int: user ID of user with lock. - */ -function bp_docs_check_post_lock( $post_id ) { - if ( !$post = get_post( $post_id ) ) - return false; - - if ( !$lock = get_post_meta( $post->ID, '_edit_lock', true ) ) - return false; - - $lock = explode( ':', $lock ); - $time = $lock[0]; - $user = isset( $lock[1] ) ? $lock[1] : get_post_meta( $post->ID, '_edit_last', true ); - - $time_window = apply_filters( 'wp_check_post_lock_window', AUTOSAVE_INTERVAL * 2 ); - - if ( $time && $time > time() - $time_window && $user != get_current_user_id() ) - return $user; - return false; -} - function bp_docs_get_doc_ids_accessible_to_current_user() { global $wpdb; diff --git a/includes/templatetags.php b/includes/templatetags.php index ffdce4bd..357283d1 100644 --- a/includes/templatetags.php +++ b/includes/templatetags.php @@ -957,140 +957,6 @@ function bp_docs_current_group_is_public() { return false; } -/** - * Get the lock status of a doc - * - * The function first tries to get the lock status out of $bp. If it has to look it up, it - * stores the data in $bp for future use. - * - * @package BuddyPress Docs - * @since 1.0-beta-2 - * - * @param int $doc_id Optional. Defaults to the doc currently being viewed - * @return int Returns 0 if there is no lock, otherwise returns the user_id of the locker - */ -function bp_docs_is_doc_edit_locked( $doc_id = false ) { - global $bp, $post; - - // Try to get the lock out of $bp first - if ( isset( $bp->bp_docs->current_doc_lock ) ) { - $is_edit_locked = $bp->bp_docs->current_doc_lock; - } else { - $is_edit_locked = 0; - - if ( empty( $doc_id ) ) - $doc_id = !empty( $post->ID ) ? $post->ID : false; - - if ( $doc_id ) { - // Because we're not using WP autosave at the moment, ensure that - // the lock interval always returns as in process - add_filter( 'wp_check_post_lock_window', create_function( false, 'return time();' ) ); - - $is_edit_locked = bp_docs_check_post_lock( $doc_id ); - } - - // Put into the $bp global to avoid extra lookups - $bp->bp_docs->current_doc_lock = $is_edit_locked; - } - - return apply_filters( 'bp_docs_is_doc_edit_locked', $is_edit_locked, $doc_id ); -} - -/** - * Echoes the output of bp_docs_get_current_doc_locker_name() - * - * @package BuddyPress Docs - * @since 1.0-beta-2 - */ -function bp_docs_current_doc_locker_name() { - echo bp_docs_get_current_doc_locker_name(); -} - /** - * Get the name of the user locking the current document, if any - * - * @package BuddyPress Docs - * @since 1.0-beta-2 - * - * @return string $locker_name The full name of the locking user - */ - function bp_docs_get_current_doc_locker_name() { - $locker_name = ''; - - $locker_id = bp_docs_is_doc_edit_locked(); - - if ( $locker_id ) - $locker_name = bp_core_get_user_displayname( $locker_id ); - - return apply_filters( 'bp_docs_get_current_doc_locker_name', $locker_name, $locker_id ); - } - -/** - * Echoes the output of bp_docs_get_force_cancel_edit_lock_link() - * - * @package BuddyPress Docs - * @since 1.0-beta-2 - */ -function bp_docs_force_cancel_edit_lock_link() { - echo bp_docs_get_force_cancel_edit_lock_link(); -} - /** - * Get the URL for canceling the edit lock on the current doc - * - * @package BuddyPress Docs - * @since 1.0-beta-2 - * - * @return string $cancel_link href for the cancel edit lock link - */ - function bp_docs_get_force_cancel_edit_lock_link() { - global $post; - - $doc_id = !empty( $post->ID ) ? $post->ID : false; - - if ( !$doc_id ) - return false; - - $doc_permalink = bp_docs_get_doc_link( $doc_id ); - - $cancel_link = wp_nonce_url( add_query_arg( 'bpd_action', 'cancel_edit_lock', $doc_permalink ), 'bp_docs_cancel_edit_lock' ); - - return apply_filters( 'bp_docs_get_force_cancel_edit_lock_link', $cancel_link, $doc_permalink ); - } - -/** - * Echoes the output of bp_docs_get_cancel_edit_link() - * - * @package BuddyPress Docs - * @since 1.0-beta-2 - */ -function bp_docs_cancel_edit_link() { - echo bp_docs_get_cancel_edit_link(); -} - /** - * Get the URL for canceling out of Edit mode on a doc - * - * This used to be a straight link back to non-edit mode, but something fancier is needed - * in order to detect the Cancel and to remove the edit lock. - * - * @package BuddyPress Docs - * @since 1.0-beta-2 - * - * @return string $cancel_link href for the cancel edit link - */ - function bp_docs_get_cancel_edit_link() { - global $bp, $post; - - $doc_id = !empty( $bp->bp_docs->current_post->ID ) ? $bp->bp_docs->current_post->ID : false; - - if ( !$doc_id ) - return false; - - $doc_permalink = bp_docs_get_doc_link( $doc_id ); - - $cancel_link = add_query_arg( 'bpd_action', 'cancel_edit', $doc_permalink ); - - return apply_filters( 'bp_docs_get_cancel_edit_link', $cancel_link, $doc_permalink ); - } - /** * Echoes the output of bp_docs_get_delete_doc_link() * From d5c525c6bc5aa095a07042936bfe59999e7baa14 Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Tue, 11 Mar 2014 21:23:23 -0400 Subject: [PATCH 16/35] Improve edit locks Use the WP heartbeat API to ensure that users are constantly connected. If more than 4 pings are missed (default 60 seconds), then the user is assumed to have closed the browser, and the edit lock is lifted. --- includes/component.php | 7 +++- includes/edit-lock.php | 86 ++++++++++++++++++++++++++++++++++++++---- includes/js/bp-docs.js | 35 +++++++++++++++++ 3 files changed, 120 insertions(+), 8 deletions(-) diff --git a/includes/component.php b/includes/component.php index 0358333a..39e1ef13 100644 --- a/includes/component.php +++ b/includes/component.php @@ -1009,6 +1009,10 @@ function body_class( $classes ) { $classes[] = 'mobile'; } + if ( bp_docs_is_doc_edit() ) { + $classes[] = 'bp-docs-edit'; + } + return array_unique( $classes ); } @@ -1095,7 +1099,7 @@ function enqueue_scripts() { // Edit mode requires bp-docs-js to be dependent on TinyMCE, so we must // reregister bp-docs-js with the correct dependencies wp_deregister_script( 'bp-docs-js' ); - wp_register_script( 'bp-docs-js', plugins_url( BP_DOCS_PLUGIN_SLUG . '/includes/js/bp-docs.js' ), array( 'jquery', 'editor' ) ); + wp_register_script( 'bp-docs-js', plugins_url( BP_DOCS_PLUGIN_SLUG . '/includes/js/bp-docs.js' ), array( 'jquery', 'editor', 'heartbeat' ) ); wp_register_script( 'word-counter', site_url() . '/wp-admin/js/word-count.js', array( 'jquery' ) ); @@ -1111,6 +1115,7 @@ function enqueue_scripts() { 'upload_title' => __( 'Upload File', 'bp-docs' ), 'upload_button' => __( 'OK', 'bp-docs' ), 'still_working' => __( 'Still working?', 'bp-docs' ), + 'pulse' => bp_docs_heartbeat_pulse(), ) ); } } diff --git a/includes/edit-lock.php b/includes/edit-lock.php index 87921733..e76d653b 100644 --- a/includes/edit-lock.php +++ b/includes/edit-lock.php @@ -6,6 +6,35 @@ * @since 1.6.0 */ +/** + * BP Docs heartbeat interval. + * + * @since 1.6.0 + * + * @return int + */ +function bp_docs_heartbeat_pulse() { + // Check whether a global heartbeat already exists + $heartbeat_settings = apply_filters( 'heartbeat_settings', array() ); + if ( ! empty( $heartbeat_settings['interval'] ) ) { + if ( 'fast' === $heartbeat_settings['interval'] ) { + $pulse = 5; + } else { + $pulse = intval( $heartbeat_settings['interval'] ); + } + } + + // Fallback + if ( empty( $pulse ) ) { + $pulse = 15; + } + + // Filter here to specify a Docs-specific pulse frequency + $pulse = intval( apply_filters( 'bp_docs_activity_pulse', $pulse ) ); + + return $pulse; +} + /** * Handle heartbeat * @@ -17,6 +46,8 @@ function bp_docs_heartbeat_callback( $response, $data ) { } $doc_id = intval( $data['doc_id'] ); + + update_post_meta( $doc_id, '_bp_docs_last_pinged', time() ); } add_filter( 'heartbeat_received', 'bp_docs_heartbeat_callback', 10, 2 ); @@ -42,10 +73,17 @@ function bp_docs_check_post_lock( $post_id ) { $time = $lock[0]; $user = isset( $lock[1] ) ? $lock[1] : get_post_meta( $post->ID, '_edit_last', true ); - $time_window = apply_filters( 'wp_check_post_lock_window', AUTOSAVE_INTERVAL * 2 ); + $last_checked = get_post_meta( $post->ID, '_bp_docs_last_pinged', true ); + + $heartbeat_interval = bp_docs_heartbeat_pulse(); + + // Bail out of the lock if four pings have been missed (one minute, by default) + $time_window = apply_filters( 'bp_docs_post_lock_interval', $heartbeat_interval * 4 ); - if ( $time && $time > time() - $time_window && $user != get_current_user_id() ) + if ( $last_checked && $last_checked > time() - $time_window && $user != get_current_user_id() ) { return $user; + } + return false; } @@ -74,10 +112,6 @@ function bp_docs_is_doc_edit_locked( $doc_id = false ) { $doc_id = !empty( $post->ID ) ? $post->ID : false; if ( $doc_id ) { - // Because we're not using WP autosave at the moment, ensure that - // the lock interval always returns as in process - add_filter( 'wp_check_post_lock_window', create_function( false, 'return time();' ) ); - $is_edit_locked = bp_docs_check_post_lock( $doc_id ); } @@ -171,7 +205,7 @@ function bp_docs_cancel_edit_link() { function bp_docs_get_cancel_edit_link() { global $bp, $post; - $doc_id = !empty( $bp->bp_docs->current_post->ID ) ? $bp->bp_docs->current_post->ID : false; + $doc_id = get_queried_object_id(); if ( !$doc_id ) return false; @@ -201,4 +235,42 @@ function bp_docs_remove_edit_lock() { } add_action( 'wp_ajax_remove_edit_lock', 'bp_docs_remove_edit_lock' ); +/** + * AJAX handler for setting edit lock. + * + * Called when a user enters an Edit page. + * + * @since 1.6.0 + */ +function bp_docs_add_edit_lock_cb() { + $doc_id = isset( $_POST['doc_id'] ) ? (int) $_POST['doc_id'] : false; + + if ( ! $doc_id ) { + return; + } + + $doc = get_post( $doc_id ); + + if ( ! $doc || is_wp_error( $doc ) ) { + return; + } + + if ( bp_docs_get_post_type_name() !== $doc->post_type ) { + return; + } + + if ( ! is_user_logged_in() ) { + return; + } + + $now = time(); + $user_id = bp_loggedin_user_id(); + $lock = "$now:$user_id"; + + update_post_meta( $doc->ID, '_edit_lock', $lock ); + update_post_meta( $doc_id, '_bp_docs_last_pinged', $now ); + + die( json_encode( '1' ) ); +} +add_action( 'wp_ajax_add_edit_lock', 'bp_docs_add_edit_lock_cb' ); diff --git a/includes/js/bp-docs.js b/includes/js/bp-docs.js index 2ea45c55..46deb2f9 100644 --- a/includes/js/bp-docs.js +++ b/includes/js/bp-docs.js @@ -1,7 +1,26 @@ jQuery(document).ready(function($){ + var doc_id = $( '#existing-doc-id' ).val(); + /* Unhide JS content */ $('.hide-if-no-js').show(); + // If this is an edit page, set the lock + if ( $( 'body' ).hasClass( 'bp-docs-edit' ) ) { + var lock_data = { + action: 'add_edit_lock', + doc_id: doc_id + }; + + $.ajax({ + url: ajaxurl, + type: 'POST', + data: lock_data, + success: function(response){ + return true; + } + }); + } + $('.bp-docs-attachment-clip').on('click', function(e) { var att_doc_id = $(e.target).closest('.bp-docs-attachment-clip').attr('id').split('-').pop(); var att_doc_drawer = $('#bp-docs-attachment-drawer-'+att_doc_id); @@ -147,6 +166,22 @@ jQuery(document).ready(function($){ return false; }); + // Set the interval and the namespace event + if ( typeof wp != 'undefined' && typeof wp.heartbeat != 'undefined' && typeof bp_docs.pulse != 'undefined' ) { + + wp.heartbeat.interval( Number( bp_docs.pulse ) ); + + jq.fn.extend({ + 'heartbeat-send': function() { + return this.bind( 'heartbeat-send.buddypress-docs' ); + }, + }); + } + + $( document ).on( 'heartbeat-send.buddypress-docs', function( e, data ) { + data['doc_id'] = $('#existing-doc-id').val(); + }); + /** * Collapse the Tags filter section */ From bd5b3604385271d35ce25c9324541397ba0bbd2b Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Tue, 11 Mar 2014 22:00:41 -0400 Subject: [PATCH 17/35] Improved redirection etc for simultaneous edits --- includes/component.php | 11 ++++++-- includes/edit-lock.php | 64 ++++++++++++++++++++++++++++++++++++------ includes/js/bp-docs.js | 8 ++++++ 3 files changed, 72 insertions(+), 11 deletions(-) diff --git a/includes/component.php b/includes/component.php index 39e1ef13..249c8541 100644 --- a/includes/component.php +++ b/includes/component.php @@ -1111,12 +1111,17 @@ function enqueue_scripts() { if ( in_array( bp_docs_get_docs_slug(), $this->slugstocheck ) || bp_docs_is_single_doc() || bp_docs_is_global_directory() || bp_docs_is_doc_create() ) { wp_enqueue_script( 'bp-docs-js' ); wp_enqueue_script( 'comment-reply' ); - wp_localize_script( 'bp-docs-js', 'bp_docs', array( + + $strings = array( 'upload_title' => __( 'Upload File', 'bp-docs' ), 'upload_button' => __( 'OK', 'bp-docs' ), 'still_working' => __( 'Still working?', 'bp-docs' ), - 'pulse' => bp_docs_heartbeat_pulse(), - ) ); + ); + + if ( bp_docs_is_doc_edit() ) { + $strings['pulse'] = bp_docs_heartbeat_pulse(); + } + wp_localize_script( 'bp-docs-js', 'bp_docs', $strings ); } } diff --git a/includes/edit-lock.php b/includes/edit-lock.php index e76d653b..5b8ad81b 100644 --- a/includes/edit-lock.php +++ b/includes/edit-lock.php @@ -47,10 +47,55 @@ function bp_docs_heartbeat_callback( $response, $data ) { $doc_id = intval( $data['doc_id'] ); - update_post_meta( $doc_id, '_bp_docs_last_pinged', time() ); + if ( ! $doc_id ) { + return $response; + } + + $uid = bp_loggedin_user_id(); + + $lock = bp_docs_check_post_lock( $doc_id ); + + // No lock, or belongs to the current user + if ( empty( $lock ) || $lock == bp_loggedin_user_id() ) { + $time = time(); + $lstring = "$time:$uid"; + update_post_meta( $doc_id, '_bp_docs_last_pinged', $lstring ); + + // Someone else is editing, so bounce + } else { + $bounce = bp_docs_get_doc_link( $doc_id ); + $by = new WP_User( $lock ); + if ( ! empty( $by->user_nicename ) ) { + $bounce = add_query_arg( 'by', $by->user_nicename, $bounce ); + } + $response['bp_docs_bounce'] = $bounce; + } + + return $response; } add_filter( 'heartbeat_received', 'bp_docs_heartbeat_callback', 10, 2 ); +/** + * Prevent a user from visiting the Edit page if it's locked. + * + * @since 1.6.0 + */ +function bp_docs_edit_lock_redirect() { + if ( ! bp_docs_is_doc_edit() ) { + return; + } + + $doc_id = get_queried_object_id(); + + $lock = bp_docs_check_post_lock( $doc_id ); + + if ( ! empty( $lock ) && $lock != bp_loggedin_user_id() ) { + $bounce = bp_docs_get_doc_link( $doc_id ); + wp_redirect( $bounce ); + } +} +add_action( 'bp_actions', 'bp_docs_edit_lock_redirect' ); + /** * Check to see if the post is currently being edited by another user. * @@ -66,21 +111,19 @@ function bp_docs_check_post_lock( $post_id ) { if ( !$post = get_post( $post_id ) ) return false; - if ( !$lock = get_post_meta( $post->ID, '_edit_lock', true ) ) + if ( !$lock = get_post_meta( $post->ID, '_bp_docs_last_pinged', true ) ) return false; $lock = explode( ':', $lock ); $time = $lock[0]; $user = isset( $lock[1] ) ? $lock[1] : get_post_meta( $post->ID, '_edit_last', true ); - $last_checked = get_post_meta( $post->ID, '_bp_docs_last_pinged', true ); - $heartbeat_interval = bp_docs_heartbeat_pulse(); // Bail out of the lock if four pings have been missed (one minute, by default) $time_window = apply_filters( 'bp_docs_post_lock_interval', $heartbeat_interval * 4 ); - if ( $last_checked && $last_checked > time() - $time_window && $user != get_current_user_id() ) { + if ( $time && $time > time() - $time_window && $user != get_current_user_id() ) { return $user; } @@ -231,7 +274,7 @@ function bp_docs_remove_edit_lock() { if ( !$doc_id ) return false; - delete_post_meta( $doc_id, '_edit_lock' ); + delete_post_meta( $doc_id, '_bp_docs_last_pinged' ); } add_action( 'wp_ajax_remove_edit_lock', 'bp_docs_remove_edit_lock' ); @@ -263,12 +306,17 @@ function bp_docs_add_edit_lock_cb() { return; } + // Is this post already locked? + $lock = bp_docs_check_post_lock( $doc_id ); + if ( ! empty( $lock ) && $lock != bp_loggedin_user_id() ) { + die(); + } + $now = time(); $user_id = bp_loggedin_user_id(); $lock = "$now:$user_id"; - update_post_meta( $doc->ID, '_edit_lock', $lock ); - update_post_meta( $doc_id, '_bp_docs_last_pinged', $now ); + update_post_meta( $doc_id, '_bp_docs_last_pinged', $lock ); die( json_encode( '1' ) ); } diff --git a/includes/js/bp-docs.js b/includes/js/bp-docs.js index 46deb2f9..35ec584c 100644 --- a/includes/js/bp-docs.js +++ b/includes/js/bp-docs.js @@ -182,6 +182,14 @@ jQuery(document).ready(function($){ data['doc_id'] = $('#existing-doc-id').val(); }); + // Increment newest_activities and activity_last_id if data has been returned + $( document ).on( 'heartbeat-tick', function( e, data ) { + if ( ! data['bp_docs_bounce'] ) { + return; + } + + window.location = data['bp_docs_bounce']; + }); /** * Collapse the Tags filter section */ From fc72a6e1e59c7666be95c417b8905a0ef03297fb Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Tue, 11 Mar 2014 22:03:50 -0400 Subject: [PATCH 18/35] More consistent styling for Lock toggle --- includes/css/screen.css | 2 +- includes/scss/screen.scss | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/includes/css/screen.css b/includes/css/screen.css index a9b5e97c..4eb4cd8e 100644 --- a/includes/css/screen.css +++ b/includes/css/screen.css @@ -1 +1 @@ -.hide-if-no-js{display:none}.description{font-weight:normal;font-style:italic}.description code{font-style:normal;background:#eee;padding:2px 4px}#bp-create-doc-button{float:right;margin:5px 19px;font-weight:bold}body.bp-docs div.page ul{list-style-type:none}#bp-docs-all-docs{width:auto}.doc-tabs{overflow:hidden}.doc-tabs ul{padding-left:0}.doc-tabs li{float:left;margin:0 5px;list-style-type:none}.doc-tabs li:first-child{margin-left:0}.doc-tabs li a{background:#f1f1f1;text-decoration:none;display:block;padding:4px 10px;border-radius:5px 5px 0 0}.doc-tabs li.current a{background:#f3f3f3;color:#555;font-weight:bold}.doc-header h4{margin-bottom:15px !important}.docs-filter{display:block;width:400px;float:left;margin-bottom:15px}.doc-search{float:right;width:250px;text-align:right}.docs-filter-tags{width:100%}.docs-filter-tags ul li{display:block;width:120px;float:left;padding:6px}.doctable{border-collapse:separate;border-spacing:0}.doctable p{padding:0;margin:0}.doctable tr:hover .row-actions{visibility:visible}.doctable tr:nth-child(even){background-color:#f3f3f3}.doctable .bp-doc-trashed-doc .attachment-clip-cell{border-left:4px solid red}.bp-docs-trashed-doc-notice{color:red;font-size:.9em;font-style:italic}#buddypress #bp-docs-all-docs li{background:#eee}#buddypress div.doc-permissions{float:none;width:auto;margin-bottom:1em}#buddypress table.doctable td{vertical-align:top}#buddypress table.doctable tr:nth-child(even){background-color:#f3f3f3}#buddypress table.doctable tr th{background-color:#f3f3f3}.row-actions{visibility:hidden;padding:2px 0 0}body.mobile .row-actions{visibility:visible}.row-actions a{color:#999;font-size:11px}.row-actions a.delete{color:#f00}#docs-filter-submit{margin:10px 4px}.title-cell{width:30%}.author-cell,.created-date-cell,.edited-date-cell{text-align:center;width:100px}.current-orderby a{padding-left:20px}.asc a{background:url(../images/sort-col-asc.gif) no-repeat}.desc a{background:url(../images/sort-col-desc.gif) no-repeat}.doc-edit-link{margin:15px 0 20px 0}.doc-meta,#doc-meta,.docs #comments{padding-top:20px;border-top:1px solid #ddd}div.docs-info-header{background:#f3f3f3;padding:5px 10px;margin-bottom:10px}#associated_group_summary .item{padding-top:1em}#associated_group_summary .meta{font-size:11px;color:#888}#associated_group_summary img.avatar{margin-left:0}#doc-attachments-ul{margin-top:1em;list-style-type:none}#doc-attachments-ul li{margin:0px 5px 0px 0;padding:6px}#doc-attachments-ul li.even{background-color:#f3f3f3}#doc-attachments-ul .doc-attachment-delete{float:right;margin-top:.15em;margin-right:.3em}.bp-docs-attachment-clip{cursor:pointer;display:block;margin-top:10px}.doc-attachment-mime-icon{display:block;float:left;width:24px;height:24px;margin-right:5px;background:transparent url("../images/mime-type-sprites.png") no-repeat}.doc-attachment-mime-tar,.doc-attachment-mime-zip,.doc-attachment-mime-gz,.doc-attachment-mime-gzip,.doc-attachment-mime-rar,.doc-attachment-mime-7z{background-position:0 0px}.doc-attachment-mime-mp3,.doc-attachment-mime-m4a,.doc-attachment-mime-m4b,.doc-attachment-mime-ra,.doc-attachment-mime-ram,.doc-attachment-mime-wav,.doc-attachment-mime-ogg,.doc-attachment-mime-oga,.doc-attachment-mime-mid,.doc-attachment-mime-midi,.doc-attachment-mime-wma,.doc-attachment-mime-mka{background-position:0 -40px}.doc-attachment-mime-ics{background-position:0 -80px}.doc-attachment-mime-mdb,.doc-attachment-mime-odb{background-position:0 -120px}.doc-attachment-mime-odg{background-position:0 -160px}.doc-attachment-mime-jpg,.doc-attachment-mime-jpeg,.doc-attachment-mime-gif,.doc-attachment-mime-png,.doc-attachment-mime-bmp,.doc-attachment-mime-tif,.doc-attachment-mime-tiff,.doc-attachment-mime-ico{background-position:0 -200px}.doc-attachment-mime-pdf{background-position:0 -240px}.doc-attachment-mime-xla,.doc-attachment-mime-xls,.doc-attachment-mime-xlt,.doc-attachment-mime-xlw,.doc-attachment-mime-xlsx,.doc-attachment-mime-xlsm,.doc-attachment-mime-xlsb,.doc-attachment-mime-xlsb,.doc-attachment-mime-xlsx,.doc-attachment-mime-xlsm,.doc-attachment-mime-xlam,.doc-attachment-mime-ods,.doc-attachment-mime-odc{background-position:0 -280px}.doc-attachment-mime-txt,.doc-attachment-mime-asc,.doc-attachment-mime-c,.doc-attachment-mime-cc,.doc-attachment-mime-h,.doc-attachment-mime-csv,.doc-attachment-mime-tsv,.doc-attachment-mime-ics,.doc-attachment-mime-rtx,.doc-attachment-mime-css,.doc-attachment-mime-htm,.doc-attachment-mime-html{background-position:0 -320px}.doc-attachment-mime-asf,.doc-attachment-mime-asx,.doc-attachment-mime-wax,.doc-attachment-mime-wmv,.doc-attachment-mime-wmx,.doc-attachment-mime-avi,.doc-attachment-mime-divx,.doc-attachment-mime-flv,.doc-attachment-mime-mov,.doc-attachment-mime-qt,.doc-attachment-mime-mpeg,.doc-attachment-mime-mpg,.doc-attachment-mime-mpe,.doc-attachment-mime-mp4,.doc-attachment-mime-m4v,.doc-attachment-mime-ogv,.doc-attachment-mime-mkv{background-position:0 -360px}body.js .bp-docs-attachment-drawer{display:none}.bp-docs-attachment-drawer h4{margin:.5em 0}.bp-docs-attachment-drawer>ul{list-style-type:none}.bp-docs-attachment-drawer>ul>li{margin-left:0}.toggleable.toggle-closed .toggle-content{display:none}.hide-pane,.show-pane,.paperclip-vertical,.paperclip-jaunty{background:url("../images/bp-docs-ui-sprites.png") no-repeat;display:block;float:left;margin-left:10px;margin-top:5px}.hide-pane{background-position:0 0;width:16px;height:16px}.show-pane{background-position:0 -28px;width:16px;height:16px}.paperclip-vertical{background-position:0 -55px;width:13px;height:36px}.paperclip-jaunty{background-position:0 -105px;width:17px;height:36px}.toggle-switch,.entry-content p.toggle-switch{display:block;font-size:1em;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;border:1px solid #ccc;background-color:#f3f3f3;padding:3px 0;text-indent:16px;margin:16px 0 0}.toggle-switch.active-switch,.entry-content p.toggle-switch.active-switch{-moz-border-radius-bottomleft:10px;-webkit-border-bottom-left-radius:10px;-moz-border-radius-bottomright:10px;-webkit-border-bottom-right-radius:10px;border-radius:3px 3px 0px 0px}.toggle-switch a,.entry-content p.toggle-switch a{color:#757575;text-decoration:none;display:block;width:100%;height:100%}.toggle-switch a:hover,.entry-content p.toggle-switch a:hover{font-weight:bold}.standard-form label.toggle-switch{margin:16px 0 0}.toggle-content{-moz-border-radius-bottomleft:2px;-webkit-border-bottom-left-radius:2px;-moz-border-radius-bottomright:2px;-webkit-border-bottom-right-radius:2px;border:1px solid #ccc;border-top:none;overflow:hidden}td.desc-column{width:300px;padding:0px 18px 12px}.docs-info-header .docs-filter{margin-bottom:0}#docs-filter-meta{font-size:.8em;color:#666;margin-bottom:0}a.docs-filter-title{margin:0 7px;text-decoration:none}a.docs-filter-title:visited{color:inherit}a.docs-filter-title.current{font-weight:bold}.docs-filter-section{border:1px solid #ccc;border-radius:2px;font-size:.8em;padding:6px 10px;margin-top:8px;transition:max-height 2s ease;overflow:hidden;position:relative}#docs-filter-section-tags a.tags-action-button,#docs-filter-section-tags a.tags-action-button:visited{display:inline;line-height:3em;text-decoration:none;background:#fff;background-opacity:.5;padding:5px 10px;border-radius:3px}body.js .docs-filter-section{display:none}body.js .docs-filter-section.docs-filter-section-open{display:block}p.currently-viewing{margin-bottom:5px;font-size:.8em;margin-top:8px}p#filter-by-tag{margin-bottom:0}.docs-info-header .toggle-switch{margin-top:8px}ul#tags-list{list-style-type:none;margin-bottom:0;padding:0;-moz-column-count:2;-moz-column-gap:10%;-webkit-column-count:2;-webkit-column-gap:10%;column-count:2;column-gap:10%}ul#tags-list li{margin-left:0}ul#tags-list li.hidden-tag{display:none}ul#tags-list li.tags-ellipses{font-style:italic}.groups-cell ul li img.avatar{float:none}.groups-cell ul li a{vertical-align:middle;font-size:.85em}.groups-cell ul{list-style-type:none;padding-left:0}.groups-cell ul li{margin-bottom:.5em}select#has-attachment{margin:8px 10px}div#bp-docs-pagination{position:relative;height:30px}div#bp-docs-pagination-count{position:absolute;left:0;top:5px;font-size:.9em;color:#999}div#bp-docs-paginate-links{position:absolute;right:0;top:5px}div#bp-docs-paginate-links a{padding:0 4px}div.doc-content{padding:20px;border:3px solid #f3f3f3}div.doc-content img{margin:10px}div.doc-content img.mceIcon{margin:0}#bp-docs-single-doc-header{overflow:hidden}body.trashed-doc #buddypress{border-left:4px solid red;padding-left:10px}div.doc-permissions{float:right;width:35%;background:#f0f0f0;border:1px solid #ddd;border-radius:3px;padding:4px}div.doc-permissions div:last-child{clear:both}#doc-permissions-summary,#doc-group-summary{font-size:1.0em;padding:3px 12px;border:1px solid}#doc-permissions-summary.doc-public{background:#b2ffb2;border-color:#00ff00}#doc-permissions-summary.doc-limited{background:#ffffe0;border-color:#e6db55}#doc-permissions-summary.doc-private{background:#ffebe8;border-color:#ff0000}a.doc-permissions-toggle{display:block;float:right;font-size:12px;cursor:hand}dl.doc-permissions-types dd,dl.doc-permissions-types dt{height:1.5em}dl.doc-permissions-types dt{width:50%;float:left;clear:left}#doc-group-summary{border-color:#f0f0f0}#doc-group-summary img.avatar{float:none}#doc-permissions-details ul{list-style-type:none;padding-left:0}#doc-permissions-details ul li{margin-bottom:.5em}span.bp-docs-level-icon{display:block;float:left;width:1.2em;height:1.2em;margin:3px 5px}.bp-docs-level-anyone span.bp-docs-level-icon{-moz-border-radius:.6em;-webkit-border-radius:.6em;border-radius:.6em;background:green}.bp-docs-level-friends span.bp-docs-level-icon,.bp-docs-level-loggedin span.bp-docs-level-icon,.bp-docs-level-group-members span.bp-docs-level-icon{width:0;height:0;border-left:.6em solid transparent;border-right:.6em solid transparent;border-bottom:1.2em solid yellow}.bp-docs-level-admins-mods span.bp-docs-level-icon,.bp-docs-level-no-one span.bp-docs-level-icon,.bp-docs-level-creator span.bp-docs-level-icon{background:red}div.doc-is-locked .toggle-switch{display:block;background:#bbb url(../images/padlock.gif) no-repeat;text-indent:25px;padding-top:3px}div.doc-is-locked .toggle-content{border:2px solid #f33;margin-top:5px;padding:7px 10px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}div.doc-meta p{margin-bottom:5px}a.nonexistent-doc{color:#f33}h2.doc-title{display:inline-block;width:50%}.comments-closed{padding:10px 20px;background:#f3f3f3;margin-top:10px}#respond{margin-top:20px}.doc-content ul{list-style:disc}.doc-content ol{list-style:decimal}.doc-content li{margin-left:20px}.doc-content blockquote{background:#f3f3f3;padding:5px;margin:10px 30px}div.hidden{display:none}table.group-docs-options td.label{width:200px}table.diff{width:100%}table.diff col.content{width:50%}table.diff tr{background-color:transparent}table.diff td,table.diff th{padding:.5em;font-family:Consolas, Monaco, Courier, monospace;border:none}table.diff .diff-deletedline del,table.diff .diff-addedline ins{text-decoration:none}table.diff .diff-deletedline{background-color:#fdd}table.diff .diff-deletedline del{background-color:#f99}table.diff .diff-addedline{background-color:#dfd}table.diff .diff-addedline ins{background-color:#9f9}#att-info{background-color:#E4F2FD}table#post-revisions{margin-top:20px}@media screen and (min-width: 4em){#docs-filter-section-tags a.tags-action-button,#docs-filter-section-tags a.tags-action-button:visited{display:block;margin-bottom:1em;padding:0;text-align:center}}@media screen and (min-width: 50em){.entry-content ul#tags-list{-moz-column-count:4;-moz-column-gap:5%;-webkit-column-count:4;-webkit-column-gap:5%;column-count:4;column-gap:5%}}@media screen and (min-width: 71em){.entry-content ul#tags-list{-moz-column-count:5;-moz-column-gap:5%;-webkit-column-count:5;-webkit-column-gap:5%;column-count:5;column-gap:5%}} +.hide-if-no-js{display:none}.description{font-weight:normal;font-style:italic}.description code{font-style:normal;background:#eee;padding:2px 4px}#bp-create-doc-button{float:right;margin:5px 19px;font-weight:bold}body.bp-docs div.page ul{list-style-type:none}#bp-docs-all-docs{width:auto}.doc-tabs{overflow:hidden}.doc-tabs ul{padding-left:0}.doc-tabs li{float:left;margin:0 5px;list-style-type:none}.doc-tabs li:first-child{margin-left:0}.doc-tabs li a{background:#f1f1f1;text-decoration:none;display:block;padding:4px 10px;border-radius:5px 5px 0 0}.doc-tabs li.current a{background:#f3f3f3;color:#555;font-weight:bold}.doc-header h4{margin-bottom:15px !important}.docs-filter{display:block;width:400px;float:left;margin-bottom:15px}.doc-search{float:right;width:250px;text-align:right}.docs-filter-tags{width:100%}.docs-filter-tags ul li{display:block;width:120px;float:left;padding:6px}.doctable{border-collapse:separate;border-spacing:0}.doctable p{padding:0;margin:0}.doctable tr:hover .row-actions{visibility:visible}.doctable tr:nth-child(even){background-color:#f3f3f3}.doctable .bp-doc-trashed-doc .attachment-clip-cell{border-left:4px solid red}.bp-docs-trashed-doc-notice{color:red;font-size:.9em;font-style:italic}#buddypress #bp-docs-all-docs li{background:#eee}#buddypress div.doc-permissions{float:none;width:auto;margin-bottom:1em}#buddypress table.doctable td{vertical-align:top}#buddypress table.doctable tr:nth-child(even){background-color:#f3f3f3}#buddypress table.doctable tr th{background-color:#f3f3f3}.row-actions{visibility:hidden;padding:2px 0 0}body.mobile .row-actions{visibility:visible}.row-actions a{color:#999;font-size:11px}.row-actions a.delete{color:#f00}#docs-filter-submit{margin:10px 4px}.title-cell{width:30%}.author-cell,.created-date-cell,.edited-date-cell{text-align:center;width:100px}.current-orderby a{padding-left:20px}.asc a{background:url(../images/sort-col-asc.gif) no-repeat}.desc a{background:url(../images/sort-col-desc.gif) no-repeat}.doc-edit-link{margin:15px 0 20px 0}.doc-meta,#doc-meta,.docs #comments{padding-top:20px;border-top:1px solid #ddd}div.docs-info-header{background:#f3f3f3;padding:5px 10px;margin-bottom:10px}#associated_group_summary .item{padding-top:1em}#associated_group_summary .meta{font-size:11px;color:#888}#associated_group_summary img.avatar{margin-left:0}#doc-attachments-ul{margin-top:1em;list-style-type:none}#doc-attachments-ul li{margin:0px 5px 0px 0;padding:6px}#doc-attachments-ul li.even{background-color:#f3f3f3}#doc-attachments-ul .doc-attachment-delete{float:right;margin-top:.15em;margin-right:.3em}.bp-docs-attachment-clip{cursor:pointer;display:block;margin-top:10px}.doc-attachment-mime-icon{display:block;float:left;width:24px;height:24px;margin-right:5px;background:transparent url("../images/mime-type-sprites.png") no-repeat}.doc-attachment-mime-tar,.doc-attachment-mime-zip,.doc-attachment-mime-gz,.doc-attachment-mime-gzip,.doc-attachment-mime-rar,.doc-attachment-mime-7z{background-position:0 0px}.doc-attachment-mime-mp3,.doc-attachment-mime-m4a,.doc-attachment-mime-m4b,.doc-attachment-mime-ra,.doc-attachment-mime-ram,.doc-attachment-mime-wav,.doc-attachment-mime-ogg,.doc-attachment-mime-oga,.doc-attachment-mime-mid,.doc-attachment-mime-midi,.doc-attachment-mime-wma,.doc-attachment-mime-mka{background-position:0 -40px}.doc-attachment-mime-ics{background-position:0 -80px}.doc-attachment-mime-mdb,.doc-attachment-mime-odb{background-position:0 -120px}.doc-attachment-mime-odg{background-position:0 -160px}.doc-attachment-mime-jpg,.doc-attachment-mime-jpeg,.doc-attachment-mime-gif,.doc-attachment-mime-png,.doc-attachment-mime-bmp,.doc-attachment-mime-tif,.doc-attachment-mime-tiff,.doc-attachment-mime-ico{background-position:0 -200px}.doc-attachment-mime-pdf{background-position:0 -240px}.doc-attachment-mime-xla,.doc-attachment-mime-xls,.doc-attachment-mime-xlt,.doc-attachment-mime-xlw,.doc-attachment-mime-xlsx,.doc-attachment-mime-xlsm,.doc-attachment-mime-xlsb,.doc-attachment-mime-xlsb,.doc-attachment-mime-xlsx,.doc-attachment-mime-xlsm,.doc-attachment-mime-xlam,.doc-attachment-mime-ods,.doc-attachment-mime-odc{background-position:0 -280px}.doc-attachment-mime-txt,.doc-attachment-mime-asc,.doc-attachment-mime-c,.doc-attachment-mime-cc,.doc-attachment-mime-h,.doc-attachment-mime-csv,.doc-attachment-mime-tsv,.doc-attachment-mime-ics,.doc-attachment-mime-rtx,.doc-attachment-mime-css,.doc-attachment-mime-htm,.doc-attachment-mime-html{background-position:0 -320px}.doc-attachment-mime-asf,.doc-attachment-mime-asx,.doc-attachment-mime-wax,.doc-attachment-mime-wmv,.doc-attachment-mime-wmx,.doc-attachment-mime-avi,.doc-attachment-mime-divx,.doc-attachment-mime-flv,.doc-attachment-mime-mov,.doc-attachment-mime-qt,.doc-attachment-mime-mpeg,.doc-attachment-mime-mpg,.doc-attachment-mime-mpe,.doc-attachment-mime-mp4,.doc-attachment-mime-m4v,.doc-attachment-mime-ogv,.doc-attachment-mime-mkv{background-position:0 -360px}body.js .bp-docs-attachment-drawer{display:none}.bp-docs-attachment-drawer h4{margin:.5em 0}.bp-docs-attachment-drawer>ul{list-style-type:none}.bp-docs-attachment-drawer>ul>li{margin-left:0}.toggleable.toggle-closed .toggle-content{display:none}.hide-pane,.show-pane,.paperclip-vertical,.paperclip-jaunty{background:url("../images/bp-docs-ui-sprites.png") no-repeat;display:block;float:left;margin-left:10px;margin-top:5px}.hide-pane{background-position:0 0;width:16px;height:16px}.show-pane{background-position:0 -28px;width:16px;height:16px}.paperclip-vertical{background-position:0 -55px;width:13px;height:36px}.paperclip-jaunty{background-position:0 -105px;width:17px;height:36px}.toggle-switch,.entry-content p.toggle-switch{display:block;font-size:1em;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;border:1px solid #ccc;background-color:#f3f3f3;padding:3px 0;text-indent:16px;margin:16px 0 0}.toggle-switch.active-switch,.entry-content p.toggle-switch.active-switch{-moz-border-radius-bottomleft:10px;-webkit-border-bottom-left-radius:10px;-moz-border-radius-bottomright:10px;-webkit-border-bottom-right-radius:10px;border-radius:3px 3px 0px 0px}.toggle-switch a,.entry-content p.toggle-switch a{color:#757575;text-decoration:none;display:block;width:100%;height:100%}.toggle-switch a:hover,.entry-content p.toggle-switch a:hover{font-weight:bold}.standard-form label.toggle-switch{margin:16px 0 0}.toggle-content{-moz-border-radius-bottomleft:2px;-webkit-border-bottom-left-radius:2px;-moz-border-radius-bottomright:2px;-webkit-border-bottom-right-radius:2px;border:1px solid #ccc;border-top:none;overflow:hidden}td.desc-column{width:300px;padding:0px 18px 12px}.docs-info-header .docs-filter{margin-bottom:0}#docs-filter-meta{font-size:.8em;color:#666;margin-bottom:0}a.docs-filter-title{margin:0 7px;text-decoration:none}a.docs-filter-title:visited{color:inherit}a.docs-filter-title.current{font-weight:bold}.docs-filter-section{border:1px solid #ccc;border-radius:2px;font-size:.8em;padding:6px 10px;margin-top:8px;transition:max-height 2s ease;overflow:hidden;position:relative}#docs-filter-section-tags a.tags-action-button,#docs-filter-section-tags a.tags-action-button:visited{display:inline;line-height:3em;text-decoration:none;background:#fff;background-opacity:.5;padding:5px 10px;border-radius:3px}body.js .docs-filter-section{display:none}body.js .docs-filter-section.docs-filter-section-open{display:block}p.currently-viewing{margin-bottom:5px;font-size:.8em;margin-top:8px}p#filter-by-tag{margin-bottom:0}.docs-info-header .toggle-switch{margin-top:8px}ul#tags-list{list-style-type:none;margin-bottom:0;padding:0;-moz-column-count:2;-moz-column-gap:10%;-webkit-column-count:2;-webkit-column-gap:10%;column-count:2;column-gap:10%}ul#tags-list li{margin-left:0}ul#tags-list li.hidden-tag{display:none}ul#tags-list li.tags-ellipses{font-style:italic}.groups-cell ul li img.avatar{float:none}.groups-cell ul li a{vertical-align:middle;font-size:.85em}.groups-cell ul{list-style-type:none;padding-left:0}.groups-cell ul li{margin-bottom:.5em}select#has-attachment{margin:8px 10px}div#bp-docs-pagination{position:relative;height:30px}div#bp-docs-pagination-count{position:absolute;left:0;top:5px;font-size:.9em;color:#999}div#bp-docs-paginate-links{position:absolute;right:0;top:5px}div#bp-docs-paginate-links a{padding:0 4px}div.doc-content{padding:20px;border:3px solid #f3f3f3}div.doc-content img{margin:10px}div.doc-content img.mceIcon{margin:0}#bp-docs-single-doc-header{overflow:hidden}body.trashed-doc #buddypress{border-left:4px solid red;padding-left:10px}div.doc-permissions{float:right;width:35%;background:#f0f0f0;border:1px solid #ddd;border-radius:3px;padding:4px}div.doc-permissions div:last-child{clear:both}#doc-permissions-summary,#doc-group-summary{font-size:1.0em;padding:3px 12px;border:1px solid}#doc-permissions-summary.doc-public{background:#b2ffb2;border-color:#00ff00}#doc-permissions-summary.doc-limited{background:#ffffe0;border-color:#e6db55}#doc-permissions-summary.doc-private{background:#ffebe8;border-color:#ff0000}a.doc-permissions-toggle{display:block;float:right;font-size:12px;cursor:hand}dl.doc-permissions-types dd,dl.doc-permissions-types dt{height:1.5em}dl.doc-permissions-types dt{width:50%;float:left;clear:left}#doc-group-summary{border-color:#f0f0f0}#doc-group-summary img.avatar{float:none}#doc-permissions-details ul{list-style-type:none;padding-left:0}#doc-permissions-details ul li{margin-bottom:.5em}span.bp-docs-level-icon{display:block;float:left;width:1.2em;height:1.2em;margin:3px 5px}.bp-docs-level-anyone span.bp-docs-level-icon{-moz-border-radius:.6em;-webkit-border-radius:.6em;border-radius:.6em;background:green}.bp-docs-level-friends span.bp-docs-level-icon,.bp-docs-level-loggedin span.bp-docs-level-icon,.bp-docs-level-group-members span.bp-docs-level-icon{width:0;height:0;border-left:.6em solid transparent;border-right:.6em solid transparent;border-bottom:1.2em solid yellow}.bp-docs-level-admins-mods span.bp-docs-level-icon,.bp-docs-level-no-one span.bp-docs-level-icon,.bp-docs-level-creator span.bp-docs-level-icon{background:red}div.doc-is-locked .toggle-content{border:2px solid #f33;margin-top:5px;padding:7px 10px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}div.doc-meta p{margin-bottom:5px}a.nonexistent-doc{color:#f33}h2.doc-title{display:inline-block;width:50%}.comments-closed{padding:10px 20px;background:#f3f3f3;margin-top:10px}#respond{margin-top:20px}.doc-content ul{list-style:disc}.doc-content ol{list-style:decimal}.doc-content li{margin-left:20px}.doc-content blockquote{background:#f3f3f3;padding:5px;margin:10px 30px}div.hidden{display:none}table.group-docs-options td.label{width:200px}table.diff{width:100%}table.diff col.content{width:50%}table.diff tr{background-color:transparent}table.diff td,table.diff th{padding:.5em;font-family:Consolas, Monaco, Courier, monospace;border:none}table.diff .diff-deletedline del,table.diff .diff-addedline ins{text-decoration:none}table.diff .diff-deletedline{background-color:#fdd}table.diff .diff-deletedline del{background-color:#f99}table.diff .diff-addedline{background-color:#dfd}table.diff .diff-addedline ins{background-color:#9f9}#att-info{background-color:#E4F2FD}table#post-revisions{margin-top:20px}@media screen and (min-width: 4em){#docs-filter-section-tags a.tags-action-button,#docs-filter-section-tags a.tags-action-button:visited{display:block;margin-bottom:1em;padding:0;text-align:center}}@media screen and (min-width: 50em){.entry-content ul#tags-list{-moz-column-count:4;-moz-column-gap:5%;-webkit-column-count:4;-webkit-column-gap:5%;column-count:4;column-gap:5%}}@media screen and (min-width: 71em){.entry-content ul#tags-list{-moz-column-count:5;-moz-column-gap:5%;-webkit-column-count:5;-webkit-column-gap:5%;column-count:5;column-gap:5%}} diff --git a/includes/scss/screen.scss b/includes/scss/screen.scss index a2fa3936..9475332c 100644 --- a/includes/scss/screen.scss +++ b/includes/scss/screen.scss @@ -731,14 +731,6 @@ span.bp-docs-level-icon { background: red; } - -div.doc-is-locked .toggle-switch { - display: block; - background: #bbb url(../images/padlock.gif) no-repeat; - text-indent: 25px; - padding-top: 3px; -} - div.doc-is-locked .toggle-content { border: 2px solid #f33; margin-top: 5px; From a8400075540ac419d785d6877a09b38b69e6acbf Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Tue, 11 Mar 2014 22:04:34 -0400 Subject: [PATCH 19/35] Readme --- readme.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.txt b/readme.txt index 6a328652..782cd759 100755 --- a/readme.txt +++ b/readme.txt @@ -36,6 +36,7 @@ This plugin is in active development. For feature requests and bug reports, visi = 1.6.0 = * Overhaul of the way group/user tag clouds work * Improved support for attachments on nginx and IIS +* Improved doc edit locking mechanisms = 1.5.7 = * Improve appearance of row actions on mobile devices From 55dea12683418e312999588c95e1863c215ae6f1 Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Tue, 11 Mar 2014 22:06:13 -0400 Subject: [PATCH 20/35] Fix Force Cancel lock links --- includes/component.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/component.php b/includes/component.php index 249c8541..440a566e 100644 --- a/includes/component.php +++ b/includes/component.php @@ -471,7 +471,7 @@ function catch_page_load() { $doc = bp_docs_get_current_doc(); // Todo: get this into a proper method as well, blech - delete_post_meta( $doc->ID, '_edit_lock' ); + delete_post_meta( $doc->ID, '_bp_docs_last_pinged' ); bp_core_add_message( __( 'Lock successfully removed', 'bp-docs' ) ); bp_core_redirect( bp_docs_get_doc_link( $doc->ID ) ); @@ -484,7 +484,7 @@ function catch_page_load() { $doc = bp_docs_get_current_doc(); // Todo: get this into a proper method as well, blech - delete_post_meta( $doc->ID, '_edit_lock' ); + delete_post_meta( $doc->ID, '_bp_docs_last_pinged' ); bp_core_redirect( bp_docs_get_doc_link( $doc->ID ) ); } From ded6aee2de4edc33068f5ab1d24d95854b8e66dc Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Wed, 12 Mar 2014 13:36:49 -0400 Subject: [PATCH 21/35] Check for WP_Error when querying for attachment accessibility. See 6322b1 Props @dcavins --- includes/attachments.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/attachments.php b/includes/attachments.php index 0e6b71e3..6c02ceac 100644 --- a/includes/attachments.php +++ b/includes/attachments.php @@ -789,7 +789,7 @@ public function check_is_protected( $force_check = true ) { // If the response body includes our test text, we have a problem $is_protected = true; - if ( $r['body'] === $test_text ) { + if ( ! is_wp_error( $r ) && $r['body'] === $test_text ) { $is_protected = false; } From 3fc07775299c34ad6d39e25d1a0800534ce0b037 Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Wed, 12 Mar 2014 13:38:52 -0400 Subject: [PATCH 22/35] Use plugin_dir_path() to build includes path --- bp-docs.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bp-docs.php b/bp-docs.php index 37650b13..3d84b43e 100644 --- a/bp-docs.php +++ b/bp-docs.php @@ -175,8 +175,9 @@ function load_constants() { } // You should never really need to override this bad boy - if ( !defined( 'BP_DOCS_INSTALL_PATH' ) ) - define( 'BP_DOCS_INSTALL_PATH', WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . BP_DOCS_PLUGIN_SLUG . DIRECTORY_SEPARATOR ); + if ( !defined( 'BP_DOCS_INSTALL_PATH' ) ) { + define( 'BP_DOCS_INSTALL_PATH', plugin_dir_path( __FILE__ ) ); + } // Ditto if ( !defined( 'BP_DOCS_INCLUDES_PATH' ) ) From fe8679034c19cdfa3c19735e3a750ae427478f4d Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Wed, 12 Mar 2014 13:49:10 -0400 Subject: [PATCH 23/35] Some unit test fixes --- tests/test-bp-docs.php | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/tests/test-bp-docs.php b/tests/test-bp-docs.php index 59345a5d..f397b16a 100644 --- a/tests/test-bp-docs.php +++ b/tests/test-bp-docs.php @@ -76,21 +76,23 @@ function test_change_group_association() { $group = $this->factory->group->create(); $group2 = $this->factory->group->create(); - $doc_id = $this->factory->doc->create( array( 'group' => $group->id ) ); + $doc_id = $this->factory->doc->create( array( + 'group' => $group, + ) ); - bp_docs_set_associated_group_id( $doc_id, $group2->id ); + bp_docs_set_associated_group_id( $doc_id, $group ); - $this->assertEquals( bp_docs_get_associated_group_id( $doc_id ), $group2->id ); + $this->assertEquals( bp_docs_get_associated_group_id( $doc_id ), $group ); } function test_set_group_association_on_create() { - $doc_id = $this->factory->doc->create( array( 'group' => $group->id ) ); - $group = $this->factory->group->create(); + $doc_id = $this->factory->doc->create( array( 'group' => $group ) ); + $permalink = get_permalink( $doc_id ); $this->go_to( $permalink ); - $_POST['associated_group_id'] = $group->id; + $_POST['associated_group_id'] = $group; //unset( $_POST['associated_group_id'] ); // We need this dummy $_POST data to make the save go through. Ugh @@ -103,12 +105,14 @@ function test_set_group_association_on_create() { $maybe_group_id = bp_docs_get_associated_group_id( $doc_id ); - $this->assertEquals( $group->id, $maybe_group_id ); + $this->assertEquals( $group, $maybe_group_id ); } function test_delete_group_association() { $group = $this->factory->group->create(); - $doc_id = $this->factory->doc->create( array( 'group' => $group->id ) ); + $doc_id = $this->factory->doc->create( array( + 'group' => $group, + ) ); $permalink = get_permalink( $doc_id ); $this->go_to( $permalink ); @@ -117,6 +121,7 @@ function test_delete_group_association() { // We need this dummy $_POST data to make the save go through. Ugh $doc = $this->factory->doc->get_object_by_id( $doc_id ); + $_POST['doc_id'] = $doc_id; $_POST['doc_content'] = $doc->post_content; $_POST['doc']['title'] = $doc->post_title; From 651208826d5d508401f7fb09806232ec50f4c6dc Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Wed, 12 Mar 2014 13:52:10 -0400 Subject: [PATCH 24/35] Improve query arguments for fetching user tags. See #383 --- includes/integration-users.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/includes/integration-users.php b/includes/integration-users.php index eab48aa5..2ee59721 100644 --- a/includes/integration-users.php +++ b/includes/integration-users.php @@ -167,8 +167,10 @@ function get_user_terms( $terms = array() ) { if ( bp_docs_is_edited_by() ) { $query_args['post__in'] = BP_Docs_Query::get_edited_by_post_ids_for_user( bp_displayed_user_id() ); + $query_args['post_status'] = array( 'publish' ); } else if ( bp_docs_is_started_by() ) { - $query_args['post_author'] = bp_displayed_user_id(); + $query_args['author'] = bp_displayed_user_id(); + $query_args['post_status'] = array( 'publish', 'trash' ); } else { // Just in case $query_args['post__in'] = array( 0 ); From 4854c0ee951961a0038f68093e9199560a521742 Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Wed, 12 Mar 2014 13:56:56 -0400 Subject: [PATCH 25/35] Handle item terms and javascript properly on mygroups directory Fixes #384. Fixes #385 Props @dcavins --- includes/component.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/includes/component.php b/includes/component.php index 440a566e..2dd26f31 100644 --- a/includes/component.php +++ b/includes/component.php @@ -1024,8 +1024,8 @@ function body_class( $classes ) { public function get_item_terms( $terms ) { global $wpdb, $bp; - // Only on global directories - if ( ! bp_docs_is_global_directory() ) { + // Only on global directory and mygroups view + if ( ! bp_docs_is_global_directory() && ! bp_docs_is_mygroups_directory() ) { return $terms; } @@ -1108,7 +1108,7 @@ function enqueue_scripts() { // Only load our JS on the right sorts of pages. Generous to account for // different item types - if ( in_array( bp_docs_get_docs_slug(), $this->slugstocheck ) || bp_docs_is_single_doc() || bp_docs_is_global_directory() || bp_docs_is_doc_create() ) { + if ( in_array( bp_docs_get_docs_slug(), $this->slugstocheck ) || bp_docs_is_single_doc() || bp_docs_is_global_directory() || bp_docs_is_mygroups_directory() || bp_docs_is_doc_create() ) { wp_enqueue_script( 'bp-docs-js' ); wp_enqueue_script( 'comment-reply' ); From fce66eb02146c994d96cf7902823a3df5dda171d Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Wed, 12 Mar 2014 14:16:06 -0400 Subject: [PATCH 26/35] Improved responsiveness in directories --- includes/css/screen.css | 2 +- includes/scss/screen.scss | 60 ++++++++++++++++++++++++++++++--------- readme.txt | 1 + 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/includes/css/screen.css b/includes/css/screen.css index 4eb4cd8e..f8c6be2e 100644 --- a/includes/css/screen.css +++ b/includes/css/screen.css @@ -1 +1 @@ -.hide-if-no-js{display:none}.description{font-weight:normal;font-style:italic}.description code{font-style:normal;background:#eee;padding:2px 4px}#bp-create-doc-button{float:right;margin:5px 19px;font-weight:bold}body.bp-docs div.page ul{list-style-type:none}#bp-docs-all-docs{width:auto}.doc-tabs{overflow:hidden}.doc-tabs ul{padding-left:0}.doc-tabs li{float:left;margin:0 5px;list-style-type:none}.doc-tabs li:first-child{margin-left:0}.doc-tabs li a{background:#f1f1f1;text-decoration:none;display:block;padding:4px 10px;border-radius:5px 5px 0 0}.doc-tabs li.current a{background:#f3f3f3;color:#555;font-weight:bold}.doc-header h4{margin-bottom:15px !important}.docs-filter{display:block;width:400px;float:left;margin-bottom:15px}.doc-search{float:right;width:250px;text-align:right}.docs-filter-tags{width:100%}.docs-filter-tags ul li{display:block;width:120px;float:left;padding:6px}.doctable{border-collapse:separate;border-spacing:0}.doctable p{padding:0;margin:0}.doctable tr:hover .row-actions{visibility:visible}.doctable tr:nth-child(even){background-color:#f3f3f3}.doctable .bp-doc-trashed-doc .attachment-clip-cell{border-left:4px solid red}.bp-docs-trashed-doc-notice{color:red;font-size:.9em;font-style:italic}#buddypress #bp-docs-all-docs li{background:#eee}#buddypress div.doc-permissions{float:none;width:auto;margin-bottom:1em}#buddypress table.doctable td{vertical-align:top}#buddypress table.doctable tr:nth-child(even){background-color:#f3f3f3}#buddypress table.doctable tr th{background-color:#f3f3f3}.row-actions{visibility:hidden;padding:2px 0 0}body.mobile .row-actions{visibility:visible}.row-actions a{color:#999;font-size:11px}.row-actions a.delete{color:#f00}#docs-filter-submit{margin:10px 4px}.title-cell{width:30%}.author-cell,.created-date-cell,.edited-date-cell{text-align:center;width:100px}.current-orderby a{padding-left:20px}.asc a{background:url(../images/sort-col-asc.gif) no-repeat}.desc a{background:url(../images/sort-col-desc.gif) no-repeat}.doc-edit-link{margin:15px 0 20px 0}.doc-meta,#doc-meta,.docs #comments{padding-top:20px;border-top:1px solid #ddd}div.docs-info-header{background:#f3f3f3;padding:5px 10px;margin-bottom:10px}#associated_group_summary .item{padding-top:1em}#associated_group_summary .meta{font-size:11px;color:#888}#associated_group_summary img.avatar{margin-left:0}#doc-attachments-ul{margin-top:1em;list-style-type:none}#doc-attachments-ul li{margin:0px 5px 0px 0;padding:6px}#doc-attachments-ul li.even{background-color:#f3f3f3}#doc-attachments-ul .doc-attachment-delete{float:right;margin-top:.15em;margin-right:.3em}.bp-docs-attachment-clip{cursor:pointer;display:block;margin-top:10px}.doc-attachment-mime-icon{display:block;float:left;width:24px;height:24px;margin-right:5px;background:transparent url("../images/mime-type-sprites.png") no-repeat}.doc-attachment-mime-tar,.doc-attachment-mime-zip,.doc-attachment-mime-gz,.doc-attachment-mime-gzip,.doc-attachment-mime-rar,.doc-attachment-mime-7z{background-position:0 0px}.doc-attachment-mime-mp3,.doc-attachment-mime-m4a,.doc-attachment-mime-m4b,.doc-attachment-mime-ra,.doc-attachment-mime-ram,.doc-attachment-mime-wav,.doc-attachment-mime-ogg,.doc-attachment-mime-oga,.doc-attachment-mime-mid,.doc-attachment-mime-midi,.doc-attachment-mime-wma,.doc-attachment-mime-mka{background-position:0 -40px}.doc-attachment-mime-ics{background-position:0 -80px}.doc-attachment-mime-mdb,.doc-attachment-mime-odb{background-position:0 -120px}.doc-attachment-mime-odg{background-position:0 -160px}.doc-attachment-mime-jpg,.doc-attachment-mime-jpeg,.doc-attachment-mime-gif,.doc-attachment-mime-png,.doc-attachment-mime-bmp,.doc-attachment-mime-tif,.doc-attachment-mime-tiff,.doc-attachment-mime-ico{background-position:0 -200px}.doc-attachment-mime-pdf{background-position:0 -240px}.doc-attachment-mime-xla,.doc-attachment-mime-xls,.doc-attachment-mime-xlt,.doc-attachment-mime-xlw,.doc-attachment-mime-xlsx,.doc-attachment-mime-xlsm,.doc-attachment-mime-xlsb,.doc-attachment-mime-xlsb,.doc-attachment-mime-xlsx,.doc-attachment-mime-xlsm,.doc-attachment-mime-xlam,.doc-attachment-mime-ods,.doc-attachment-mime-odc{background-position:0 -280px}.doc-attachment-mime-txt,.doc-attachment-mime-asc,.doc-attachment-mime-c,.doc-attachment-mime-cc,.doc-attachment-mime-h,.doc-attachment-mime-csv,.doc-attachment-mime-tsv,.doc-attachment-mime-ics,.doc-attachment-mime-rtx,.doc-attachment-mime-css,.doc-attachment-mime-htm,.doc-attachment-mime-html{background-position:0 -320px}.doc-attachment-mime-asf,.doc-attachment-mime-asx,.doc-attachment-mime-wax,.doc-attachment-mime-wmv,.doc-attachment-mime-wmx,.doc-attachment-mime-avi,.doc-attachment-mime-divx,.doc-attachment-mime-flv,.doc-attachment-mime-mov,.doc-attachment-mime-qt,.doc-attachment-mime-mpeg,.doc-attachment-mime-mpg,.doc-attachment-mime-mpe,.doc-attachment-mime-mp4,.doc-attachment-mime-m4v,.doc-attachment-mime-ogv,.doc-attachment-mime-mkv{background-position:0 -360px}body.js .bp-docs-attachment-drawer{display:none}.bp-docs-attachment-drawer h4{margin:.5em 0}.bp-docs-attachment-drawer>ul{list-style-type:none}.bp-docs-attachment-drawer>ul>li{margin-left:0}.toggleable.toggle-closed .toggle-content{display:none}.hide-pane,.show-pane,.paperclip-vertical,.paperclip-jaunty{background:url("../images/bp-docs-ui-sprites.png") no-repeat;display:block;float:left;margin-left:10px;margin-top:5px}.hide-pane{background-position:0 0;width:16px;height:16px}.show-pane{background-position:0 -28px;width:16px;height:16px}.paperclip-vertical{background-position:0 -55px;width:13px;height:36px}.paperclip-jaunty{background-position:0 -105px;width:17px;height:36px}.toggle-switch,.entry-content p.toggle-switch{display:block;font-size:1em;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;border:1px solid #ccc;background-color:#f3f3f3;padding:3px 0;text-indent:16px;margin:16px 0 0}.toggle-switch.active-switch,.entry-content p.toggle-switch.active-switch{-moz-border-radius-bottomleft:10px;-webkit-border-bottom-left-radius:10px;-moz-border-radius-bottomright:10px;-webkit-border-bottom-right-radius:10px;border-radius:3px 3px 0px 0px}.toggle-switch a,.entry-content p.toggle-switch a{color:#757575;text-decoration:none;display:block;width:100%;height:100%}.toggle-switch a:hover,.entry-content p.toggle-switch a:hover{font-weight:bold}.standard-form label.toggle-switch{margin:16px 0 0}.toggle-content{-moz-border-radius-bottomleft:2px;-webkit-border-bottom-left-radius:2px;-moz-border-radius-bottomright:2px;-webkit-border-bottom-right-radius:2px;border:1px solid #ccc;border-top:none;overflow:hidden}td.desc-column{width:300px;padding:0px 18px 12px}.docs-info-header .docs-filter{margin-bottom:0}#docs-filter-meta{font-size:.8em;color:#666;margin-bottom:0}a.docs-filter-title{margin:0 7px;text-decoration:none}a.docs-filter-title:visited{color:inherit}a.docs-filter-title.current{font-weight:bold}.docs-filter-section{border:1px solid #ccc;border-radius:2px;font-size:.8em;padding:6px 10px;margin-top:8px;transition:max-height 2s ease;overflow:hidden;position:relative}#docs-filter-section-tags a.tags-action-button,#docs-filter-section-tags a.tags-action-button:visited{display:inline;line-height:3em;text-decoration:none;background:#fff;background-opacity:.5;padding:5px 10px;border-radius:3px}body.js .docs-filter-section{display:none}body.js .docs-filter-section.docs-filter-section-open{display:block}p.currently-viewing{margin-bottom:5px;font-size:.8em;margin-top:8px}p#filter-by-tag{margin-bottom:0}.docs-info-header .toggle-switch{margin-top:8px}ul#tags-list{list-style-type:none;margin-bottom:0;padding:0;-moz-column-count:2;-moz-column-gap:10%;-webkit-column-count:2;-webkit-column-gap:10%;column-count:2;column-gap:10%}ul#tags-list li{margin-left:0}ul#tags-list li.hidden-tag{display:none}ul#tags-list li.tags-ellipses{font-style:italic}.groups-cell ul li img.avatar{float:none}.groups-cell ul li a{vertical-align:middle;font-size:.85em}.groups-cell ul{list-style-type:none;padding-left:0}.groups-cell ul li{margin-bottom:.5em}select#has-attachment{margin:8px 10px}div#bp-docs-pagination{position:relative;height:30px}div#bp-docs-pagination-count{position:absolute;left:0;top:5px;font-size:.9em;color:#999}div#bp-docs-paginate-links{position:absolute;right:0;top:5px}div#bp-docs-paginate-links a{padding:0 4px}div.doc-content{padding:20px;border:3px solid #f3f3f3}div.doc-content img{margin:10px}div.doc-content img.mceIcon{margin:0}#bp-docs-single-doc-header{overflow:hidden}body.trashed-doc #buddypress{border-left:4px solid red;padding-left:10px}div.doc-permissions{float:right;width:35%;background:#f0f0f0;border:1px solid #ddd;border-radius:3px;padding:4px}div.doc-permissions div:last-child{clear:both}#doc-permissions-summary,#doc-group-summary{font-size:1.0em;padding:3px 12px;border:1px solid}#doc-permissions-summary.doc-public{background:#b2ffb2;border-color:#00ff00}#doc-permissions-summary.doc-limited{background:#ffffe0;border-color:#e6db55}#doc-permissions-summary.doc-private{background:#ffebe8;border-color:#ff0000}a.doc-permissions-toggle{display:block;float:right;font-size:12px;cursor:hand}dl.doc-permissions-types dd,dl.doc-permissions-types dt{height:1.5em}dl.doc-permissions-types dt{width:50%;float:left;clear:left}#doc-group-summary{border-color:#f0f0f0}#doc-group-summary img.avatar{float:none}#doc-permissions-details ul{list-style-type:none;padding-left:0}#doc-permissions-details ul li{margin-bottom:.5em}span.bp-docs-level-icon{display:block;float:left;width:1.2em;height:1.2em;margin:3px 5px}.bp-docs-level-anyone span.bp-docs-level-icon{-moz-border-radius:.6em;-webkit-border-radius:.6em;border-radius:.6em;background:green}.bp-docs-level-friends span.bp-docs-level-icon,.bp-docs-level-loggedin span.bp-docs-level-icon,.bp-docs-level-group-members span.bp-docs-level-icon{width:0;height:0;border-left:.6em solid transparent;border-right:.6em solid transparent;border-bottom:1.2em solid yellow}.bp-docs-level-admins-mods span.bp-docs-level-icon,.bp-docs-level-no-one span.bp-docs-level-icon,.bp-docs-level-creator span.bp-docs-level-icon{background:red}div.doc-is-locked .toggle-content{border:2px solid #f33;margin-top:5px;padding:7px 10px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}div.doc-meta p{margin-bottom:5px}a.nonexistent-doc{color:#f33}h2.doc-title{display:inline-block;width:50%}.comments-closed{padding:10px 20px;background:#f3f3f3;margin-top:10px}#respond{margin-top:20px}.doc-content ul{list-style:disc}.doc-content ol{list-style:decimal}.doc-content li{margin-left:20px}.doc-content blockquote{background:#f3f3f3;padding:5px;margin:10px 30px}div.hidden{display:none}table.group-docs-options td.label{width:200px}table.diff{width:100%}table.diff col.content{width:50%}table.diff tr{background-color:transparent}table.diff td,table.diff th{padding:.5em;font-family:Consolas, Monaco, Courier, monospace;border:none}table.diff .diff-deletedline del,table.diff .diff-addedline ins{text-decoration:none}table.diff .diff-deletedline{background-color:#fdd}table.diff .diff-deletedline del{background-color:#f99}table.diff .diff-addedline{background-color:#dfd}table.diff .diff-addedline ins{background-color:#9f9}#att-info{background-color:#E4F2FD}table#post-revisions{margin-top:20px}@media screen and (min-width: 4em){#docs-filter-section-tags a.tags-action-button,#docs-filter-section-tags a.tags-action-button:visited{display:block;margin-bottom:1em;padding:0;text-align:center}}@media screen and (min-width: 50em){.entry-content ul#tags-list{-moz-column-count:4;-moz-column-gap:5%;-webkit-column-count:4;-webkit-column-gap:5%;column-count:4;column-gap:5%}}@media screen and (min-width: 71em){.entry-content ul#tags-list{-moz-column-count:5;-moz-column-gap:5%;-webkit-column-count:5;-webkit-column-gap:5%;column-count:5;column-gap:5%}} +.hide-if-no-js{display:none}.description{font-weight:normal;font-style:italic}.description code{font-style:normal;background:#eee;padding:2px 4px}#bp-create-doc-button{float:right;margin:5px 19px;font-weight:bold}body.bp-docs div.page ul{list-style-type:none}#bp-docs-all-docs{width:auto}.doc-tabs{overflow:hidden}.doc-tabs ul{padding-left:0}.doc-tabs li{float:left;margin:0 5px;list-style-type:none}.doc-tabs li:first-child{margin-left:0}.doc-tabs li a{background:#f1f1f1;text-decoration:none;display:block;padding:4px 10px;border-radius:5px 5px 0 0}.doc-tabs li.current a{background:#f3f3f3;color:#555;font-weight:bold}.doc-header h4{margin-bottom:15px !important}.docs-filter{display:block;width:400px;float:left;margin-bottom:15px}.doc-search{float:right;width:250px;text-align:right}.docs-filter-tags{width:100%}.docs-filter-tags ul li{display:block;width:120px;float:left;padding:6px}.doctable{border-collapse:separate;border-spacing:0}.doctable p{padding:0;margin:0}.doctable tr:hover .row-actions{visibility:visible}.doctable tr:nth-child(even){background-color:#f3f3f3}.doctable .bp-doc-trashed-doc .attachment-clip-cell{border-left:4px solid red}.bp-docs-trashed-doc-notice{color:red;font-size:.9em;font-style:italic}#buddypress #bp-docs-all-docs li{background:#eee}#buddypress div.doc-permissions{float:none;width:auto;margin-bottom:1em}#buddypress table.doctable td{vertical-align:top}#buddypress table.doctable tr:nth-child(even){background-color:#f3f3f3}#buddypress table.doctable tr th{background-color:#f3f3f3}.row-actions{visibility:hidden;padding:2px 0 0}body.mobile .row-actions{visibility:visible}.row-actions a{color:#999;font-size:11px}.row-actions a.delete{color:#f00}#docs-filter-submit{margin:10px 4px}.title-cell{width:30%}.author-cell,.created-date-cell,.edited-date-cell{text-align:center;width:100px}.current-orderby a{padding-left:20px}.asc a{background:url(../images/sort-col-asc.gif) no-repeat}.desc a{background:url(../images/sort-col-desc.gif) no-repeat}.doc-edit-link{margin:15px 0 20px 0}.doc-meta,#doc-meta,.docs #comments{padding-top:20px;border-top:1px solid #ddd}div.docs-info-header{background:#f3f3f3;padding:5px 10px;margin-bottom:10px}#associated_group_summary .item{padding-top:1em}#associated_group_summary .meta{font-size:11px;color:#888}#associated_group_summary img.avatar{margin-left:0}#doc-attachments-ul{margin-top:1em;list-style-type:none}#doc-attachments-ul li{margin:0px 5px 0px 0;padding:6px}#doc-attachments-ul li.even{background-color:#f3f3f3}#doc-attachments-ul .doc-attachment-delete{float:right;margin-top:.15em;margin-right:.3em}.bp-docs-attachment-clip{cursor:pointer;display:block;margin-top:10px}.doc-attachment-mime-icon{display:block;float:left;width:24px;height:24px;margin-right:5px;background:transparent url("../images/mime-type-sprites.png") no-repeat}.doc-attachment-mime-tar,.doc-attachment-mime-zip,.doc-attachment-mime-gz,.doc-attachment-mime-gzip,.doc-attachment-mime-rar,.doc-attachment-mime-7z{background-position:0 0px}.doc-attachment-mime-mp3,.doc-attachment-mime-m4a,.doc-attachment-mime-m4b,.doc-attachment-mime-ra,.doc-attachment-mime-ram,.doc-attachment-mime-wav,.doc-attachment-mime-ogg,.doc-attachment-mime-oga,.doc-attachment-mime-mid,.doc-attachment-mime-midi,.doc-attachment-mime-wma,.doc-attachment-mime-mka{background-position:0 -40px}.doc-attachment-mime-ics{background-position:0 -80px}.doc-attachment-mime-mdb,.doc-attachment-mime-odb{background-position:0 -120px}.doc-attachment-mime-odg{background-position:0 -160px}.doc-attachment-mime-jpg,.doc-attachment-mime-jpeg,.doc-attachment-mime-gif,.doc-attachment-mime-png,.doc-attachment-mime-bmp,.doc-attachment-mime-tif,.doc-attachment-mime-tiff,.doc-attachment-mime-ico{background-position:0 -200px}.doc-attachment-mime-pdf{background-position:0 -240px}.doc-attachment-mime-xla,.doc-attachment-mime-xls,.doc-attachment-mime-xlt,.doc-attachment-mime-xlw,.doc-attachment-mime-xlsx,.doc-attachment-mime-xlsm,.doc-attachment-mime-xlsb,.doc-attachment-mime-xlsb,.doc-attachment-mime-xlsx,.doc-attachment-mime-xlsm,.doc-attachment-mime-xlam,.doc-attachment-mime-ods,.doc-attachment-mime-odc{background-position:0 -280px}.doc-attachment-mime-txt,.doc-attachment-mime-asc,.doc-attachment-mime-c,.doc-attachment-mime-cc,.doc-attachment-mime-h,.doc-attachment-mime-csv,.doc-attachment-mime-tsv,.doc-attachment-mime-ics,.doc-attachment-mime-rtx,.doc-attachment-mime-css,.doc-attachment-mime-htm,.doc-attachment-mime-html{background-position:0 -320px}.doc-attachment-mime-asf,.doc-attachment-mime-asx,.doc-attachment-mime-wax,.doc-attachment-mime-wmv,.doc-attachment-mime-wmx,.doc-attachment-mime-avi,.doc-attachment-mime-divx,.doc-attachment-mime-flv,.doc-attachment-mime-mov,.doc-attachment-mime-qt,.doc-attachment-mime-mpeg,.doc-attachment-mime-mpg,.doc-attachment-mime-mpe,.doc-attachment-mime-mp4,.doc-attachment-mime-m4v,.doc-attachment-mime-ogv,.doc-attachment-mime-mkv{background-position:0 -360px}body.js .bp-docs-attachment-drawer{display:none}.bp-docs-attachment-drawer h4{margin:.5em 0}.bp-docs-attachment-drawer>ul{list-style-type:none}.bp-docs-attachment-drawer>ul>li{margin-left:0}.toggleable.toggle-closed .toggle-content{display:none}.hide-pane,.show-pane,.paperclip-vertical,.paperclip-jaunty{background:url("../images/bp-docs-ui-sprites.png") no-repeat;display:block;float:left;margin-left:10px;margin-top:5px}.hide-pane{background-position:0 0;width:16px;height:16px}.show-pane{background-position:0 -28px;width:16px;height:16px}.paperclip-vertical{background-position:0 -55px;width:13px;height:36px}.paperclip-jaunty{background-position:0 -105px;width:17px;height:36px}.toggle-switch,.entry-content p.toggle-switch{display:block;font-size:1em;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;border:1px solid #ccc;background-color:#f3f3f3;padding:3px 0;text-indent:16px;margin:16px 0 0}.toggle-switch.active-switch,.entry-content p.toggle-switch.active-switch{-moz-border-radius-bottomleft:10px;-webkit-border-bottom-left-radius:10px;-moz-border-radius-bottomright:10px;-webkit-border-bottom-right-radius:10px;border-radius:3px 3px 0px 0px}.toggle-switch a,.entry-content p.toggle-switch a{color:#757575;text-decoration:none;display:block;width:100%;height:100%}.toggle-switch a:hover,.entry-content p.toggle-switch a:hover{font-weight:bold}.standard-form label.toggle-switch{margin:16px 0 0}.toggle-content{-moz-border-radius-bottomleft:2px;-webkit-border-bottom-left-radius:2px;-moz-border-radius-bottomright:2px;-webkit-border-bottom-right-radius:2px;border:1px solid #ccc;border-top:none;overflow:hidden}td.desc-column{width:300px;padding:0px 18px 12px}.docs-info-header .docs-filter{margin-bottom:0}#docs-filter-meta{font-size:.8em;color:#666;margin-bottom:0}a.docs-filter-title{margin:0 7px;text-decoration:none}a.docs-filter-title:visited{color:inherit}a.docs-filter-title.current{font-weight:bold}.docs-filter-section{border:1px solid #ccc;border-radius:2px;font-size:.8em;padding:6px 10px;margin-top:8px;transition:max-height 2s ease;overflow:hidden;position:relative}#docs-filter-section-tags a.tags-action-button,#docs-filter-section-tags a.tags-action-button:visited{display:inline;line-height:3em;text-decoration:none;background:#fff;background-opacity:.5;padding:5px 10px;border-radius:3px}body.js .docs-filter-section{display:none}body.js .docs-filter-section.docs-filter-section-open{display:block}p.currently-viewing{margin-bottom:5px;font-size:.8em;margin-top:8px}p#filter-by-tag{margin-bottom:0}.docs-info-header .toggle-switch{margin-top:8px}ul#tags-list{list-style-type:none;margin-bottom:0;padding:0;-moz-column-count:2;-moz-column-gap:10%;-webkit-column-count:2;-webkit-column-gap:10%;column-count:2;column-gap:10%}ul#tags-list li{margin-left:0}ul#tags-list li.hidden-tag{display:none}ul#tags-list li.tags-ellipses{font-style:italic}.groups-cell{padding-left:10px}.groups-cell ul{list-style-type:none;padding-left:0}.groups-cell ul li{margin-bottom:.5em;margin-left:0}.groups-cell ul li a{vertical-align:middle;font-size:.85em}.groups-cell ul li img.avatar{float:none}select#has-attachment{margin:8px 10px}div#bp-docs-pagination{position:relative;height:30px}div#bp-docs-pagination-count{position:absolute;left:0;top:5px;font-size:.9em;color:#999}div#bp-docs-paginate-links{position:absolute;right:0;top:5px}div#bp-docs-paginate-links a{padding:0 4px}div.doc-content{padding:20px;border:3px solid #f3f3f3}div.doc-content img{margin:10px}div.doc-content img.mceIcon{margin:0}#bp-docs-single-doc-header{overflow:hidden}body.trashed-doc #buddypress{border-left:4px solid red;padding-left:10px}div.doc-permissions{float:right;width:35%;background:#f0f0f0;border:1px solid #ddd;border-radius:3px;padding:4px}div.doc-permissions div:last-child{clear:both}#doc-permissions-summary,#doc-group-summary{font-size:1.0em;padding:3px 12px;border:1px solid}#doc-permissions-summary.doc-public{background:#b2ffb2;border-color:#00ff00}#doc-permissions-summary.doc-limited{background:#ffffe0;border-color:#e6db55}#doc-permissions-summary.doc-private{background:#ffebe8;border-color:#ff0000}a.doc-permissions-toggle{display:block;float:right;font-size:12px;cursor:hand}dl.doc-permissions-types dd,dl.doc-permissions-types dt{height:1.5em}dl.doc-permissions-types dt{width:50%;float:left;clear:left}#doc-group-summary{border-color:#f0f0f0}#doc-group-summary img.avatar{float:none}#doc-permissions-details ul{list-style-type:none;padding-left:0}#doc-permissions-details ul li{margin-bottom:.5em}span.bp-docs-level-icon{display:block;float:left;width:1.2em;height:1.2em;margin:3px 5px}.bp-docs-level-anyone span.bp-docs-level-icon{-moz-border-radius:.6em;-webkit-border-radius:.6em;border-radius:.6em;background:green}.bp-docs-level-friends span.bp-docs-level-icon,.bp-docs-level-loggedin span.bp-docs-level-icon,.bp-docs-level-group-members span.bp-docs-level-icon{width:0;height:0;border-left:.6em solid transparent;border-right:.6em solid transparent;border-bottom:1.2em solid yellow}.bp-docs-level-admins-mods span.bp-docs-level-icon,.bp-docs-level-no-one span.bp-docs-level-icon,.bp-docs-level-creator span.bp-docs-level-icon{background:red}div.doc-is-locked .toggle-content{border:2px solid #f33;margin-top:5px;padding:7px 10px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}div.doc-meta p{margin-bottom:5px}a.nonexistent-doc{color:#f33}h2.doc-title{display:inline-block;width:50%}.comments-closed{padding:10px 20px;background:#f3f3f3;margin-top:10px}#respond{margin-top:20px}.doc-content ul{list-style:disc}.doc-content ol{list-style:decimal}.doc-content li{margin-left:20px}.doc-content blockquote{background:#f3f3f3;padding:5px;margin:10px 30px}div.hidden{display:none}table.group-docs-options td.label{width:200px}table.diff{width:100%}table.diff col.content{width:50%}table.diff tr{background-color:transparent}table.diff td,table.diff th{padding:.5em;font-family:Consolas, Monaco, Courier, monospace;border:none}table.diff .diff-deletedline del,table.diff .diff-addedline ins{text-decoration:none}table.diff .diff-deletedline{background-color:#fdd}table.diff .diff-deletedline del{background-color:#f99}table.diff .diff-addedline{background-color:#dfd}table.diff .diff-addedline ins{background-color:#9f9}#att-info{background-color:#E4F2FD}table#post-revisions{margin-top:20px}@media screen and (min-width: 4em){#docs-filter-section-tags a.tags-action-button,#docs-filter-section-tags a.tags-action-button:visited{display:block;margin-bottom:1em;padding:0;text-align:center}}@media screen and (min-width: 50em){.entry-content ul#tags-list{-moz-column-count:4;-moz-column-gap:5%;-webkit-column-count:4;-webkit-column-gap:5%;column-count:4;column-gap:5%}}@media screen and (min-width: 71em){.entry-content ul#tags-list{-moz-column-count:5;-moz-column-gap:5%;-webkit-column-count:5;-webkit-column-gap:5%;column-count:5;column-gap:5%}}@media screen and (max-width: 820px){.created-date-cell{display:none}}@media screen and (max-width: 620px){.tags-cell{display:none}}@media screen and (max-width: 520px){.groups-cell{display:none}}@media screen and (max-width: 420px){.attachment-clip-cell,.edited-date-cell{display:none}} diff --git a/includes/scss/screen.scss b/includes/scss/screen.scss index 9475332c..b2b160b1 100644 --- a/includes/scss/screen.scss +++ b/includes/scss/screen.scss @@ -195,6 +195,10 @@ body.mobile .row-actions { width: 100px; } +.group-cell { + +} + .current-orderby a { padding-left: 20px; } @@ -577,21 +581,27 @@ ul#tags-list { } } -.groups-cell ul li img.avatar { - float: none; -} +.groups-cell { + padding-left: 10px; -.groups-cell ul li a { - vertical-align: middle; - font-size: .85em; -} + ul { + list-style-type: none; + padding-left: 0; -.groups-cell ul { - list-style-type: none; - padding-left: 0; -} -.groups-cell ul li { - margin-bottom: .5em; + li { + margin-bottom: .5em; + margin-left: 0; + + a { + vertical-align: middle; + font-size: .85em; + } + + img.avatar { + float: none; + } + } + } } select#has-attachment { @@ -855,3 +865,27 @@ table#post-revisions { @include multi-columns(5, 5%); } } + +@media screen and (max-width:820px) { + .created-date-cell { + display: none; + } +} + +@media screen and (max-width:620px) { + .tags-cell { + display: none; + } +} + +@media screen and (max-width:520px) { + .groups-cell { + display: none; + } +} + +@media screen and (max-width:420px) { + .attachment-clip-cell, .edited-date-cell { + display: none; + } +} diff --git a/readme.txt b/readme.txt index 782cd759..c091ae69 100755 --- a/readme.txt +++ b/readme.txt @@ -37,6 +37,7 @@ This plugin is in active development. For feature requests and bug reports, visi * Overhaul of the way group/user tag clouds work * Improved support for attachments on nginx and IIS * Improved doc edit locking mechanisms +* Improved responsiveness on directories = 1.5.7 = * Improve appearance of row actions on mobile devices From dc49a82ae90100cd305ad6f4ee0830efb6a8f156 Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Wed, 12 Mar 2014 14:22:40 -0400 Subject: [PATCH 27/35] Better positining for tabindent key in TinyMCE 4.x --- includes/templatetags-edit.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/includes/templatetags-edit.php b/includes/templatetags-edit.php index 52897fed..ebb8aef2 100644 --- a/includes/templatetags-edit.php +++ b/includes/templatetags-edit.php @@ -263,7 +263,13 @@ function bp_docs_add_external_tinymce_plugins( $plugins ) { * @return array $buttons Button list, with BP Docs buttons added */ function bp_docs_add_external_tinymce_buttons_row1( $buttons ) { - $justify_right_key = array_search( 'justifyright', $buttons ); + // TinyMCE 4.0+ + $justify_right_key = array_search( 'alignright', $buttons ); + + // 3.0 + if ( false === $justify_right_key ) { + $justify_right_key = array_search( 'justifyright', $buttons ); + } if ( $justify_right_key !== 0 ) { // Shift the buttons one to the right and remove from original array From e9aa5dd7f25b511ce6c7e15a23cba03bda09157d Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Wed, 12 Mar 2014 14:25:22 -0400 Subject: [PATCH 28/35] Don't show fullscreen button in TinyMCE. It's broken --- includes/templatetags-edit.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/includes/templatetags-edit.php b/includes/templatetags-edit.php index ebb8aef2..58c01be0 100644 --- a/includes/templatetags-edit.php +++ b/includes/templatetags-edit.php @@ -288,6 +288,15 @@ function bp_docs_add_external_tinymce_buttons_row1( $buttons ) { $ks = array_pop( $buttons ); $buttons = array_merge( $buttons, array( 'print' ), array( $ks ) ); + // Fullscreen is kinda busted here, so remove it + $fs = array_search( 'fullscreen', $buttons ); + if ( false !== $fs ) { + unset( $buttons[ $fs ] ); + } + + // Reset indexes + $buttons = array_values( $buttons ); + return $buttons; } add_filter( 'mce_buttons', 'bp_docs_add_external_tinymce_buttons_row1' ); From add69fbd09e8e8677fa106ddfe4e78a0f5c130fb Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Fri, 14 Mar 2014 09:44:55 -0400 Subject: [PATCH 29/35] Admin notice for IIS7 non-protected attacments --- includes/attachments.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/includes/attachments.php b/includes/attachments.php index 6c02ceac..312c0885 100644 --- a/includes/attachments.php +++ b/includes/attachments.php @@ -179,7 +179,7 @@ public function delete_htaccess() { * @return $file */ public function maybe_create_rewrites( $file ) { - global $is_apache, $is_nginx; + global $is_apache; if ( ! $this->get_doc_id() ) { return $file; @@ -692,6 +692,7 @@ public function admin_notice_init() { } add_action( 'admin_notices', array( $this, 'admin_notice' ) ); + add_action( 'network_admin_notices', array( $this, 'admin_notice' ) ); } public function admin_notice() { @@ -710,6 +711,19 @@ public function admin_notice() { '; } + if ( $is_iis7 ) { + $help_url = 'https://github.com/boonebgorges/buddypress-docs/wiki/Attachment-Privacy#wiki-nginx'; + + $help_p = __( 'It looks like you are running IIS 7. We recommend the following setting in your Web.config file:', 'bp-docs' ); + $help_p .= '
      <rule name="buddypress-docs-attachments">
      +    <match url="^wp-content/uploads/bp-attachments/([0-9]+)/(.*)$"/>
      +        <conditions>
      +	    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="false"/>
      +	</conditions>
      +    <action type="Redirect" url=?p={R:1}&bp-attachment={R:2}"/>
      +</rule> 
      '; + } + ?>
      From 63f1883603aba4e272e67ad313c36882d0d9de3e Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Fri, 14 Mar 2014 09:55:06 -0400 Subject: [PATCH 30/35] Redirect instructions for nginx and IIS7 should be dynamic --- includes/attachments.php | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/includes/attachments.php b/includes/attachments.php index 312c0885..5f5e0661 100644 --- a/includes/attachments.php +++ b/includes/attachments.php @@ -701,12 +701,21 @@ public function admin_notice() { $dismiss_url = add_query_arg( 'bpdocs-disable-attachment-notice', '1', $_SERVER['REQUEST_URI'] ); $dismiss_url = wp_nonce_url( $dismiss_url, 'bpdocs-disable-attachment-notice' ); + if ( ! bp_is_root_blog() ) { + switch_to_blog( bp_get_root_blog_id() ); + } + + $upload_dir = $this->mod_upload_dir( wp_upload_dir() ); + $att_url = str_replace( get_option( 'home' ), '', $upload_dir['url'] ); + + restore_current_blog(); + if ( $is_nginx ) { $help_url = 'https://github.com/boonebgorges/buddypress-docs/wiki/Attachment-Privacy#wiki-nginx'; $help_p = __( 'It looks like you are running nginx. We recommend the following setting in your site configuration file:', 'bp-docs' ); - $help_p .= '
      location /wp-content/uploads/bp-attachments/ {
      -    rewrite ^.*uploads/bp-attachments/([0-9]+)/(.*) /?p=$1&bp-attachment=$2 permanent;
      +			$help_p .= '
      location ' . $att_url . ' {
      +    rewrite ^.*' . str_replace( '/wp-content/', '', $att_url ) . '([0-9]+)/(.*) /?p=$1&bp-attachment=$2 permanent;
       }
       
      '; } @@ -716,11 +725,11 @@ public function admin_notice() { $help_p = __( 'It looks like you are running IIS 7. We recommend the following setting in your Web.config file:', 'bp-docs' ); $help_p .= '
      <rule name="buddypress-docs-attachments">
      -    <match url="^wp-content/uploads/bp-attachments/([0-9]+)/(.*)$"/>
      +    <match url="^' . $att_url . '([0-9]+)/(.*)$"/>
               <conditions>
       	    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="false"/>
       	</conditions>
      -    <action type="Redirect" url=?p={R:1}&bp-attachment={R:2}"/>
      +    <action type="Redirect" url="?p={R:1}&bp-attachment={R:2}"/>
       </rule> 
      '; } From 8024b9a2ea3f3e06643d124d401185af59cdbec9 Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Fri, 14 Mar 2014 09:58:44 -0400 Subject: [PATCH 31/35] Point to the proper wiki pages for privacy info --- includes/attachments.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/attachments.php b/includes/attachments.php index 5f5e0661..f81419a1 100644 --- a/includes/attachments.php +++ b/includes/attachments.php @@ -711,7 +711,7 @@ public function admin_notice() { restore_current_blog(); if ( $is_nginx ) { - $help_url = 'https://github.com/boonebgorges/buddypress-docs/wiki/Attachment-Privacy#wiki-nginx'; + $help_url = 'https://github.com/boonebgorges/buddypress-docs/wiki/Attachment-Privacy#nginx'; $help_p = __( 'It looks like you are running nginx. We recommend the following setting in your site configuration file:', 'bp-docs' ); $help_p .= '
      location ' . $att_url . ' {
      @@ -721,7 +721,7 @@ public function admin_notice() {
       		}
       
       		if ( $is_iis7 ) {
      -			$help_url = 'https://github.com/boonebgorges/buddypress-docs/wiki/Attachment-Privacy#wiki-nginx';
      +			$help_url = 'https://github.com/boonebgorges/buddypress-docs/wiki/Attachment-Privacy#iis7';
       
       			$help_p  = __( 'It looks like you are running IIS 7. We recommend the following setting in your Web.config file:', 'bp-docs' );
       			$help_p .= '
      <rule name="buddypress-docs-attachments">
      
      From 176a22156ef2df2aae01a80efaab47364bc0594d Mon Sep 17 00:00:00 2001
      From: Boone B Gorges 
      Date: Fri, 14 Mar 2014 10:12:16 -0400
      Subject: [PATCH 32/35] Change display of attachments in directory list
      
      Uses background image for "has-attachment" icon and adds icons for
      attachment list (only visible at larger display sizes).
      ---
       includes/templatetags.php | 7 ++++---
       1 file changed, 4 insertions(+), 3 deletions(-)
      
      diff --git a/includes/templatetags.php b/includes/templatetags.php
      index 357283d1..80aee877 100644
      --- a/includes/templatetags.php
      +++ b/includes/templatetags.php
      @@ -1862,8 +1862,9 @@ function bp_docs_attachment_item_markup( $attachment_id, $format = 'full' ) {
       		);
       	} else {
       		$markup = sprintf(
      -			'
    • %s
    • ', + '
    • %s
    • ', $attachment_id, + $attachment_ext, $att_url, esc_attr( $att_base ), esc_html( $att_base ) @@ -1901,9 +1902,9 @@ function bp_docs_attachment_icon() { return; } - $pc = plugins_url( BP_DOCS_PLUGIN_SLUG . '/includes/images/paperclip.png' ); + // $pc = plugins_url( BP_DOCS_PLUGIN_SLUG . '/includes/images/paperclip.png' ); - $html = ''; + $html = ''; echo $html; } From b6e4d339af9d9b23dff8a139043007069e4a9408 Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Fri, 14 Mar 2014 10:15:08 -0400 Subject: [PATCH 33/35] Readme --- readme.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/readme.txt b/readme.txt index c091ae69..281211fe 100755 --- a/readme.txt +++ b/readme.txt @@ -37,7 +37,8 @@ This plugin is in active development. For feature requests and bug reports, visi * Overhaul of the way group/user tag clouds work * Improved support for attachments on nginx and IIS * Improved doc edit locking mechanisms -* Improved responsiveness on directories +* Improved appearance on devices of various sizes +* Support for WordPress 3.9 and TinyMCE 4.x = 1.5.7 = * Improve appearance of row actions on mobile devices From c1a3fb16ddf0d2b53d7b5cf67a5b466e2b073584 Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Fri, 14 Mar 2014 10:20:33 -0400 Subject: [PATCH 34/35] Better styling for settings table cells --- includes/css/screen.css | 2 +- includes/scss/screen.scss | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/includes/css/screen.css b/includes/css/screen.css index f8c6be2e..71eab987 100644 --- a/includes/css/screen.css +++ b/includes/css/screen.css @@ -1 +1 @@ -.hide-if-no-js{display:none}.description{font-weight:normal;font-style:italic}.description code{font-style:normal;background:#eee;padding:2px 4px}#bp-create-doc-button{float:right;margin:5px 19px;font-weight:bold}body.bp-docs div.page ul{list-style-type:none}#bp-docs-all-docs{width:auto}.doc-tabs{overflow:hidden}.doc-tabs ul{padding-left:0}.doc-tabs li{float:left;margin:0 5px;list-style-type:none}.doc-tabs li:first-child{margin-left:0}.doc-tabs li a{background:#f1f1f1;text-decoration:none;display:block;padding:4px 10px;border-radius:5px 5px 0 0}.doc-tabs li.current a{background:#f3f3f3;color:#555;font-weight:bold}.doc-header h4{margin-bottom:15px !important}.docs-filter{display:block;width:400px;float:left;margin-bottom:15px}.doc-search{float:right;width:250px;text-align:right}.docs-filter-tags{width:100%}.docs-filter-tags ul li{display:block;width:120px;float:left;padding:6px}.doctable{border-collapse:separate;border-spacing:0}.doctable p{padding:0;margin:0}.doctable tr:hover .row-actions{visibility:visible}.doctable tr:nth-child(even){background-color:#f3f3f3}.doctable .bp-doc-trashed-doc .attachment-clip-cell{border-left:4px solid red}.bp-docs-trashed-doc-notice{color:red;font-size:.9em;font-style:italic}#buddypress #bp-docs-all-docs li{background:#eee}#buddypress div.doc-permissions{float:none;width:auto;margin-bottom:1em}#buddypress table.doctable td{vertical-align:top}#buddypress table.doctable tr:nth-child(even){background-color:#f3f3f3}#buddypress table.doctable tr th{background-color:#f3f3f3}.row-actions{visibility:hidden;padding:2px 0 0}body.mobile .row-actions{visibility:visible}.row-actions a{color:#999;font-size:11px}.row-actions a.delete{color:#f00}#docs-filter-submit{margin:10px 4px}.title-cell{width:30%}.author-cell,.created-date-cell,.edited-date-cell{text-align:center;width:100px}.current-orderby a{padding-left:20px}.asc a{background:url(../images/sort-col-asc.gif) no-repeat}.desc a{background:url(../images/sort-col-desc.gif) no-repeat}.doc-edit-link{margin:15px 0 20px 0}.doc-meta,#doc-meta,.docs #comments{padding-top:20px;border-top:1px solid #ddd}div.docs-info-header{background:#f3f3f3;padding:5px 10px;margin-bottom:10px}#associated_group_summary .item{padding-top:1em}#associated_group_summary .meta{font-size:11px;color:#888}#associated_group_summary img.avatar{margin-left:0}#doc-attachments-ul{margin-top:1em;list-style-type:none}#doc-attachments-ul li{margin:0px 5px 0px 0;padding:6px}#doc-attachments-ul li.even{background-color:#f3f3f3}#doc-attachments-ul .doc-attachment-delete{float:right;margin-top:.15em;margin-right:.3em}.bp-docs-attachment-clip{cursor:pointer;display:block;margin-top:10px}.doc-attachment-mime-icon{display:block;float:left;width:24px;height:24px;margin-right:5px;background:transparent url("../images/mime-type-sprites.png") no-repeat}.doc-attachment-mime-tar,.doc-attachment-mime-zip,.doc-attachment-mime-gz,.doc-attachment-mime-gzip,.doc-attachment-mime-rar,.doc-attachment-mime-7z{background-position:0 0px}.doc-attachment-mime-mp3,.doc-attachment-mime-m4a,.doc-attachment-mime-m4b,.doc-attachment-mime-ra,.doc-attachment-mime-ram,.doc-attachment-mime-wav,.doc-attachment-mime-ogg,.doc-attachment-mime-oga,.doc-attachment-mime-mid,.doc-attachment-mime-midi,.doc-attachment-mime-wma,.doc-attachment-mime-mka{background-position:0 -40px}.doc-attachment-mime-ics{background-position:0 -80px}.doc-attachment-mime-mdb,.doc-attachment-mime-odb{background-position:0 -120px}.doc-attachment-mime-odg{background-position:0 -160px}.doc-attachment-mime-jpg,.doc-attachment-mime-jpeg,.doc-attachment-mime-gif,.doc-attachment-mime-png,.doc-attachment-mime-bmp,.doc-attachment-mime-tif,.doc-attachment-mime-tiff,.doc-attachment-mime-ico{background-position:0 -200px}.doc-attachment-mime-pdf{background-position:0 -240px}.doc-attachment-mime-xla,.doc-attachment-mime-xls,.doc-attachment-mime-xlt,.doc-attachment-mime-xlw,.doc-attachment-mime-xlsx,.doc-attachment-mime-xlsm,.doc-attachment-mime-xlsb,.doc-attachment-mime-xlsb,.doc-attachment-mime-xlsx,.doc-attachment-mime-xlsm,.doc-attachment-mime-xlam,.doc-attachment-mime-ods,.doc-attachment-mime-odc{background-position:0 -280px}.doc-attachment-mime-txt,.doc-attachment-mime-asc,.doc-attachment-mime-c,.doc-attachment-mime-cc,.doc-attachment-mime-h,.doc-attachment-mime-csv,.doc-attachment-mime-tsv,.doc-attachment-mime-ics,.doc-attachment-mime-rtx,.doc-attachment-mime-css,.doc-attachment-mime-htm,.doc-attachment-mime-html{background-position:0 -320px}.doc-attachment-mime-asf,.doc-attachment-mime-asx,.doc-attachment-mime-wax,.doc-attachment-mime-wmv,.doc-attachment-mime-wmx,.doc-attachment-mime-avi,.doc-attachment-mime-divx,.doc-attachment-mime-flv,.doc-attachment-mime-mov,.doc-attachment-mime-qt,.doc-attachment-mime-mpeg,.doc-attachment-mime-mpg,.doc-attachment-mime-mpe,.doc-attachment-mime-mp4,.doc-attachment-mime-m4v,.doc-attachment-mime-ogv,.doc-attachment-mime-mkv{background-position:0 -360px}body.js .bp-docs-attachment-drawer{display:none}.bp-docs-attachment-drawer h4{margin:.5em 0}.bp-docs-attachment-drawer>ul{list-style-type:none}.bp-docs-attachment-drawer>ul>li{margin-left:0}.toggleable.toggle-closed .toggle-content{display:none}.hide-pane,.show-pane,.paperclip-vertical,.paperclip-jaunty{background:url("../images/bp-docs-ui-sprites.png") no-repeat;display:block;float:left;margin-left:10px;margin-top:5px}.hide-pane{background-position:0 0;width:16px;height:16px}.show-pane{background-position:0 -28px;width:16px;height:16px}.paperclip-vertical{background-position:0 -55px;width:13px;height:36px}.paperclip-jaunty{background-position:0 -105px;width:17px;height:36px}.toggle-switch,.entry-content p.toggle-switch{display:block;font-size:1em;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;border:1px solid #ccc;background-color:#f3f3f3;padding:3px 0;text-indent:16px;margin:16px 0 0}.toggle-switch.active-switch,.entry-content p.toggle-switch.active-switch{-moz-border-radius-bottomleft:10px;-webkit-border-bottom-left-radius:10px;-moz-border-radius-bottomright:10px;-webkit-border-bottom-right-radius:10px;border-radius:3px 3px 0px 0px}.toggle-switch a,.entry-content p.toggle-switch a{color:#757575;text-decoration:none;display:block;width:100%;height:100%}.toggle-switch a:hover,.entry-content p.toggle-switch a:hover{font-weight:bold}.standard-form label.toggle-switch{margin:16px 0 0}.toggle-content{-moz-border-radius-bottomleft:2px;-webkit-border-bottom-left-radius:2px;-moz-border-radius-bottomright:2px;-webkit-border-bottom-right-radius:2px;border:1px solid #ccc;border-top:none;overflow:hidden}td.desc-column{width:300px;padding:0px 18px 12px}.docs-info-header .docs-filter{margin-bottom:0}#docs-filter-meta{font-size:.8em;color:#666;margin-bottom:0}a.docs-filter-title{margin:0 7px;text-decoration:none}a.docs-filter-title:visited{color:inherit}a.docs-filter-title.current{font-weight:bold}.docs-filter-section{border:1px solid #ccc;border-radius:2px;font-size:.8em;padding:6px 10px;margin-top:8px;transition:max-height 2s ease;overflow:hidden;position:relative}#docs-filter-section-tags a.tags-action-button,#docs-filter-section-tags a.tags-action-button:visited{display:inline;line-height:3em;text-decoration:none;background:#fff;background-opacity:.5;padding:5px 10px;border-radius:3px}body.js .docs-filter-section{display:none}body.js .docs-filter-section.docs-filter-section-open{display:block}p.currently-viewing{margin-bottom:5px;font-size:.8em;margin-top:8px}p#filter-by-tag{margin-bottom:0}.docs-info-header .toggle-switch{margin-top:8px}ul#tags-list{list-style-type:none;margin-bottom:0;padding:0;-moz-column-count:2;-moz-column-gap:10%;-webkit-column-count:2;-webkit-column-gap:10%;column-count:2;column-gap:10%}ul#tags-list li{margin-left:0}ul#tags-list li.hidden-tag{display:none}ul#tags-list li.tags-ellipses{font-style:italic}.groups-cell{padding-left:10px}.groups-cell ul{list-style-type:none;padding-left:0}.groups-cell ul li{margin-bottom:.5em;margin-left:0}.groups-cell ul li a{vertical-align:middle;font-size:.85em}.groups-cell ul li img.avatar{float:none}select#has-attachment{margin:8px 10px}div#bp-docs-pagination{position:relative;height:30px}div#bp-docs-pagination-count{position:absolute;left:0;top:5px;font-size:.9em;color:#999}div#bp-docs-paginate-links{position:absolute;right:0;top:5px}div#bp-docs-paginate-links a{padding:0 4px}div.doc-content{padding:20px;border:3px solid #f3f3f3}div.doc-content img{margin:10px}div.doc-content img.mceIcon{margin:0}#bp-docs-single-doc-header{overflow:hidden}body.trashed-doc #buddypress{border-left:4px solid red;padding-left:10px}div.doc-permissions{float:right;width:35%;background:#f0f0f0;border:1px solid #ddd;border-radius:3px;padding:4px}div.doc-permissions div:last-child{clear:both}#doc-permissions-summary,#doc-group-summary{font-size:1.0em;padding:3px 12px;border:1px solid}#doc-permissions-summary.doc-public{background:#b2ffb2;border-color:#00ff00}#doc-permissions-summary.doc-limited{background:#ffffe0;border-color:#e6db55}#doc-permissions-summary.doc-private{background:#ffebe8;border-color:#ff0000}a.doc-permissions-toggle{display:block;float:right;font-size:12px;cursor:hand}dl.doc-permissions-types dd,dl.doc-permissions-types dt{height:1.5em}dl.doc-permissions-types dt{width:50%;float:left;clear:left}#doc-group-summary{border-color:#f0f0f0}#doc-group-summary img.avatar{float:none}#doc-permissions-details ul{list-style-type:none;padding-left:0}#doc-permissions-details ul li{margin-bottom:.5em}span.bp-docs-level-icon{display:block;float:left;width:1.2em;height:1.2em;margin:3px 5px}.bp-docs-level-anyone span.bp-docs-level-icon{-moz-border-radius:.6em;-webkit-border-radius:.6em;border-radius:.6em;background:green}.bp-docs-level-friends span.bp-docs-level-icon,.bp-docs-level-loggedin span.bp-docs-level-icon,.bp-docs-level-group-members span.bp-docs-level-icon{width:0;height:0;border-left:.6em solid transparent;border-right:.6em solid transparent;border-bottom:1.2em solid yellow}.bp-docs-level-admins-mods span.bp-docs-level-icon,.bp-docs-level-no-one span.bp-docs-level-icon,.bp-docs-level-creator span.bp-docs-level-icon{background:red}div.doc-is-locked .toggle-content{border:2px solid #f33;margin-top:5px;padding:7px 10px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}div.doc-meta p{margin-bottom:5px}a.nonexistent-doc{color:#f33}h2.doc-title{display:inline-block;width:50%}.comments-closed{padding:10px 20px;background:#f3f3f3;margin-top:10px}#respond{margin-top:20px}.doc-content ul{list-style:disc}.doc-content ol{list-style:decimal}.doc-content li{margin-left:20px}.doc-content blockquote{background:#f3f3f3;padding:5px;margin:10px 30px}div.hidden{display:none}table.group-docs-options td.label{width:200px}table.diff{width:100%}table.diff col.content{width:50%}table.diff tr{background-color:transparent}table.diff td,table.diff th{padding:.5em;font-family:Consolas, Monaco, Courier, monospace;border:none}table.diff .diff-deletedline del,table.diff .diff-addedline ins{text-decoration:none}table.diff .diff-deletedline{background-color:#fdd}table.diff .diff-deletedline del{background-color:#f99}table.diff .diff-addedline{background-color:#dfd}table.diff .diff-addedline ins{background-color:#9f9}#att-info{background-color:#E4F2FD}table#post-revisions{margin-top:20px}@media screen and (min-width: 4em){#docs-filter-section-tags a.tags-action-button,#docs-filter-section-tags a.tags-action-button:visited{display:block;margin-bottom:1em;padding:0;text-align:center}}@media screen and (min-width: 50em){.entry-content ul#tags-list{-moz-column-count:4;-moz-column-gap:5%;-webkit-column-count:4;-webkit-column-gap:5%;column-count:4;column-gap:5%}}@media screen and (min-width: 71em){.entry-content ul#tags-list{-moz-column-count:5;-moz-column-gap:5%;-webkit-column-count:5;-webkit-column-gap:5%;column-count:5;column-gap:5%}}@media screen and (max-width: 820px){.created-date-cell{display:none}}@media screen and (max-width: 620px){.tags-cell{display:none}}@media screen and (max-width: 520px){.groups-cell{display:none}}@media screen and (max-width: 420px){.attachment-clip-cell,.edited-date-cell{display:none}} +.hide-if-no-js{display:none}.description{font-weight:normal;font-style:italic}.description code{font-style:normal;background:#eee;padding:2px 4px}#bp-create-doc-button{float:right;margin:5px 19px;font-weight:bold}body.bp-docs div.page ul{list-style-type:none}#bp-docs-all-docs{width:auto}.doc-tabs{overflow:hidden}.doc-tabs ul{padding-left:0}.doc-tabs li{float:left;margin:0 5px;list-style-type:none}.doc-tabs li:first-child{margin-left:0}.doc-tabs li a{background:#f1f1f1;text-decoration:none;display:block;padding:4px 10px;border-radius:5px 5px 0 0}.doc-tabs li.current a{background:#f3f3f3;color:#555;font-weight:bold}.doc-header h4{margin-bottom:15px !important}.docs-filter{display:block;width:400px;float:left;margin-bottom:15px}.doc-search{float:right;width:250px;text-align:right}.docs-filter-tags{width:100%}.docs-filter-tags ul li{display:block;width:120px;float:left;padding:6px}.doctable{border-collapse:separate;border-spacing:0}.doctable p{padding:0;margin:0}.doctable tr:hover .row-actions{visibility:visible}.doctable tr:nth-child(even){background-color:#f3f3f3}.doctable .bp-doc-trashed-doc .attachment-clip-cell{border-left:4px solid red}.bp-docs-trashed-doc-notice{color:red;font-size:.9em;font-style:italic}#buddypress #bp-docs-all-docs li{background:#eee}#buddypress div.doc-permissions{float:none;width:auto;margin-bottom:1em}#buddypress table.doctable td{vertical-align:top}#buddypress table.doctable tr:nth-child(even){background-color:#f3f3f3}#buddypress table.doctable tr th{background-color:#f3f3f3}.row-actions{visibility:hidden;padding:2px 0 0}body.mobile .row-actions{visibility:visible}.row-actions a{color:#999;font-size:11px}.row-actions a.delete{color:#f00}#docs-filter-submit{margin:10px 4px}.title-cell{width:30%}.author-cell,.created-date-cell,.edited-date-cell{text-align:center;width:100px}.current-orderby a{padding-left:20px}.asc a{background:url(../images/sort-col-asc.gif) no-repeat}.desc a{background:url(../images/sort-col-desc.gif) no-repeat}.doc-edit-link{margin:15px 0 20px 0}.doc-meta,#doc-meta,.docs #comments{padding-top:20px;border-top:1px solid #ddd}div.docs-info-header{background:#f3f3f3;padding:5px 10px;margin-bottom:10px}#associated_group_summary .item{padding-top:1em}#associated_group_summary .meta{font-size:11px;color:#888}#associated_group_summary img.avatar{margin-left:0}#doc-attachments-ul{margin-top:1em;list-style-type:none}#doc-attachments-ul li{margin:0px 5px 0px 0;padding:6px}#doc-attachments-ul li.even{background-color:#f3f3f3}#doc-attachments-ul .doc-attachment-delete{float:right;margin-top:.15em;margin-right:.3em}.bp-docs-attachment-clip{cursor:pointer;display:block;margin-top:10px}.doc-attachment-mime-icon{display:block;float:left;width:24px;height:24px;margin-right:5px;background:transparent url("../images/mime-type-sprites.png") no-repeat}.doc-attachment-mime-tar,.doc-attachment-mime-zip,.doc-attachment-mime-gz,.doc-attachment-mime-gzip,.doc-attachment-mime-rar,.doc-attachment-mime-7z{background-position:0 0px}.doc-attachment-mime-mp3,.doc-attachment-mime-m4a,.doc-attachment-mime-m4b,.doc-attachment-mime-ra,.doc-attachment-mime-ram,.doc-attachment-mime-wav,.doc-attachment-mime-ogg,.doc-attachment-mime-oga,.doc-attachment-mime-mid,.doc-attachment-mime-midi,.doc-attachment-mime-wma,.doc-attachment-mime-mka{background-position:0 -40px}.doc-attachment-mime-ics{background-position:0 -80px}.doc-attachment-mime-mdb,.doc-attachment-mime-odb{background-position:0 -120px}.doc-attachment-mime-odg{background-position:0 -160px}.doc-attachment-mime-jpg,.doc-attachment-mime-jpeg,.doc-attachment-mime-gif,.doc-attachment-mime-png,.doc-attachment-mime-bmp,.doc-attachment-mime-tif,.doc-attachment-mime-tiff,.doc-attachment-mime-ico{background-position:0 -200px}.doc-attachment-mime-pdf{background-position:0 -240px}.doc-attachment-mime-xla,.doc-attachment-mime-xls,.doc-attachment-mime-xlt,.doc-attachment-mime-xlw,.doc-attachment-mime-xlsx,.doc-attachment-mime-xlsm,.doc-attachment-mime-xlsb,.doc-attachment-mime-xlsb,.doc-attachment-mime-xlsx,.doc-attachment-mime-xlsm,.doc-attachment-mime-xlam,.doc-attachment-mime-ods,.doc-attachment-mime-odc{background-position:0 -280px}.doc-attachment-mime-txt,.doc-attachment-mime-asc,.doc-attachment-mime-c,.doc-attachment-mime-cc,.doc-attachment-mime-h,.doc-attachment-mime-csv,.doc-attachment-mime-tsv,.doc-attachment-mime-ics,.doc-attachment-mime-rtx,.doc-attachment-mime-css,.doc-attachment-mime-htm,.doc-attachment-mime-html{background-position:0 -320px}.doc-attachment-mime-asf,.doc-attachment-mime-asx,.doc-attachment-mime-wax,.doc-attachment-mime-wmv,.doc-attachment-mime-wmx,.doc-attachment-mime-avi,.doc-attachment-mime-divx,.doc-attachment-mime-flv,.doc-attachment-mime-mov,.doc-attachment-mime-qt,.doc-attachment-mime-mpeg,.doc-attachment-mime-mpg,.doc-attachment-mime-mpe,.doc-attachment-mime-mp4,.doc-attachment-mime-m4v,.doc-attachment-mime-ogv,.doc-attachment-mime-mkv{background-position:0 -360px}body.js .bp-docs-attachment-drawer{display:none}.bp-docs-attachment-drawer h4{margin:.5em 0}.bp-docs-attachment-drawer>ul{list-style-type:none}.bp-docs-attachment-drawer>ul>li{margin-left:0}.toggleable.toggle-closed .toggle-content{display:none}.hide-pane,.show-pane,.paperclip-vertical,.paperclip-jaunty{background:url("../images/bp-docs-ui-sprites.png") no-repeat;display:block;float:left;margin-left:10px;margin-top:5px}.hide-pane{background-position:0 0;width:16px;height:16px}.show-pane{background-position:0 -28px;width:16px;height:16px}.paperclip-vertical{background-position:0 -55px;width:13px;height:36px}.paperclip-jaunty{background-position:0 -105px;width:17px;height:36px}.toggle-switch,.entry-content p.toggle-switch{display:block;font-size:1em;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;border:1px solid #ccc;background-color:#f3f3f3;padding:3px 0;text-indent:16px;margin:16px 0 0}.toggle-switch.active-switch,.entry-content p.toggle-switch.active-switch{-moz-border-radius-bottomleft:10px;-webkit-border-bottom-left-radius:10px;-moz-border-radius-bottomright:10px;-webkit-border-bottom-right-radius:10px;border-radius:3px 3px 0px 0px}.toggle-switch a,.entry-content p.toggle-switch a{color:#757575;text-decoration:none;display:block;width:100%;height:100%}.toggle-switch a:hover,.entry-content p.toggle-switch a:hover{font-weight:bold}.standard-form label.toggle-switch{margin:16px 0 0}.toggle-content{-moz-border-radius-bottomleft:2px;-webkit-border-bottom-left-radius:2px;-moz-border-radius-bottomright:2px;-webkit-border-bottom-right-radius:2px;border:1px solid #ccc;border-top:none;overflow:hidden}td.desc-column{width:50%;padding:0px 18px 12px}.docs-info-header .docs-filter{margin-bottom:0}#docs-filter-meta{font-size:.8em;color:#666;margin-bottom:0}a.docs-filter-title{margin:0 7px;text-decoration:none}a.docs-filter-title:visited{color:inherit}a.docs-filter-title.current{font-weight:bold}.docs-filter-section{border:1px solid #ccc;border-radius:2px;font-size:.8em;padding:6px 10px;margin-top:8px;transition:max-height 2s ease;overflow:hidden;position:relative}#docs-filter-section-tags a.tags-action-button,#docs-filter-section-tags a.tags-action-button:visited{display:inline;line-height:3em;text-decoration:none;background:#fff;background-opacity:.5;padding:5px 10px;border-radius:3px}body.js .docs-filter-section{display:none}body.js .docs-filter-section.docs-filter-section-open{display:block}p.currently-viewing{margin-bottom:5px;font-size:.8em;margin-top:8px}p#filter-by-tag{margin-bottom:0}.docs-info-header .toggle-switch{margin-top:8px}ul#tags-list{list-style-type:none;margin-bottom:0;padding:0;-moz-column-count:2;-moz-column-gap:10%;-webkit-column-count:2;-webkit-column-gap:10%;column-count:2;column-gap:10%}ul#tags-list li{margin-left:0}ul#tags-list li.hidden-tag{display:none}ul#tags-list li.tags-ellipses{font-style:italic}.groups-cell{padding-left:10px}.groups-cell ul{list-style-type:none;padding-left:0}.groups-cell ul li{margin-bottom:.5em;margin-left:0}.groups-cell ul li a{vertical-align:middle;font-size:.85em}.groups-cell ul li img.avatar{float:none}select#has-attachment{margin:8px 10px}div#bp-docs-pagination{position:relative;height:30px}div#bp-docs-pagination-count{position:absolute;left:0;top:5px;font-size:.9em;color:#999}div#bp-docs-paginate-links{position:absolute;right:0;top:5px}div#bp-docs-paginate-links a{padding:0 4px}div.doc-content{padding:20px;border:3px solid #f3f3f3}div.doc-content img{margin:10px}div.doc-content img.mceIcon{margin:0}#bp-docs-single-doc-header{overflow:hidden}body.trashed-doc #buddypress{border-left:4px solid red;padding-left:10px}div.doc-permissions{float:right;width:35%;background:#f0f0f0;border:1px solid #ddd;border-radius:3px;padding:4px}div.doc-permissions div:last-child{clear:both}#doc-permissions-summary,#doc-group-summary{font-size:1.0em;padding:3px 12px;border:1px solid}#doc-permissions-summary.doc-public{background:#b2ffb2;border-color:#00ff00}#doc-permissions-summary.doc-limited{background:#ffffe0;border-color:#e6db55}#doc-permissions-summary.doc-private{background:#ffebe8;border-color:#ff0000}a.doc-permissions-toggle{display:block;float:right;font-size:12px;cursor:hand}dl.doc-permissions-types dd,dl.doc-permissions-types dt{height:1.5em}dl.doc-permissions-types dt{width:50%;float:left;clear:left}#doc-group-summary{border-color:#f0f0f0}#doc-group-summary img.avatar{float:none}#doc-permissions-details ul{list-style-type:none;padding-left:0}#doc-permissions-details ul li{margin-bottom:.5em}span.bp-docs-level-icon{display:block;float:left;width:1.2em;height:1.2em;margin:3px 5px}.bp-docs-level-anyone span.bp-docs-level-icon{-moz-border-radius:.6em;-webkit-border-radius:.6em;border-radius:.6em;background:green}.bp-docs-level-friends span.bp-docs-level-icon,.bp-docs-level-loggedin span.bp-docs-level-icon,.bp-docs-level-group-members span.bp-docs-level-icon{width:0;height:0;border-left:.6em solid transparent;border-right:.6em solid transparent;border-bottom:1.2em solid yellow}.bp-docs-level-admins-mods span.bp-docs-level-icon,.bp-docs-level-no-one span.bp-docs-level-icon,.bp-docs-level-creator span.bp-docs-level-icon{background:red}div.doc-is-locked .toggle-content{border:2px solid #f33;margin-top:5px;padding:7px 10px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}div.doc-meta p{margin-bottom:5px}a.nonexistent-doc{color:#f33}h2.doc-title{display:inline-block;width:50%}.comments-closed{padding:10px 20px;background:#f3f3f3;margin-top:10px}#respond{margin-top:20px}.doc-content ul{list-style:disc}.doc-content ol{list-style:decimal}.doc-content li{margin-left:20px}.doc-content blockquote{background:#f3f3f3;padding:5px;margin:10px 30px}div.hidden{display:none}table.group-docs-options td.label{width:200px}table.diff{width:100%}table.diff col.content{width:50%}table.diff tr{background-color:transparent}table.diff td,table.diff th{padding:.5em;font-family:Consolas, Monaco, Courier, monospace;border:none}table.diff .diff-deletedline del,table.diff .diff-addedline ins{text-decoration:none}table.diff .diff-deletedline{background-color:#fdd}table.diff .diff-deletedline del{background-color:#f99}table.diff .diff-addedline{background-color:#dfd}table.diff .diff-addedline ins{background-color:#9f9}#att-info{background-color:#E4F2FD}table#post-revisions{margin-top:20px}@media screen and (min-width: 4em){#docs-filter-section-tags a.tags-action-button,#docs-filter-section-tags a.tags-action-button:visited{display:block;margin-bottom:1em;padding:0;text-align:center}}@media screen and (min-width: 50em){.entry-content ul#tags-list{-moz-column-count:4;-moz-column-gap:5%;-webkit-column-count:4;-webkit-column-gap:5%;column-count:4;column-gap:5%}}@media screen and (min-width: 71em){.entry-content ul#tags-list{-moz-column-count:5;-moz-column-gap:5%;-webkit-column-count:5;-webkit-column-gap:5%;column-count:5;column-gap:5%}}@media screen and (max-width: 820px){.created-date-cell{display:none}}@media screen and (max-width: 620px){.tags-cell{display:none}}@media screen and (max-width: 520px){.groups-cell{display:none}}@media screen and (max-width: 420px){.attachment-clip-cell,.edited-date-cell{display:none}} diff --git a/includes/scss/screen.scss b/includes/scss/screen.scss index b2b160b1..0361d928 100644 --- a/includes/scss/screen.scss +++ b/includes/scss/screen.scss @@ -68,7 +68,7 @@ body.bp-docs div.page ul { padding: 4px 10px; border-radius: 5px 5px 0 0; } - + &.current a { background: $grey; color: #555; @@ -108,12 +108,12 @@ body.bp-docs div.page ul { .doctable { border-collapse: separate; border-spacing: 0; - + p { padding: 0; margin: 0; } - + tr:hover .row-actions { visibility: visible; } @@ -196,7 +196,7 @@ body.mobile .row-actions { } .group-cell { - + } .current-orderby a { @@ -463,9 +463,9 @@ body.js .bp-docs-attachment-drawer { -webkit-border-bottom-right-radius: 10px; border-radius: 3px 3px 0px 0px; } - + a { - color: $grey_text; + color: $grey_text; text-decoration: none; display: block; width: 100%; @@ -492,7 +492,7 @@ body.js .bp-docs-attachment-drawer { } td.desc-column { - width: 300px; + width: 50%; padding: 0px 18px 12px; } @@ -525,7 +525,7 @@ a.docs-filter-title.current { font-size: .8em; padding: 6px 10px; margin-top: 8px; - transition: max-height 2s ease; + transition: max-height 2s ease; overflow: hidden; position: relative; } @@ -844,7 +844,7 @@ table#post-revisions { } //Media query for most screens, unseen by IE 7 or 8 -@media screen and (min-width:4em) { +@media screen and (min-width:4em) { #docs-filter-section-tags a.tags-action-button, #docs-filter-section-tags a.tags-action-button:visited { display: block; // Let the button span the entire box @@ -854,13 +854,13 @@ table#post-revisions { } } //Media query for larger screens, like tablet -@media screen and (min-width:50em) { +@media screen and (min-width:50em) { .entry-content ul#tags-list { @include multi-columns(4, 5%); } } //Media query for larger screens, like desktop -@media screen and (min-width:71em) { +@media screen and (min-width:71em) { .entry-content ul#tags-list { @include multi-columns(5, 5%); } From e806fc35addc8392c3c03c00ff43354ec496b279 Mon Sep 17 00:00:00 2001 From: Boone B Gorges Date: Fri, 14 Mar 2014 10:24:44 -0400 Subject: [PATCH 35/35] Bump version numbers to 1.6.0 --- loader.php | 4 ++-- readme.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/loader.php b/loader.php index 420a8d0b..e648089b 100644 --- a/loader.php +++ b/loader.php @@ -3,7 +3,7 @@ Plugin Name: BuddyPress Docs Plugin URI: http://github.com/boonebgorges/buddypress-docs Description: Adds collaborative Docs to BuddyPress -Version: 1.5.7 +Version: 1.6.0 Author: Boone B Gorges Author URI: http://boone.gorg.es Licence: GPLv3 @@ -13,7 +13,7 @@ It's on like Donkey Kong */ -define( 'BP_DOCS_VERSION', '1.5.7' ); +define( 'BP_DOCS_VERSION', '1.6.0' ); // BuddyPress Docs introduces a lot of overhead. Unless otherwise specified, // don't load the plugin on subsites of an MS install diff --git a/readme.txt b/readme.txt index 281211fe..3ce9c01a 100755 --- a/readme.txt +++ b/readme.txt @@ -3,8 +3,8 @@ Contributors: boonebgorges, cuny-academic-commons Donate link: http://teleogistic.net/donate Tags: buddypress, docs, wiki, documents, collaboration Requires at least: WordPress 3.3, BuddyPress 1.5 -Tested up to: WordPress 3.8, BuddyPress 1.9.2 -Stable tag: 1.5.7 +Tested up to: WordPress 3.9, BuddyPress 2.0.0 +Stable tag: 1.6.0 Adds collaborative Docs to BuddyPress.