]> git.immae.eu Git - github/shaarli/Shaarli.git/commitdiff
Merge pull request #1621 from ArthurHoaro/feature/tag-separators
authorArthurHoaro <arthur@hoa.ro>
Sun, 8 Nov 2020 13:07:33 +0000 (14:07 +0100)
committerGitHub <noreply@github.com>
Sun, 8 Nov 2020 13:07:33 +0000 (14:07 +0100)
1  2 
application/bookmark/LinkUtils.php
assets/default/scss/shaarli.scss
tests/bookmark/LinkUtilsTest.php

index a74fda5795c09e9f0fd6b3ed1e8d98b81226bc5d,9493b0aa894e00de160684be54dc3f8ab4aa4bab..cf97e3b0a904a08d72a5ee7d3467efb1536f5c96
@@@ -68,16 -68,16 +68,16 @@@ function html_extract_tag($tag, $html
      $properties = implode('|', $propertiesKey);
      // We need a OR here to accept either 'property=og:noquote' or 'property="og:unrelated og:my-tag"'
      $orCondition  = '["\']?(?:og:)?'. $tag .'["\']?|["\'][^\'"]*?(?:og:)?' . $tag . '[^\'"]*?[\'"]';
 -    // Try to retrieve OpenGraph image.
 -    $ogRegex = '#<meta[^>]+(?:'. $properties .')=(?:'. $orCondition .')[^>]*content=["\'](.*?)["\'].*?>#';
 +    // Try to retrieve OpenGraph tag.
 +    $ogRegex = '#<meta[^>]+(?:'. $properties .')=(?:'. $orCondition .')[^>]*content=(["\'])([^\1]*?)\1.*?>#';
      // If the attributes are not in the order property => content (e.g. Github)
      // New regex to keep this readable... more or less.
 -    $ogRegexReverse = '#<meta[^>]+content=["\'](.*?)["\'][^>]+(?:'. $properties .')=(?:'. $orCondition .').*?>#';
 +    $ogRegexReverse = '#<meta[^>]+content=(["\'])([^\1]*?)\1[^>]+(?:'. $properties .')=(?:'. $orCondition .').*?>#';
  
      if (preg_match($ogRegex, $html, $matches) > 0
          || preg_match($ogRegexReverse, $html, $matches) > 0
      ) {
 -        return $matches[1];
 +        return $matches[2];
      }
  
      return false;
@@@ -176,3 -176,49 +176,49 @@@ function is_note($linkUrl
  {
      return isset($linkUrl[0]) && $linkUrl[0] === '?';
  }
+ /**
+  * Extract an array of tags from a given tag string, with provided separator.
+  *
+  * @param string|null $tags      String containing a list of tags separated by $separator.
+  * @param string      $separator Shaarli's default: ' ' (whitespace)
+  *
+  * @return array List of tags
+  */
+ function tags_str2array(?string $tags, string $separator): array
+ {
+     // For whitespaces, we use the special \s regex character
+     $separator = $separator === ' ' ? '\s' : $separator;
+     return preg_split('/\s*' . $separator . '+\s*/', trim($tags) ?? '', -1, PREG_SPLIT_NO_EMPTY);
+ }
+ /**
+  * Return a tag string with provided separator from a list of tags.
+  * Note that given array is clean up by tags_filter().
+  *
+  * @param array|null $tags      List of tags
+  * @param string     $separator
+  *
+  * @return string
+  */
+ function tags_array2str(?array $tags, string $separator): string
+ {
+     return implode($separator, tags_filter($tags, $separator));
+ }
+ /**
+  * Clean an array of tags: trim + remove empty entries
+  *
+  * @param array|null $tags List of tags
+  * @param string     $separator
+  *
+  * @return array
+  */
+ function tags_filter(?array $tags, string $separator): array
+ {
+     $trimDefault = " \t\n\r\0\x0B";
+     return array_values(array_filter(array_map(function (string $entry) use ($separator, $trimDefault): string {
+         return trim($entry, $trimDefault . $separator);
+     }, $tags ?? [])));
+ }
index 3404ce124035b1a2d456b230901262f8c95676d7,ed774a9d6e63cacb9564155c1dc3523c14e85623..cc8ccc1e0d4811de5b526e65d886f0b820058606
@@@ -139,6 -139,16 +139,16 @@@ body
    }
  }
  
+ .page-form,
+ .pure-alert {
+   code {
+     display: inline-block;
+     padding: 0 2px;
+     color: $dark-grey;
+     background-color: var(--background-color);
+   }
+ }
  // Make pure-extras alert closable.
  .pure-alert-closable {
    .fa-times {
@@@ -1266,15 -1276,11 +1276,15 @@@ form 
      margin: 70px 0 25px;
    }
  
 +  a {
 +    color: var(--main-color);
 +  }
 +
    pre {
      margin: 0 20%;
      padding: 20px 0;
      text-align: left;
 -    line-height: .7em;
 +    line-height: 1em;
    }
  }
  
index 9bddf84b3f02939ec9afb479948eaee368d4a1ff,c2f9f9305716829b91ba6ffe36cfc9a8a29cb80e..ddab4e3caebd0e7070273738054f9f58d0821aa0
@@@ -168,36 -168,6 +168,36 @@@ class LinkUtilsTest extends TestCas
          $this->assertEquals($description, html_extract_tag('description', $html));
      }
  
 +    /**
 +     * Test html_extract_tag() with double quoted content containing single quote, and the opposite.
 +     */
 +    public function testHtmlExtractExistentNameTagWithMixedQuotes(): void
 +    {
 +        $description = 'Bob and Alice share M&M\'s.';
 +
 +        $html = '<meta property="og:description" content="' . $description . '">';
 +        $this->assertEquals($description, html_extract_tag('description', $html));
 +
 +        $html = '<meta tag1="content1" property="og:unrelated1 og:description og:unrelated2" '.
 +            'tag2="content2" content="' . $description . '" tag3="content3">';
 +        $this->assertEquals($description, html_extract_tag('description', $html));
 +
 +        $html = '<meta property="og:description" name="description" content="' . $description . '">';
 +        $this->assertEquals($description, html_extract_tag('description', $html));
 +
 +        $description = 'Bob and Alice share "cookies".';
 +
 +        $html = '<meta property="og:description" content=\'' . $description . '\'>';
 +        $this->assertEquals($description, html_extract_tag('description', $html));
 +
 +        $html = '<meta tag1="content1" property="og:unrelated1 og:description og:unrelated2" '.
 +            'tag2="content2" content=\'' . $description . '\' tag3="content3">';
 +        $this->assertEquals($description, html_extract_tag('description', $html));
 +
 +        $html = '<meta property="og:description" name="description" content=\'' . $description . '\'>';
 +        $this->assertEquals($description, html_extract_tag('description', $html));
 +    }
 +
      /**
       * Test html_extract_tag() when the tag <meta name= is not found.
       */
              $title,
              $desc,
              $keywords,
-             false
+             false,
+             ' '
          );
  
          $data = [
              $title,
              $desc,
              $keywords,
-             false
+             false,
+             ' '
          );
  
          $data = [
              $title,
              $desc,
              $keywords,
-             false
+             false,
+             ' '
          );
  
          $data = [
              $title,
              $desc,
              $keywords,
-             false
+             false,
+             ' '
          );
  
          $data = [
              $title,
              $desc,
              $keywords,
-             true
+             true,
+             ' '
          );
          $data = [
              'th=device-width">'
          $this->assertFalse(is_note('https://github.com/shaarli/Shaarli/?hi'));
      }
  
+     /**
+      * Test tags_str2array with whitespace separator.
+      */
+     public function testTagsStr2ArrayWithSpaceSeparator(): void
+     {
+         $separator = ' ';
+         static::assertSame(['tag1', 'tag2', 'tag3'], tags_str2array('tag1 tag2 tag3', $separator));
+         static::assertSame(['tag1', 'tag2', 'tag3'], tags_str2array('tag1  tag2     tag3', $separator));
+         static::assertSame(['tag1', 'tag2', 'tag3'], tags_str2array('   tag1  tag2     tag3   ', $separator));
+         static::assertSame(['tag1@', 'tag2,', '.tag3'], tags_str2array('   tag1@  tag2,     .tag3   ', $separator));
+         static::assertSame([], tags_str2array('', $separator));
+         static::assertSame([], tags_str2array('   ', $separator));
+         static::assertSame([], tags_str2array(null, $separator));
+     }
+     /**
+      * Test tags_str2array with @ separator.
+      */
+     public function testTagsStr2ArrayWithCharSeparator(): void
+     {
+         $separator = '@';
+         static::assertSame(['tag1', 'tag2', 'tag3'], tags_str2array('tag1@tag2@tag3', $separator));
+         static::assertSame(['tag1', 'tag2', 'tag3'], tags_str2array('tag1@@@@tag2@@@@tag3', $separator));
+         static::assertSame(['tag1', 'tag2', 'tag3'], tags_str2array('@@@tag1@@@tag2@@@@tag3@@', $separator));
+         static::assertSame(
+             ['tag1#', 'tag2, and other', '.tag3'],
+             tags_str2array('@@@   tag1#     @@@ tag2, and other @@@@.tag3@@', $separator)
+         );
+         static::assertSame([], tags_str2array('', $separator));
+         static::assertSame([], tags_str2array('   ', $separator));
+         static::assertSame([], tags_str2array(null, $separator));
+     }
+     /**
+      * Test tags_array2str with ' ' separator.
+      */
+     public function testTagsArray2StrWithSpaceSeparator(): void
+     {
+         $separator = ' ';
+         static::assertSame('tag1 tag2 tag3', tags_array2str(['tag1', 'tag2', 'tag3'], $separator));
+         static::assertSame('tag1, tag2@ tag3', tags_array2str(['tag1,', 'tag2@', 'tag3'], $separator));
+         static::assertSame('tag1 tag2 tag3', tags_array2str(['   tag1   ', 'tag2', 'tag3   '], $separator));
+         static::assertSame('tag1 tag2 tag3', tags_array2str(['   tag1   ', ' ', 'tag2', '   ', 'tag3   '], $separator));
+         static::assertSame('tag1', tags_array2str(['   tag1   '], $separator));
+         static::assertSame('', tags_array2str(['  '], $separator));
+         static::assertSame('', tags_array2str([], $separator));
+         static::assertSame('', tags_array2str(null, $separator));
+     }
+     /**
+      * Test tags_array2str with @ separator.
+      */
+     public function testTagsArray2StrWithCharSeparator(): void
+     {
+         $separator = '@';
+         static::assertSame('tag1@tag2@tag3', tags_array2str(['tag1', 'tag2', 'tag3'], $separator));
+         static::assertSame('tag1,@tag2@tag3', tags_array2str(['tag1,', 'tag2@', 'tag3'], $separator));
+         static::assertSame(
+             'tag1@tag2, and other@tag3',
+             tags_array2str(['@@@@ tag1@@@', ' @tag2, and other @', 'tag3@@@@'], $separator)
+         );
+         static::assertSame('tag1@tag2@tag3', tags_array2str(['@@@tag1@@@', '@', 'tag2', '@@@', 'tag3@@@'], $separator));
+         static::assertSame('tag1', tags_array2str(['@@@@tag1@@@@'], $separator));
+         static::assertSame('', tags_array2str(['@@@'], $separator));
+         static::assertSame('', tags_array2str([], $separator));
+         static::assertSame('', tags_array2str(null, $separator));
+     }
+     /**
+      * Test tags_array2str with @ separator.
+      */
+     public function testTagsFilterWithSpaceSeparator(): void
+     {
+         $separator = ' ';
+         static::assertSame(['tag1', 'tag2', 'tag3'], tags_filter(['tag1', 'tag2', 'tag3'], $separator));
+         static::assertSame(['tag1,', 'tag2@', 'tag3'], tags_filter(['tag1,', 'tag2@', 'tag3'], $separator));
+         static::assertSame(['tag1', 'tag2', 'tag3'], tags_filter(['   tag1   ', 'tag2', 'tag3   '], $separator));
+         static::assertSame(['tag1', 'tag2', 'tag3'], tags_filter(['   tag1   ', ' ', 'tag2', '   ', 'tag3   '], $separator));
+         static::assertSame(['tag1'], tags_filter(['   tag1   '], $separator));
+         static::assertSame([], tags_filter(['  '], $separator));
+         static::assertSame([], tags_filter([], $separator));
+         static::assertSame([], tags_filter(null, $separator));
+     }
+     /**
+      * Test tags_array2str with @ separator.
+      */
+     public function testTagsArrayFilterWithSpaceSeparator(): void
+     {
+         $separator = '@';
+         static::assertSame(['tag1', 'tag2', 'tag3'], tags_filter(['tag1', 'tag2', 'tag3'], $separator));
+         static::assertSame(['tag1,', 'tag2#', 'tag3'], tags_filter(['tag1,', 'tag2#', 'tag3'], $separator));
+         static::assertSame(
+             ['tag1', 'tag2, and other', 'tag3'],
+             tags_filter(['@@@@ tag1@@@', ' @tag2, and other @', 'tag3@@@@'], $separator)
+         );
+         static::assertSame(['tag1', 'tag2', 'tag3'], tags_filter(['@@@tag1@@@', '@', 'tag2', '@@@', 'tag3@@@'], $separator));
+         static::assertSame(['tag1'], tags_filter(['@@@@tag1@@@@'], $separator));
+         static::assertSame([], tags_filter(['@@@'], $separator));
+         static::assertSame([], tags_filter([], $separator));
+         static::assertSame([], tags_filter(null, $separator));
+     }
      /**
       * Util function to build an hashtag link.
       *