ACF Content Analysis for Yoast SEO - Version 2.1.0

Version Description

Released July 10th, 2018

Bugfixes: * Fixes a bug where attempting to get the ACF version, wouldn't always be reliable. This would lead the plugin to think that a newer version was installed than what was actually present. * Fixes potential conflicts with other plugins due to generic variable naming. * Fixes a bug where the YoastSEO ACF Content analysis would attempted to be loaded, although it wasn't available.

Other: * Adds filter examples to the readme.

Download this release

Release Info

Developer Yoast
Plugin Icon 128x128 ACF Content Analysis for Yoast SEO
Version 2.1.0
Comparing to
See all releases

Code changes from version 2.0.1 to 2.1.0

Files changed (69) hide show
  1. .eslintrc +12 -0
  2. inc/{class-ac-yoast-acf-content-analysis.php → ac-yoast-seo-acf-content-analysis.php} +14 -17
  3. inc/{class-yoast-acf-analysis-assets.php → assets.php} +15 -3
  4. inc/configuration/{class-yoast-acf-analysis-configuration.php → configuration.php} +29 -5
  5. inc/configuration/{class-yoast-acf-analysis-string-store.php → string-store.php} +10 -1
  6. inc/dependencies/{class-yoast-acf-analysis-dependency-afc.php → dependency-acf.php} +8 -0
  7. inc/dependencies/{interface-yoast-acf-analysis-depencency.php → dependency-interface.php} +8 -0
  8. inc/dependencies/{class-yoast-acf-analysis-dependency-yoast-seo.php → dependency-yoast-seo.php} +8 -0
  9. inc/{class-yoast-acf-analysis-facade.php → facade.php} +7 -3
  10. inc/{class-yoast-acf-analysis-registry.php → registry.php} +9 -0
  11. inc/{class-yoast-acf-analysis-requirements.php → requirements.php} +10 -2
  12. js/src/app.js +64 -63
  13. js/src/cache/cache.attachments.js +33 -36
  14. js/src/cache/cache.js +28 -34
  15. js/src/collect/collect-v4.js +14 -14
  16. js/src/collect/collect-v5.js +54 -66
  17. js/src/collect/collect.js +47 -56
  18. js/src/config/config.js +2 -1
  19. js/src/helper.js +2 -2
  20. js/src/main.js +9 -14
  21. js/src/replacevars.js +39 -40
  22. js/src/scraper-store.js +65 -62
  23. js/src/scraper/scraper.email.js +11 -16
  24. js/src/scraper/scraper.gallery.js +25 -33
  25. js/src/scraper/scraper.image.js +20 -26
  26. js/src/scraper/scraper.link.js +33 -0
  27. js/src/scraper/scraper.taxonomy.js +49 -61
  28. js/src/scraper/scraper.text.js +33 -41
  29. js/src/scraper/scraper.textarea.js +11 -16
  30. js/src/scraper/scraper.url.js +11 -16
  31. js/src/scraper/scraper.wysiwyg.js +41 -46
  32. js/yoast-acf-analysis.js +582 -617
  33. license.txt +22 -1
  34. package-lock.json +0 -3407
  35. readme.txt +45 -4
  36. renovate.json +12 -0
  37. ruleset.xml +0 -23
  38. tests/js/system/data/acf4.php +8 -0
  39. tests/js/system/data/acf5.php +25 -1
  40. tests/js/system/data/test-data-loader-functions.php +32 -0
  41. tests/js/system/nightwatch.conf.example.js +2 -2
  42. tests/js/system/nightwatch.json +1 -1
  43. tests/js/system/pages/WordPressHelper.js +3 -1
  44. tests/js/system/tests/acf5/content-pro.js +33 -0
  45. tests/js/system/tests/acf5/relational.js +4 -4
  46. tests/js/system/tests/general/basic.js +2 -1
  47. tests/js/system/tests/general/filters.js +2 -2
  48. tests/php/unit/Configuration/StringStoreTest.php +0 -118
  49. tests/php/unit/Configuration/{ConfigurationTest.php → configuration-test.php} +34 -20
  50. tests/php/unit/Configuration/string-store-test.php +117 -0
  51. tests/php/unit/Dependencies/ACFClass.php +0 -5
  52. tests/php/unit/Dependencies/{ACFDependencyTest.php → acf-dependency-test.php} +13 -7
  53. tests/php/unit/Dependencies/acf.php +13 -0
  54. tests/php/unit/Dependencies/{YoastSEODependencyTest.php → yoast-seo-dependency-test.php} +13 -7
  55. tests/php/unit/Doubles/failing-dependency.php +22 -0
  56. tests/php/unit/Doubles/passing-dependency.php +22 -0
  57. tests/php/unit/RequirementsTest.php +0 -90
  58. tests/php/unit/{AssetsTest.php → assets-test.php} +13 -7
  59. tests/php/unit/{MainTest.php → main-test.php} +13 -15
  60. tests/php/unit/{RegistryTest.php → registry-test.php} +13 -10
  61. tests/php/unit/requirements-test.php +58 -0
  62. vendor/autoload.php +1 -1
  63. vendor/autoload_52.php +1 -1
  64. vendor/composer/ClassLoader.php +2 -2
  65. vendor/composer/autoload_classmap.php +10 -10
  66. vendor/composer/autoload_real.php +4 -4
  67. vendor/composer/autoload_real_52.php +3 -3
  68. vendor/composer/autoload_static.php +143 -0
  69. yoast-acf-analysis.php +41 -32
.eslintrc ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ extends: yoast
2
+
3
+ rules:
4
+ complexity: [1, 6]
5
+ camelcase: 1
6
+ brace-style: 2
7
+ max-len: 1
8
+ max-statements: 1
9
+ valid-jsdoc: 2
10
+ global-require: 1
11
+ strict: 1
12
+ keyword-spacing: 2
inc/{class-ac-yoast-acf-content-analysis.php → ac-yoast-seo-acf-content-analysis.php} RENAMED
@@ -1,8 +1,11 @@
1
  <?php
2
-
3
  /**
4
- * Class Yoast_ACF_Analysis
5
  *
 
 
 
 
6
  * Adds ACF data to the content analyses of WordPress SEO.
7
  */
8
  class AC_Yoast_SEO_ACF_Content_Analysis {
@@ -30,10 +33,6 @@ class AC_Yoast_SEO_ACF_Content_Analysis {
30
 
31
  $this->boot();
32
 
33
- if ( defined( 'AC_YOAST_ACF_ANALYSIS_ENVIRONMENT' ) && 'development' === AC_YOAST_ACF_ANALYSIS_ENVIRONMENT ) {
34
- $this->boot_dev();
35
- }
36
-
37
  $this->register_config_filters();
38
 
39
  $assets = new Yoast_ACF_Analysis_Assets();
@@ -78,21 +77,13 @@ class AC_Yoast_SEO_ACF_Content_Analysis {
78
  $registry->add( 'config', $configuration );
79
  }
80
 
81
- /**
82
- * Boots the plugin for dev environment.
83
- */
84
- public function boot_dev() {
85
- $version = ( -1 === version_compare( get_option( 'acf_version' ), 5 ) ) ? '4' : '5';
86
- require_once AC_SEO_ACF_ANALYSIS_PLUGIN_PATH . '/tests/js/system/data/acf' . $version . '.php';
87
- }
88
-
89
  /**
90
  * Filters the Scraper Configuration to add the headlines configuration for the text scraper.
91
  */
92
  protected function register_config_filters() {
93
  add_filter(
94
  Yoast_ACF_Analysis_Facade::get_filter_name( 'scraper_config' ),
95
- array( $this, 'filter_scraper_config')
96
  );
97
  }
98
 
@@ -207,8 +198,14 @@ class AC_Yoast_SEO_ACF_Content_Analysis {
207
  $blacklist->add( $type );
208
  }
209
 
210
- if ( -1 === version_compare( get_option( 'acf_version' ), 5 ) ) {
211
- // It is not worth supporting the Pro Addons to v4, as Pro users can just switch to v5.
 
 
 
 
 
 
212
  $blacklist->remove( 'gallery' );
213
  $blacklist->remove( 'repeater' );
214
  $blacklist->remove( 'flexible_content' );
1
  <?php
 
2
  /**
3
+ * ACF Content Analysis for Yoast SEO plugin file.
4
  *
5
+ * @package YoastACFAnalysis
6
+ */
7
+
8
+ /**
9
  * Adds ACF data to the content analyses of WordPress SEO.
10
  */
11
  class AC_Yoast_SEO_ACF_Content_Analysis {
33
 
34
  $this->boot();
35
 
 
 
 
 
36
  $this->register_config_filters();
37
 
38
  $assets = new Yoast_ACF_Analysis_Assets();
77
  $registry->add( 'config', $configuration );
78
  }
79
 
 
 
 
 
 
 
 
 
80
  /**
81
  * Filters the Scraper Configuration to add the headlines configuration for the text scraper.
82
  */
83
  protected function register_config_filters() {
84
  add_filter(
85
  Yoast_ACF_Analysis_Facade::get_filter_name( 'scraper_config' ),
86
+ array( $this, 'filter_scraper_config' )
87
  );
88
  }
89
 
198
  $blacklist->add( $type );
199
  }
200
 
201
+ /**
202
+ * Disable Pro fields for anything but ACF 5 pro.
203
+ *
204
+ * - It is not worth supporting the Pro Addons to v4, as Pro users can just switch to v5.
205
+ * - ACF v5 FREE on the other hand does not support these fields either.
206
+ */
207
+ if ( ! defined( 'ACF_PRO' ) || ! ACF_PRO ) {
208
+
209
  $blacklist->remove( 'gallery' );
210
  $blacklist->remove( 'repeater' );
211
  $blacklist->remove( 'flexible_content' );
inc/{class-yoast-acf-analysis-assets.php → assets.php} RENAMED
@@ -1,12 +1,20 @@
1
  <?php
2
-
 
 
 
 
3
 
4
  /**
5
  * Class Yoast_ACF_Analysis_Frontend
6
  */
7
  class Yoast_ACF_Analysis_Assets {
8
 
9
- /** @var array Plugin information. */
 
 
 
 
10
  protected $plugin_data;
11
 
12
  /**
@@ -24,7 +32,11 @@ class Yoast_ACF_Analysis_Assets {
24
  public function enqueue_scripts() {
25
  global $pagenow;
26
 
27
- /* @var $config Yoast_ACF_Analysis_Configuration */
 
 
 
 
28
  $config = Yoast_ACF_Analysis_Facade::get_registry()->get( 'config' );
29
 
30
  // Post page enqueue.
1
  <?php
2
+ /**
3
+ * ACF Content Analysis for Yoast SEO plugin file.
4
+ *
5
+ * @package YoastACFAnalysis
6
+ */
7
 
8
  /**
9
  * Class Yoast_ACF_Analysis_Frontend
10
  */
11
  class Yoast_ACF_Analysis_Assets {
12
 
13
+ /**
14
+ * Plugin information.
15
+ *
16
+ * @var array
17
+ */
18
  protected $plugin_data;
19
 
20
  /**
32
  public function enqueue_scripts() {
33
  global $pagenow;
34
 
35
+ /**
36
+ * Yoast ACF plugin configuration.
37
+ *
38
+ * @var \Yoast_ACF_Analysis_Configuration
39
+ */
40
  $config = Yoast_ACF_Analysis_Facade::get_registry()->get( 'config' );
41
 
42
  // Post page enqueue.
inc/configuration/{class-yoast-acf-analysis-configuration.php → configuration.php} RENAMED
@@ -1,5 +1,9 @@
1
  <?php
2
-
 
 
 
 
3
 
4
  /**
5
  * Class Yoast_ACF_Analysis_Configuration_Default
@@ -21,13 +25,23 @@ class Yoast_ACF_Analysis_Configuration {
21
  */
22
  protected $field_selectors;
23
 
24
- /** @var int Refresh rate to use */
 
 
 
 
25
  protected $refresh_rate = 1000;
26
 
27
- /** @var array Scraper configuration */
 
 
 
 
28
  protected $scraper_config = array();
29
 
30
  /**
 
 
31
  * @param Yoast_ACF_Analysis_String_Store $blacklist_type Blacklist Type Configuration Object.
32
  * @param Yoast_ACF_Analysis_String_Store $blacklist_name Blacklist Name Configuration Object.
33
  * @param Yoast_ACF_Analysis_String_Store $field_selectors Field Selectors Configuration Object.
@@ -48,7 +62,13 @@ class Yoast_ACF_Analysis_Configuration {
48
  * @return string The ACF version.
49
  */
50
  public function get_acf_version() {
51
- return get_option( 'acf_version' );
 
 
 
 
 
 
52
  }
53
 
54
  /**
@@ -131,7 +151,9 @@ class Yoast_ACF_Analysis_Configuration {
131
  }
132
 
133
  /**
134
- * @return bool
 
 
135
  */
136
  public function is_debug() {
137
  return ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG === true );
@@ -222,6 +244,8 @@ class Yoast_ACF_Analysis_Configuration {
222
  }
223
 
224
  /**
 
 
225
  * @return array
226
  */
227
  public function to_array() {
1
  <?php
2
+ /**
3
+ * ACF Content Analysis for Yoast SEO plugin file.
4
+ *
5
+ * @package YoastACFAnalysis
6
+ */
7
 
8
  /**
9
  * Class Yoast_ACF_Analysis_Configuration_Default
25
  */
26
  protected $field_selectors;
27
 
28
+ /**
29
+ * Refresh rate to use.
30
+ *
31
+ * @var int
32
+ */
33
  protected $refresh_rate = 1000;
34
 
35
+ /**
36
+ * Scraper configuration.
37
+ *
38
+ * @var array
39
+ */
40
  protected $scraper_config = array();
41
 
42
  /**
43
+ * Yoast_ACF_Analysis_Configuration constructor.
44
+ *
45
  * @param Yoast_ACF_Analysis_String_Store $blacklist_type Blacklist Type Configuration Object.
46
  * @param Yoast_ACF_Analysis_String_Store $blacklist_name Blacklist Name Configuration Object.
47
  * @param Yoast_ACF_Analysis_String_Store $field_selectors Field Selectors Configuration Object.
62
  * @return string The ACF version.
63
  */
64
  public function get_acf_version() {
65
+ // ACF 5 introduces `acf_get_setting`, so this might not always be available.
66
+ if ( function_exists( 'acf_get_setting' ) ) {
67
+ return acf_get_setting( 'version' );
68
+ }
69
+
70
+ // Fall back on filter use.
71
+ return apply_filters( 'acf/get_info', 'version' );
72
  }
73
 
74
  /**
151
  }
152
 
153
  /**
154
+ * Determines if debug mode is enabled.
155
+ *
156
+ * @return bool True if debug mode is enabled. False otherwise.
157
  */
158
  public function is_debug() {
159
  return ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG === true );
244
  }
245
 
246
  /**
247
+ * Retrieves an array representation of the current object.
248
+ *
249
  * @return array
250
  */
251
  public function to_array() {
inc/configuration/{class-yoast-acf-analysis-string-store.php → string-store.php} RENAMED
@@ -1,4 +1,9 @@
1
  <?php
 
 
 
 
 
2
 
3
  /**
4
  * Class Yoast_ACF_Analysis_String_Store
@@ -7,7 +12,11 @@
7
  */
8
  class Yoast_ACF_Analysis_String_Store {
9
 
10
- /** @var array List of stored items. */
 
 
 
 
11
  protected $items = array();
12
 
13
  /**
1
  <?php
2
+ /**
3
+ * ACF Content Analysis for Yoast SEO plugin file.
4
+ *
5
+ * @package YoastACFAnalysis
6
+ */
7
 
8
  /**
9
  * Class Yoast_ACF_Analysis_String_Store
12
  */
13
  class Yoast_ACF_Analysis_String_Store {
14
 
15
+ /**
16
+ * List of stored items.
17
+ *
18
+ * @var array
19
+ */
20
  protected $items = array();
21
 
22
  /**
inc/dependencies/{class-yoast-acf-analysis-dependency-afc.php → dependency-acf.php} RENAMED
@@ -1,5 +1,13 @@
1
  <?php
 
 
 
 
 
2
 
 
 
 
3
  final class Yoast_ACF_Analysis_Dependency_ACF implements Yoast_ACF_Analysis_Dependency {
4
 
5
  /**
1
  <?php
2
+ /**
3
+ * ACF Content Analysis for Yoast SEO plugin file.
4
+ *
5
+ * @package YoastACFAnalysis
6
+ */
7
 
8
+ /**
9
+ * Checks wether ACF is installed.
10
+ */
11
  final class Yoast_ACF_Analysis_Dependency_ACF implements Yoast_ACF_Analysis_Dependency {
12
 
13
  /**
inc/dependencies/{interface-yoast-acf-analysis-depencency.php → dependency-interface.php} RENAMED
@@ -1,5 +1,13 @@
1
  <?php
 
 
 
 
 
2
 
 
 
 
3
  interface Yoast_ACF_Analysis_Dependency {
4
  /**
5
  * Checks if this dependency is met.
1
  <?php
2
+ /**
3
+ * ACF Content Analysis for Yoast SEO plugin file.
4
+ *
5
+ * @package YoastACFAnalysis
6
+ */
7
 
8
+ /**
9
+ * Interface Yoast_ACF_Analysis_Dependency.
10
+ */
11
  interface Yoast_ACF_Analysis_Dependency {
12
  /**
13
  * Checks if this dependency is met.
inc/dependencies/{class-yoast-acf-analysis-dependency-yoast-seo.php → dependency-yoast-seo.php} RENAMED
@@ -1,5 +1,13 @@
1
  <?php
 
 
 
 
 
2
 
 
 
 
3
  final class Yoast_ACF_Analysis_Dependency_Yoast_SEO implements Yoast_ACF_Analysis_Dependency {
4
 
5
  const MINIMAL_REQUIRED_VERSION = 3.2;
1
  <?php
2
+ /**
3
+ * ACF Content Analysis for Yoast SEO plugin file.
4
+ *
5
+ * @package YoastACFAnalysis
6
+ */
7
 
8
+ /**
9
+ * Checks for the required Yoast SEO version.
10
+ */
11
  final class Yoast_ACF_Analysis_Dependency_Yoast_SEO implements Yoast_ACF_Analysis_Dependency {
12
 
13
  const MINIMAL_REQUIRED_VERSION = 3.2;
inc/{class-yoast-acf-analysis-facade.php → facade.php} RENAMED
@@ -1,9 +1,13 @@
1
  <?php
 
 
 
 
 
2
 
3
  /**
4
  * Class Yoast_ACF_Analysis_Facade
5
  */
6
-
7
  class Yoast_ACF_Analysis_Facade {
8
 
9
  /**
@@ -23,7 +27,7 @@ class Yoast_ACF_Analysis_Facade {
23
  public static function get_registry() {
24
  static $registry = null;
25
 
26
- if( null === $registry ) {
27
  $registry = new Yoast_ACF_Analysis_Registry();
28
  }
29
 
@@ -38,7 +42,7 @@ class Yoast_ACF_Analysis_Facade {
38
  * @return string Full filter name to use.
39
  */
40
  public static function get_filter_name( $filter_name ) {
41
- // Example: yoast-acf-analysis/refresh_rate
42
  return sprintf( '%1$s/%2$s', self::get_plugin_name(), ltrim( $filter_name, '/' ) );
43
  }
44
  }
1
  <?php
2
+ /**
3
+ * ACF Content Analysis for Yoast SEO plugin file.
4
+ *
5
+ * @package YoastACFAnalysis
6
+ */
7
 
8
  /**
9
  * Class Yoast_ACF_Analysis_Facade
10
  */
 
11
  class Yoast_ACF_Analysis_Facade {
12
 
13
  /**
27
  public static function get_registry() {
28
  static $registry = null;
29
 
30
+ if ( null === $registry ) {
31
  $registry = new Yoast_ACF_Analysis_Registry();
32
  }
33
 
42
  * @return string Full filter name to use.
43
  */
44
  public static function get_filter_name( $filter_name ) {
45
+ // Example: yoast-acf-analysis/refresh_rate.
46
  return sprintf( '%1$s/%2$s', self::get_plugin_name(), ltrim( $filter_name, '/' ) );
47
  }
48
  }
inc/{class-yoast-acf-analysis-registry.php → registry.php} RENAMED
@@ -1,4 +1,9 @@
1
  <?php
 
 
 
 
 
2
 
3
  /**
4
  * Class Yoast_ACF_Analysis_Registry
@@ -13,6 +18,8 @@ class Yoast_ACF_Analysis_Registry {
13
  private $storage = array();
14
 
15
  /**
 
 
16
  * @param string|int $id Registry index.
17
  * @param mixed $item Item to store in the registry.
18
  */
@@ -21,6 +28,8 @@ class Yoast_ACF_Analysis_Registry {
21
  }
22
 
23
  /**
 
 
24
  * @param string|int $id Registry index.
25
  *
26
  * @return object|null Object if a class is registered for the ID, otherwise null.
1
  <?php
2
+ /**
3
+ * ACF Content Analysis for Yoast SEO plugin file.
4
+ *
5
+ * @package YoastACFAnalysis
6
+ */
7
 
8
  /**
9
  * Class Yoast_ACF_Analysis_Registry
18
  private $storage = array();
19
 
20
  /**
21
+ * Adds an item to the registry.
22
+ *
23
  * @param string|int $id Registry index.
24
  * @param mixed $item Item to store in the registry.
25
  */
28
  }
29
 
30
  /**
31
+ * Retrieves an item from the registry.
32
+ *
33
  * @param string|int $id Registry index.
34
  *
35
  * @return object|null Object if a class is registered for the ID, otherwise null.
inc/{class-yoast-acf-analysis-requirements.php → requirements.php} RENAMED
@@ -1,12 +1,20 @@
1
  <?php
2
-
 
 
 
 
3
 
4
  /**
5
  * Class Yoast_ACF_Analysis_Requirements
6
  */
7
  class Yoast_ACF_Analysis_Requirements {
8
 
9
- /** @var Yoast_ACF_Analysis_Dependency[] List of registered dependencies. */
 
 
 
 
10
  protected $dependencies = array();
11
 
12
  /**
1
  <?php
2
+ /**
3
+ * ACF Content Analysis for Yoast SEO plugin file.
4
+ *
5
+ * @package YoastACFAnalysis
6
+ */
7
 
8
  /**
9
  * Class Yoast_ACF_Analysis_Requirements
10
  */
11
  class Yoast_ACF_Analysis_Requirements {
12
 
13
+ /**
14
+ * List of registered dependencies.
15
+ *
16
+ * @var Yoast_ACF_Analysis_Dependency[]
17
+ */
18
  protected $dependencies = array();
19
 
20
  /**
js/src/app.js CHANGED
@@ -1,4 +1,4 @@
1
- /* global YoastSEO */
2
  var config = require( "./config/config.js" );
3
  var helper = require( "./helper.js" );
4
  var collect = require( "./collect/collect.js" );
@@ -6,81 +6,82 @@ var replaceVars = require( "./replacevars.js" );
6
 
7
  var analysisTimeout = 0;
8
 
9
- var App = function(){
 
10
 
11
- YoastSEO.app.registerPlugin(config.pluginName, {status: 'ready'});
12
-
13
- YoastSEO.app.registerModification('content', collect.append.bind(collect), config.pluginName);
14
-
15
- this.bindListeners();
16
 
 
17
  };
18
 
19
- App.prototype.bindListeners = function(){
20
-
21
- var _self = this;
22
-
23
- if(helper.acf_version >= 5){
24
-
25
- jQuery(function(){
26
-
27
- replaceVars.updateReplaceVars(collect);
28
-
29
- acf.add_action('change remove append sortstop', _self.maybeRefresh);
30
- acf.add_action('change remove append sortstop', replaceVars.updateReplaceVars.bind(_self, collect));
31
-
32
- });
33
-
34
- }else{
35
-
36
- var fieldSelectors = config.fieldSelectors.slice(0);
37
- var wysiwygSelector = 'textarea[id^=wysiwyg-acf]';
38
-
39
- // Ignore Wysiwyg fields because they trigger a refresh in Yoast SEO itself
40
- fieldSelectorsWithoutWysiwyg = _.without(fieldSelectors, wysiwygSelector);
41
-
42
- jQuery(document).on('acf/setup_fields', function(){
43
-
44
- replaceVars.updateReplaceVars(collect);
45
-
46
- var fieldsWithoutWysiwyg = jQuery('#post-body, #edittag').find(fieldSelectorsWithoutWysiwyg.join(','));
47
- var fields = jQuery('#post-body, #edittag').find(fieldSelectors.join(','));
48
-
49
- fieldsWithoutWysiwyg.on('change', _self.maybeRefresh.bind(_self) );
50
- // Do not ignore Wysiwyg fields for the purpose of Replace Vars.
51
- fields.on('change', replaceVars.updateReplaceVars.bind(_self, collect));
52
-
53
- if (YoastSEO.wp._tinyMCEHelper) {
54
-
55
- jQuery(wysiwygSelector).each( function () {
56
- YoastSEO.wp._tinyMCEHelper.addEventHandler(this.id, [ 'input', 'change', 'cut', 'paste' ],
57
- replaceVars.updateReplaceVars.bind(_self, collect));
58
- });
59
-
60
- }
61
 
62
- //Also refresh on media close as attachment data might have changed
63
- wp.media.frame.on('close', _self.maybeRefresh.bind(_self) );
64
- });
 
 
 
 
65
 
66
- }
 
67
  };
68
 
69
- App.prototype.maybeRefresh = function(){
 
 
 
 
 
70
 
71
- if ( analysisTimeout ) {
72
- window.clearTimeout(analysisTimeout);
73
- }
74
 
75
- analysisTimeout = window.setTimeout( function() {
 
 
76
 
77
- if(config.debug){
78
- console.log('Recalculate...' + new Date() + '(Internal)');
79
- }
 
80
 
81
- YoastSEO.app.pluginReloaded(config.pluginName);
82
- }, config.refreshRate );
 
 
83
 
 
 
84
  };
85
 
86
  module.exports = App;
1
+ /* global YoastSEO, acf, _, jQuery, wp */
2
  var config = require( "./config/config.js" );
3
  var helper = require( "./helper.js" );
4
  var collect = require( "./collect/collect.js" );
6
 
7
  var analysisTimeout = 0;
8
 
9
+ var App = function() {
10
+ YoastSEO.app.registerPlugin( config.pluginName, { status: "ready" } );
11
 
12
+ YoastSEO.app.registerModification( "content", collect.append.bind( collect ), config.pluginName );
 
 
 
 
13
 
14
+ this.bindListeners();
15
  };
16
 
17
+ /**
18
+ * ACF 4 Listener.
19
+ *
20
+ * @param {Array} fieldSelectors List of field selectors.
21
+ * @param {string} wysiwygSelector Element selector for WYSIWYG fields.
22
+ * @param {Array} fieldSelectorsWithoutWysiwyg List of fields.
23
+ *
24
+ * @returns {void}
25
+ */
26
+ App.prototype.acf4Listener = function( fieldSelectors, wysiwygSelector, fieldSelectorsWithoutWysiwyg ) {
27
+ replaceVars.updateReplaceVars( collect );
28
+
29
+ var fieldsWithoutWysiwyg = jQuery( "#post-body, #edittag" ).find( fieldSelectorsWithoutWysiwyg.join( "," ) );
30
+ var fields = jQuery( "#post-body, #edittag" ).find( fieldSelectors.join( "," ) );
31
+
32
+ fieldsWithoutWysiwyg.on( "change", this.maybeRefresh.bind( this ) );
33
+ // Do not ignore Wysiwyg fields for the purpose of Replace Vars.
34
+ fields.on( "change", replaceVars.updateReplaceVars.bind( this, collect ) );
35
+
36
+ if ( YoastSEO.wp._tinyMCEHelper ) {
37
+ jQuery( wysiwygSelector ).each( function() {
38
+ YoastSEO.wp._tinyMCEHelper.addEventHandler( this.id, [ "input", "change", "cut", "paste" ],
39
+ replaceVars.updateReplaceVars.bind( this, collect ) );
40
+ } );
41
+ }
42
+
43
+ // Also refresh on media close as attachment data might have changed
44
+ wp.media.frame.on( "close", this.maybeRefresh );
45
+ };
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
+ /**
48
+ * ACF 5 Listener.
49
+ *
50
+ * @returns {void}
51
+ */
52
+ App.prototype.acf5Listener = function() {
53
+ replaceVars.updateReplaceVars( collect );
54
 
55
+ acf.add_action( "change remove append sortstop", this.maybeRefresh );
56
+ acf.add_action( "change remove append sortstop", replaceVars.updateReplaceVars.bind( this, collect ) );
57
  };
58
 
59
+ App.prototype.bindListeners = function() {
60
+ if ( helper.acf_version >= 5 ) {
61
+ jQuery( this.acf5Listener.bind( this ) );
62
+ } else {
63
+ var fieldSelectors = config.fieldSelectors.slice( 0 );
64
+ var wysiwygSelector = "textarea[id^=wysiwyg-acf]";
65
 
66
+ // Ignore Wysiwyg fields because they trigger a refresh in Yoast SEO itself
67
+ var fieldSelectorsWithoutWysiwyg = _.without( fieldSelectors, wysiwygSelector );
 
68
 
69
+ jQuery( document ).on( "acf/setup_fields", this.acf4Listener.bind( this, fieldSelectors, wysiwygSelector, fieldSelectorsWithoutWysiwyg ) );
70
+ }
71
+ };
72
 
73
+ App.prototype.maybeRefresh = function() {
74
+ if ( analysisTimeout ) {
75
+ window.clearTimeout( analysisTimeout );
76
+ }
77
 
78
+ analysisTimeout = window.setTimeout( function() {
79
+ if ( config.debug ) {
80
+ console.log( "Recalculate..." + new Date() + "(Internal)" );
81
+ }
82
 
83
+ YoastSEO.app.pluginReloaded( config.pluginName );
84
+ }, config.refreshRate );
85
  };
86
 
87
  module.exports = App;
js/src/cache/cache.attachments.js CHANGED
@@ -1,49 +1,46 @@
1
  /* global _ */
2
  var cache = require( "./cache.js" );
3
 
4
- var refresh = function(attachment_ids){
5
-
6
- var uncached = cache.getUncached(attachment_ids, 'attachment');
7
-
8
- if (uncached.length === 0){
9
- return;
10
- }
11
-
12
- window.wp.ajax.post('query-attachments', {
13
- 'query': {
14
- 'post__in': uncached
15
- }
16
- }).done(function (attachments) {
17
-
18
- _.each(attachments, function (attachment) {
19
- cache.set(attachment.id, attachment, 'attachment');
20
- YoastACFAnalysis.maybeRefresh();
21
- });
22
-
23
- });
24
-
25
  };
26
 
27
- var get = function( id ){
 
28
 
29
- var attachment = cache.get(id, 'attachment');
 
 
30
 
31
- if(!attachment) return false;
32
 
33
- var changedAttachment = wp.media.attachment( id );
 
 
34
 
35
- if( changedAttachment.has('alt') ){
36
- attachment.alt = changedAttachment.get('alt');
37
- }
38
 
39
- if( changedAttachment.has('title') ){
40
- attachment.title = changedAttachment.get('title');
41
- }
42
-
43
- return attachment;
44
  };
45
 
46
  module.exports = {
47
- refresh: refresh,
48
- get: get
49
- };
1
  /* global _ */
2
  var cache = require( "./cache.js" );
3
 
4
+ var refresh = function( attachment_ids ) {
5
+ var uncached = cache.getUncached( attachment_ids, "attachment" );
6
+
7
+ if ( uncached.length === 0 ) {
8
+ return;
9
+ }
10
+
11
+ window.wp.ajax.post( "query-attachments", {
12
+ query: {
13
+ post__in: uncached,
14
+ },
15
+ } ).done( function( attachments ) {
16
+ _.each( attachments, function( attachment ) {
17
+ cache.set( attachment.id, attachment, "attachment" );
18
+ window.YoastACFAnalysis.maybeRefresh();
19
+ } );
20
+ } );
 
 
 
 
21
  };
22
 
23
+ var get = function( id ) {
24
+ var attachment = cache.get( id, "attachment" );
25
 
26
+ if ( ! attachment ) {
27
+ return false;
28
+ }
29
 
30
+ var changedAttachment = window.wp.media.attachment( id );
31
 
32
+ if ( changedAttachment.has( "alt" ) ) {
33
+ attachment.alt = changedAttachment.get( "alt" );
34
+ }
35
 
36
+ if ( changedAttachment.has( "title" ) ) {
37
+ attachment.title = changedAttachment.get( "title" );
38
+ }
39
 
40
+ return attachment;
 
 
 
 
41
  };
42
 
43
  module.exports = {
44
+ refresh: refresh,
45
+ get: get,
46
+ };
js/src/cache/cache.js CHANGED
@@ -1,58 +1,52 @@
1
  /* global _ */
2
  var Cache = function() {
3
- this.clear('all');
4
  };
5
 
6
  var _cache;
7
 
8
  Cache.prototype.set = function( id, value, store ) {
 
9
 
10
- store = typeof store !== 'undefined' ? store : 'default';
 
 
11
 
12
- if( !(store in _cache) ){
13
- _cache[store] = {};
14
- }
15
-
16
- _cache[ store ][ id ] = value;
17
  };
18
 
19
- Cache.prototype.get = function( id, store ){
20
-
21
- store = typeof store !== 'undefined' ? store : 'default';
22
 
23
- if ( store in _cache && id in _cache[ store ] ) {
24
- return _cache[ store ][ id ];
25
- }else{
26
- return false;
27
- }
28
 
 
29
  };
30
 
31
- Cache.prototype.getUncached = function(ids, store){
32
-
33
- store = typeof store !== 'undefined' ? store : 'default';
34
 
35
- var that = this;
36
 
37
- ids = _.uniq(ids);
38
 
39
- return ids.filter(function(id){
40
- var value = that.get(id, store);
41
- return value === false;
42
- });
43
 
 
 
44
  };
45
 
46
- Cache.prototype.clear = function(store){
47
-
48
- store = typeof store !== 'undefined' ? store : 'default';
49
-
50
- if(store === 'all'){
51
- _cache = {};
52
- }else{
53
- _cache[store] = {};
54
- }
55
 
 
 
 
 
 
56
  };
57
 
58
- module.exports = new Cache();
1
  /* global _ */
2
  var Cache = function() {
3
+ this.clear( "all" );
4
  };
5
 
6
  var _cache;
7
 
8
  Cache.prototype.set = function( id, value, store ) {
9
+ store = typeof store === "undefined" ? "default" : store;
10
 
11
+ if ( ! ( store in _cache ) ) {
12
+ _cache[ store ] = {};
13
+ }
14
 
15
+ _cache[ store ][ id ] = value;
 
 
 
 
16
  };
17
 
18
+ Cache.prototype.get = function( id, store ) {
19
+ store = typeof store === "undefined" ? "default" : store;
 
20
 
21
+ if ( store in _cache && id in _cache[ store ] ) {
22
+ return _cache[ store ][ id ];
23
+ }
 
 
24
 
25
+ return false;
26
  };
27
 
28
+ Cache.prototype.getUncached = function( ids, store ) {
29
+ store = typeof store === "undefined" ? "default" : store;
 
30
 
31
+ var that = this;
32
 
33
+ ids = _.uniq( ids );
34
 
35
+ return ids.filter( function( id ) {
36
+ var value = that.get( id, store );
 
 
37
 
38
+ return value === false;
39
+ } );
40
  };
41
 
42
+ Cache.prototype.clear = function( store ) {
43
+ store = typeof store === "undefined" ? "default" : store;
 
 
 
 
 
 
 
44
 
45
+ if ( store === "all" ) {
46
+ _cache = {};
47
+ } else {
48
+ _cache[ store ] = {};
49
+ }
50
  };
51
 
52
+ module.exports = new Cache();
js/src/collect/collect-v4.js CHANGED
@@ -1,22 +1,22 @@
 
 
1
  var config = require( "./../config/config.js" );
2
  var fieldSelectors = config.fieldSelectors;
3
 
4
  var field_data = [];
5
 
6
- var fields = jQuery('#post-body, #edittag').find(fieldSelectors.join(','));
7
-
8
- fields.each(function() {
9
-
10
- var $el = jQuery(this).parents('.field').last();
11
 
12
- field_data.push({
13
- $el : $el,
14
- key : $el.data('field_key'),
15
- name : $el.data('field_name'),
16
- type : $el.data('field_type'),
17
- post_meta_key : $el.data('field_name')
18
- });
19
 
20
- });
 
 
 
 
 
 
 
21
 
22
- module.exports = field_data;
1
+ /* global jQuery */
2
+
3
  var config = require( "./../config/config.js" );
4
  var fieldSelectors = config.fieldSelectors;
5
 
6
  var field_data = [];
7
 
8
+ var fields = jQuery( "#post-body, #edittag" ).find( fieldSelectors.join( "," ) );
 
 
 
 
9
 
10
+ fields.each( function() {
11
+ var $el = jQuery( this ).parents( ".field" ).last();
 
 
 
 
 
12
 
13
+ field_data.push( {
14
+ $el: $el,
15
+ key: $el.data( "field_key" ),
16
+ name: $el.data( "field_name" ),
17
+ type: $el.data( "field_type" ),
18
+ post_meta_key: $el.data( "field_name" ),
19
+ } );
20
+ } );
21
 
22
+ module.exports = field_data;
js/src/collect/collect-v5.js CHANGED
@@ -1,67 +1,55 @@
1
- module.exports = function(){
2
-
3
- var outerFieldsName = [
4
- 'flexible_content',
5
- 'repeater',
6
- 'group'
7
- ];
8
-
9
- var innerFields = [];
10
- var outerFields = [];
11
-
12
- var fields = _.map(acf.get_fields(), function(field){
13
-
14
- var field_data = jQuery.extend( true, {}, acf.get_data(jQuery(field)) );
15
- field_data.$el = jQuery(field);
16
- field_data.post_meta_key = field_data.name;
17
-
18
- // Collect nested and parent
19
- if( outerFieldsName.indexOf(field_data.type) === -1 ) {
20
- innerFields.push(field_data);
21
- }else{
22
- outerFields.push(field_data);
23
- }
24
-
25
- return field_data;
26
-
27
- });
28
-
29
- if( outerFields.length === 0){
30
- return fields;
31
- }
32
-
33
- // Transform field names for nested fields.
34
- _.each(innerFields, function(inner){
35
-
36
- _.each(outerFields, function(outer){
37
-
38
- if (jQuery.contains(outer.$el[0], inner.$el[0])) {
39
-
40
- // Types that hold multiple children.
41
- if (outer.type === 'flexible_content' || outer.type === 'repeater'){
42
-
43
- outer.children = outer.children || [];
44
- outer.children.push(inner);
45
- inner.parent = outer;
46
- inner.post_meta_key = outer.name + '_' + (outer.children.length - 1) + '_' + inner.name;
47
-
48
- }
49
-
50
- // Types that hold single children.
51
- if (outer.type === 'group') {
52
-
53
- outer.children = [inner];
54
- inner.parent = outer;
55
- inner.post_meta_key = outer.name + '_' + inner.name;
56
-
57
- }
58
-
59
- }
60
-
61
- });
62
-
63
- });
64
-
65
- return fields;
66
-
67
  };
1
+ /* global _, acf, jQuery */
2
+
3
+ module.exports = function() {
4
+ var outerFieldsName = [
5
+ "flexible_content",
6
+ "repeater",
7
+ "group",
8
+ ];
9
+
10
+ var innerFields = [];
11
+ var outerFields = [];
12
+
13
+ var fields = _.map( acf.get_fields(), function( field ) {
14
+ var field_data = jQuery.extend( true, {}, acf.get_data( jQuery( field ) ) );
15
+ field_data.$el = jQuery( field );
16
+ field_data.post_meta_key = field_data.name;
17
+
18
+ // Collect nested and parent
19
+ if ( outerFieldsName.indexOf( field_data.type ) === -1 ) {
20
+ innerFields.push( field_data );
21
+ } else {
22
+ outerFields.push( field_data );
23
+ }
24
+
25
+ return field_data;
26
+ } );
27
+
28
+ if ( outerFields.length === 0 ) {
29
+ return fields;
30
+ }
31
+
32
+ // Transform field names for nested fields.
33
+ _.each( innerFields, function( inner ) {
34
+ _.each( outerFields, function( outer ) {
35
+ if ( jQuery.contains( outer.$el[ 0 ], inner.$el[ 0 ] ) ) {
36
+ // Types that hold multiple children.
37
+ if ( outer.type === "flexible_content" || outer.type === "repeater" ) {
38
+ outer.children = outer.children || [];
39
+ outer.children.push( inner );
40
+ inner.parent = outer;
41
+ inner.post_meta_key = outer.name + "_" + ( outer.children.length - 1 ) + "_" + inner.name;
42
+ }
43
+
44
+ // Types that hold single children.
45
+ if ( outer.type === "group" ) {
46
+ outer.children = [ inner ];
47
+ inner.parent = outer;
48
+ inner.post_meta_key = outer.name + "_" + inner.name;
49
+ }
50
+ }
51
+ } );
52
+ } );
53
+
54
+ return fields;
 
 
 
 
 
 
 
 
 
 
 
 
55
  };
js/src/collect/collect.js CHANGED
@@ -1,86 +1,77 @@
1
- /* global acf, _ */
2
 
3
  var config = require( "./../config/config.js" );
4
  var helper = require( "./../helper.js" );
5
  var scraper_store = require( "./../scraper-store.js" );
6
 
7
- var Collect = function(){
8
 
9
  };
10
 
11
- Collect.prototype.getFieldData = function () {
12
- var field_data = this.filterBroken(this.filterBlacklistName(this.filterBlacklistType(this.getData())));
13
 
14
- var used_types = _.uniq(_.pluck(field_data, 'type'));
15
 
16
- if(config.debug) {
 
 
 
17
 
18
- console.log('Used types:');
19
- console.log(used_types);
 
20
 
21
- }
22
-
23
- _.each(used_types, function(type){
24
- field_data = scraper_store.getScraper(type).scrape(field_data);
25
- });
26
-
27
- return field_data;
28
  };
29
 
30
- Collect.prototype.append = function(data){
31
-
32
- if(config.debug){
33
- console.log('Recalculate...' + new Date());
34
- }
35
-
36
- var field_data = this.getFieldData();
37
 
38
- _.each(field_data, function(field){
39
 
40
- if(typeof field.content !== 'undefined' && field.content !== ''){
41
- data += '\n' + field.content;
42
- }
 
 
43
 
44
- });
 
 
45
 
46
- if(config.debug){
47
- console.log('Field data:');
48
- console.table(field_data);
49
-
50
- console.log('Data:');
51
- console.log(data);
52
- }
53
-
54
- return data;
55
 
 
56
  };
57
 
58
- Collect.prototype.getData = function(){
59
-
60
- if(helper.acf_version >= 5){
61
- return require( "./collect-v5.js" )();
62
- }else{
63
- return require( "./collect-v4.js" );
64
- }
65
-
66
  };
67
 
68
- Collect.prototype.filterBlacklistType = function(field_data){
69
- return _.filter(field_data, function(field){
70
- return !_.contains(config.blacklistType, field.type);
71
- });
72
  };
73
 
74
- Collect.prototype.filterBlacklistName = function(field_data){
75
- return _.filter(field_data, function(field){
76
- return !_.contains(config.blacklistName, field.name);
77
- });
78
  };
79
 
80
- Collect.prototype.filterBroken = function(field_data){
81
- return _.filter(field_data, function(field){
82
- return ('key' in field);
83
- });
84
  };
85
 
86
  module.exports = new Collect();
1
+ /* global _ */
2
 
3
  var config = require( "./../config/config.js" );
4
  var helper = require( "./../helper.js" );
5
  var scraper_store = require( "./../scraper-store.js" );
6
 
7
+ var Collect = function() {
8
 
9
  };
10
 
11
+ Collect.prototype.getFieldData = function() {
12
+ var field_data = this.filterBroken( this.filterBlacklistName( this.filterBlacklistType( this.getData() ) ) );
13
 
14
+ var used_types = _.uniq( _.pluck( field_data, "type" ) );
15
 
16
+ if ( config.debug ) {
17
+ console.log( "Used types:" );
18
+ console.log( used_types );
19
+ }
20
 
21
+ _.each( used_types, function( type ) {
22
+ field_data = scraper_store.getScraper( type ).scrape( field_data );
23
+ } );
24
 
25
+ return field_data;
 
 
 
 
 
 
26
  };
27
 
28
+ Collect.prototype.append = function( data ) {
29
+ if ( config.debug ) {
30
+ console.log( "Recalculate..." + new Date() );
31
+ }
 
 
 
32
 
33
+ var field_data = this.getFieldData();
34
 
35
+ _.each( field_data, function( field ) {
36
+ if ( typeof field.content !== "undefined" && field.content !== "" ) {
37
+ data += "\n" + field.content;
38
+ }
39
+ } );
40
 
41
+ if ( config.debug ) {
42
+ console.log( "Field data:" );
43
+ console.table( field_data );
44
 
45
+ console.log( "Data:" );
46
+ console.log( data );
47
+ }
 
 
 
 
 
 
48
 
49
+ return data;
50
  };
51
 
52
+ Collect.prototype.getData = function() {
53
+ if ( helper.acf_version >= 5 ) {
54
+ return require( "./collect-v5.js" )();
55
+ }
56
+ return require( "./collect-v4.js" );
 
 
 
57
  };
58
 
59
+ Collect.prototype.filterBlacklistType = function( field_data ) {
60
+ return _.filter( field_data, function( field ) {
61
+ return ! _.contains( config.blacklistType, field.type );
62
+ } );
63
  };
64
 
65
+ Collect.prototype.filterBlacklistName = function( field_data ) {
66
+ return _.filter( field_data, function( field ) {
67
+ return ! _.contains( config.blacklistName, field.name );
68
+ } );
69
  };
70
 
71
+ Collect.prototype.filterBroken = function( field_data ) {
72
+ return _.filter( field_data, function( field ) {
73
+ return ( "key" in field );
74
+ } );
75
  };
76
 
77
  module.exports = new Collect();
js/src/config/config.js CHANGED
@@ -1 +1,2 @@
1
- module.exports = YoastACFAnalysisConfig;
 
1
+ /* globals YoastACFAnalysisConfig */
2
+ module.exports = YoastACFAnalysisConfig;
js/src/helper.js CHANGED
@@ -1,5 +1,5 @@
1
  var config = require( "./config/config.js" );
2
 
3
  module.exports = {
4
- acf_version: parseFloat(config.acfVersion, 10)
5
- };
1
  var config = require( "./config/config.js" );
2
 
3
  module.exports = {
4
+ acf_version: parseFloat( config.acfVersion, 10 ),
5
+ };
js/src/main.js CHANGED
@@ -1,17 +1,12 @@
1
- /* global jQuery, YoastACFAnalysis: true */
 
2
 
3
  var App = require( "./app.js" );
4
 
5
- (function($) {
6
-
7
- $(document).ready(function() {
8
-
9
- if( "undefined" !== typeof YoastSEO){
10
-
11
- YoastACFAnalysis = new App();
12
-
13
- }
14
-
15
- });
16
-
17
- }(jQuery));
1
+ /* global jQuery, YoastSEO, YoastACFAnalysis: true */
2
+ /* exported YoastACFAnalysis */
3
 
4
  var App = require( "./app.js" );
5
 
6
+ ( function( $ ) {
7
+ $( document ).ready( function() {
8
+ if ( "undefined" !== typeof YoastSEO ) {
9
+ YoastACFAnalysis = new App();
10
+ }
11
+ } );
12
+ }( jQuery ) );
 
 
 
 
 
 
js/src/replacevars.js CHANGED
@@ -4,53 +4,52 @@ var config = require( "./config/config.js" );
4
 
5
  var ReplaceVar = YoastReplaceVarPlugin.ReplaceVar;
6
 
7
- var supportedTypes = ['email', 'text', 'textarea', 'url', 'wysiwyg'];
8
 
9
  var replaceVars = {};
10
 
11
- var replaceVarPluginAvailable = function(){
12
- if (ReplaceVar === undefined) {
13
- if (config.debug) {
14
- console.log('Replacing ACF variables in the Snippet Window requires Yoast SEO >= 5.3.');
15
- }
16
- return false;
17
- }
18
- return true;
19
- };
20
-
21
- var updateReplaceVars = function (collect) {
22
- if (!replaceVarPluginAvailable()) {
23
- return;
24
- }
25
-
26
- var fieldData = _.filter(collect.getFieldData(), function (field) { return _.contains(supportedTypes, field.type) });
27
-
28
- _.each(fieldData, function(field) {
29
- // Remove HTML tags using jQuery in case of a wysiwyg field.
30
- var content = (field.type === 'wysiwyg') ? jQuery(jQuery.parseHTML(field.content)).text() : field.content;
31
-
32
- if(replaceVars[field.post_meta_key]===undefined){
33
 
34
- replaceVars[field.post_meta_key] = new ReplaceVar( '%%cf_'+field.post_meta_key+'%%', content, { source: 'direct' } );
35
- YoastSEO.wp.replaceVarsPlugin.addReplacement( replaceVars[field.post_meta_key] );
36
 
37
- if (config.debug) {
38
- console.log("Created ReplaceVar for: ", field.post_meta_key, " with: ", content, replaceVars[field.post_meta_key]);
39
- }
40
-
41
- }else{
42
-
43
- replaceVars[field.post_meta_key].replacement = content;
44
-
45
- if (config.debug) {
46
- console.log("Updated ReplaceVar for: ", field.post_meta_key, " with: ", content, replaceVars[field.post_meta_key]);
47
- }
48
-
49
- }
50
 
51
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  };
53
 
54
  module.exports = {
55
- updateReplaceVars: updateReplaceVars
56
  };
4
 
5
  var ReplaceVar = YoastReplaceVarPlugin.ReplaceVar;
6
 
7
+ var supportedTypes = [ "email", "text", "textarea", "url", "wysiwyg" ];
8
 
9
  var replaceVars = {};
10
 
11
+ var replaceVarPluginAvailable = function() {
12
+ if ( typeof ReplaceVar === "undefined" ) {
13
+ if ( config.debug ) {
14
+ console.log( "Replacing ACF variables in the Snippet Window requires Yoast SEO >= 5.3." );
15
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
+ return false;
18
+ }
19
 
20
+ return true;
21
+ };
 
 
 
 
 
 
 
 
 
 
 
22
 
23
+ var updateReplaceVars = function( collect ) {
24
+ if ( ! replaceVarPluginAvailable() ) {
25
+ return;
26
+ }
27
+
28
+ var fieldData = _.filter( collect.getFieldData(), function( field ) {
29
+ return _.contains( supportedTypes, field.type );
30
+ } );
31
+
32
+ _.each( fieldData, function( field ) {
33
+ // Remove HTML tags using jQuery in case of a wysiwyg field.
34
+ var content = ( field.type === "wysiwyg" ) ? jQuery( jQuery.parseHTML( field.content ) ).text() : field.content;
35
+
36
+ if ( typeof replaceVars[ field.post_meta_key ] === "undefined" ) {
37
+ replaceVars[ field.post_meta_key ] = new ReplaceVar( "%%cf_" + field.post_meta_key + "%%", content, { source: "direct" } );
38
+ YoastSEO.wp.replaceVarsPlugin.addReplacement( replaceVars[ field.post_meta_key ] );
39
+
40
+ if ( config.debug ) {
41
+ console.log( "Created ReplaceVar for: ", field.post_meta_key, " with: ", content, replaceVars[ field.post_meta_key ] );
42
+ }
43
+ } else {
44
+ replaceVars[ field.post_meta_key ].replacement = content;
45
+
46
+ if ( config.debug ) {
47
+ console.log( "Updated ReplaceVar for: ", field.post_meta_key, " with: ", content, replaceVars[ field.post_meta_key ] );
48
+ }
49
+ }
50
+ } );
51
  };
52
 
53
  module.exports = {
54
+ updateReplaceVars: updateReplaceVars,
55
  };
js/src/scraper-store.js CHANGED
@@ -1,91 +1,94 @@
1
- /* global _ */
2
  var config = require( "./config/config.js" );
3
 
4
  var scraperObjects = {
 
 
 
 
 
 
5
 
6
- //Basic
7
- 'text': require( "./scraper/scraper.text.js" ),
8
- 'textarea': require( "./scraper/scraper.textarea.js" ),
9
- 'email': require( "./scraper/scraper.email.js" ),
10
- 'url': require( "./scraper/scraper.url.js" ),
11
 
12
- //Content
13
- 'wysiwyg': require( "./scraper/scraper.wysiwyg.js" ),
14
- //TODO: Add oembed handler
15
- 'image': require( "./scraper/scraper.image.js" ),
16
- 'gallery': require( "./scraper/scraper.gallery.js" ),
17
 
18
- //Choice
19
- //TODO: select, checkbox, radio
20
 
21
- //Relational
22
- 'taxonomy': require( "./scraper/scraper.taxonomy.js" )
23
-
24
- //jQuery
25
- //TODO: google_map, date_picker, color_picker
26
 
27
  };
28
 
29
  var scrapers = {};
30
 
31
  /**
32
- * Set a scraper object on the store. Existing scrapers will be overwritten.
33
  *
34
- * @param {Object} scraper
35
- * @param {string} type
 
36
  */
37
- var setScraper = function(scraper, type){
 
 
 
 
38
 
39
- if(config.debug && hasScraper(type)){
40
- console.warn('Scraper for "' + type + '" already exists and will be overwritten.' );
41
- }
 
 
 
 
 
 
 
 
 
 
 
42
 
43
- scrapers[type] = scraper;
44
 
45
- return scraper;
46
  };
47
 
48
  /**
49
  * Returns the scraper object for a field type.
50
  * If there is no scraper object for this field type a no-op scraper is returned.
51
  *
52
- * @param {string} type
53
- * @returns {Object}
54
- */
55
- var getScraper = function(type){
56
-
57
- if(hasScraper(type)){
58
- return scrapers[type];
59
- }else if(type in scraperObjects){
60
- return setScraper(new scraperObjects[type](), type);
61
- }else{
62
- //If we do not have a scraper just pass the fields through so it will be filtered out by the app.
63
- return {
64
- scrape: function(fields){
65
- if(config.debug){
66
- console.warn('No Scraper for field type: ' + type );
67
- }
68
- return fields;
69
- }
70
- };
71
- }
72
- }
73
-
74
- /**
75
- * Checks if there already is a scraper for a field type in the store.
76
  *
77
- * @param {string} type
78
- * @returns {boolean}
79
  */
80
- var hasScraper = function(type){
81
-
82
- return (type in scrapers);
83
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  };
85
 
86
  module.exports = {
87
-
88
- setScraper: setScraper,
89
- getScraper: getScraper
90
-
91
- };
 
1
  var config = require( "./config/config.js" );
2
 
3
  var scraperObjects = {
4
+ // Basic
5
+ text: require( "./scraper/scraper.text.js" ),
6
+ textarea: require( "./scraper/scraper.textarea.js" ),
7
+ email: require( "./scraper/scraper.email.js" ),
8
+ url: require( "./scraper/scraper.url.js" ),
9
+ link: require( "./scraper/scraper.link.js" ),
10
 
11
+ // Content
12
+ wysiwyg: require( "./scraper/scraper.wysiwyg.js" ),
13
+ // TODO: Add oembed handler
14
+ image: require( "./scraper/scraper.image.js" ),
15
+ gallery: require( "./scraper/scraper.gallery.js" ),
16
 
17
+ // Choice
18
+ // TODO: select, checkbox, radio
 
 
 
19
 
20
+ // Relational
21
+ taxonomy: require( "./scraper/scraper.taxonomy.js" ),
22
 
23
+ // jQuery
24
+ // TODO: google_map, date_picker, color_picker
 
 
 
25
 
26
  };
27
 
28
  var scrapers = {};
29
 
30
  /**
31
+ * Checks if there already is a scraper for a field type in the store.
32
  *
33
+ * @param {string} type Type of scraper to find.
34
+ *
35
+ * @returns {boolean} True if the scraper is already defined.
36
  */
37
+ var hasScraper = function( type ) {
38
+ return (
39
+ type in scrapers
40
+ );
41
+ };
42
 
43
+ /**
44
+ * Set a scraper object on the store. Existing scrapers will be overwritten.
45
+ *
46
+ * @param {Object} scraper The scraper to add.
47
+ * @param {string} type Type of scraper.
48
+ *
49
+ * @chainable
50
+ *
51
+ * @returns {Object} Added scraper.
52
+ */
53
+ var setScraper = function( scraper, type ) {
54
+ if ( config.debug && hasScraper( type ) ) {
55
+ console.warn( "Scraper for " + type + " already exists and will be overwritten." );
56
+ }
57
 
58
+ scrapers[ type ] = scraper;
59
 
60
+ return scraper;
61
  };
62
 
63
  /**
64
  * Returns the scraper object for a field type.
65
  * If there is no scraper object for this field type a no-op scraper is returned.
66
  *
67
+ * @param {string} type Type of scraper to fetch.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  *
69
+ * @returns {Object} The scraper for the specified type.
 
70
  */
71
+ var getScraper = function( type ) {
72
+ if ( hasScraper( type ) ) {
73
+ return scrapers[ type ];
74
+ }
75
+
76
+ if ( type in scraperObjects ) {
77
+ return setScraper( new scraperObjects[ type ](), type );
78
+ }
79
+
80
+ // If we do not have a scraper just pass the fields through so it will be filtered out by the app.
81
+ return {
82
+ scrape: function( fields ) {
83
+ if ( config.debug ) {
84
+ console.warn( "No Scraper for field type: " + type );
85
+ }
86
+ return fields;
87
+ },
88
+ };
89
  };
90
 
91
  module.exports = {
92
+ setScraper: setScraper,
93
+ getScraper: getScraper,
94
+ };
 
 
js/src/scraper/scraper.email.js CHANGED
@@ -1,24 +1,19 @@
1
- var scrapers = require( "./../scraper-store.js" );
2
 
3
  var Scraper = function() {};
4
 
5
- Scraper.prototype.scrape = function(fields){
 
 
 
 
6
 
7
- var that = this;
8
 
9
- fields = _.map(fields, function(field){
10
-
11
- if(field.type !== 'email'){
12
- return field;
13
- }
14
-
15
- field.content = field.$el.find('input[type=email][id^=acf]').val();
16
-
17
- return field;
18
- });
19
-
20
- return fields;
21
 
 
22
  };
23
 
24
- module.exports = Scraper;
1
+ /* global _ */
2
 
3
  var Scraper = function() {};
4
 
5
+ Scraper.prototype.scrape = function( fields ) {
6
+ fields = _.map( fields, function( field ) {
7
+ if ( field.type !== "email" ) {
8
+ return field;
9
+ }
10
 
11
+ field.content = field.$el.find( "input[type=email][id^=acf]" ).val();
12
 
13
+ return field;
14
+ } );
 
 
 
 
 
 
 
 
 
 
15
 
16
+ return fields;
17
  };
18
 
19
+ module.exports = Scraper;
js/src/scraper/scraper.gallery.js CHANGED
@@ -1,48 +1,40 @@
 
 
1
  var attachmentCache = require( "./../cache/cache.attachments.js" );
2
- var scrapers = require( "./../scraper-store.js" );
3
 
4
  var Scraper = function() {};
5
 
6
- Scraper.prototype.scrape = function(fields){
7
-
8
- var that = this;
9
-
10
- var attachment_ids = [];
11
-
12
- fields = _.map(fields, function(field){
13
-
14
- if(field.type !== 'gallery'){
15
- return field;
16
- }
17
-
18
- field.content = '';
19
-
20
- field.$el.find('.acf-gallery-attachment input[type=hidden]').each( function (index, element){
21
-
22
- //TODO: Is this the best way to get the attachment id?
23
- var attachment_id = jQuery( this ).val();
24
-
25
- //Collect all attachment ids for cache refresh
26
- attachment_ids.push(attachment_id);
27
 
28
- //If we have the attachment data in the cache we can return a useful value
29
- if(attachmentCache.get(attachment_id, 'attachment')){
 
 
30
 
31
- var attachment = attachmentCache.get(attachment_id, 'attachment');
32
 
33
- field.content += '<img src="' + attachment.url + '" alt="' + attachment.alt + '" title="' + attachment.title + '">';
 
 
34
 
35
- }
 
36
 
37
- });
 
 
38
 
39
- return field;
40
- });
 
41
 
42
- attachmentCache.refresh(attachment_ids);
 
43
 
44
- return fields;
45
 
 
46
  };
47
 
48
- module.exports = Scraper;
1
+ /* global _, jQuery */
2
+
3
  var attachmentCache = require( "./../cache/cache.attachments.js" );
 
4
 
5
  var Scraper = function() {};
6
 
7
+ Scraper.prototype.scrape = function( fields ) {
8
+ var attachment_ids = [];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
+ fields = _.map( fields, function( field ) {
11
+ if ( field.type !== "gallery" ) {
12
+ return field;
13
+ }
14
 
15
+ field.content = "";
16
 
17
+ field.$el.find( ".acf-gallery-attachment input[type=hidden]" ).each( function() {
18
+ // TODO: Is this the best way to get the attachment id?
19
+ var attachment_id = jQuery( this ).val();
20
 
21
+ // Collect all attachment ids for cache refresh
22
+ attachment_ids.push( attachment_id );
23
 
24
+ // If we have the attachment data in the cache we can return a useful value
25
+ if ( attachmentCache.get( attachment_id, "attachment" ) ) {
26
+ var attachment = attachmentCache.get( attachment_id, "attachment" );
27
 
28
+ field.content += '<img src="' + attachment.url + '" alt="' + attachment.alt + '" title="' + attachment.title + '">';
29
+ }
30
+ } );
31
 
32
+ return field;
33
+ } );
34
 
35
+ attachmentCache.refresh( attachment_ids );
36
 
37
+ return fields;
38
  };
39
 
40
+ module.exports = Scraper;
js/src/scraper/scraper.image.js CHANGED
@@ -1,42 +1,36 @@
 
 
1
  var attachmentCache = require( "./../cache/cache.attachments.js" );
2
- var scrapers = require( "./../scraper-store.js" );
3
 
4
  var Scraper = function() {};
5
 
6
- Scraper.prototype.scrape = function(fields){
7
-
8
- var that = this;
9
-
10
- var attachment_ids = [];
11
-
12
- fields = _.map(fields, function(field){
13
-
14
- if(field.type !== 'image'){
15
- return field;
16
- }
17
-
18
- field.content = '';
19
-
20
- var attachment_id = field.$el.find('input[type=hidden]').val();
21
 
22
- attachment_ids.push(attachment_id);
 
 
 
23
 
24
- if(attachmentCache.get(attachment_id, 'attachment')){
25
 
26
- var attachment = attachmentCache.get(attachment_id, 'attachment');
27
 
28
- field.content += '<img src="' + attachment.url + '" alt="' + attachment.alt + '" title="' + attachment.title + '">';
29
 
30
- }
 
31
 
 
 
32
 
33
- return field;
34
- });
35
 
36
- attachmentCache.refresh(attachment_ids);
 
37
 
38
- return fields;
39
 
 
40
  };
41
 
42
- module.exports = Scraper;
1
+ /* global _ */
2
+
3
  var attachmentCache = require( "./../cache/cache.attachments.js" );
 
4
 
5
  var Scraper = function() {};
6
 
7
+ Scraper.prototype.scrape = function( fields ) {
8
+ var attachment_ids = [];
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
+ fields = _.map( fields, function( field ) {
11
+ if ( field.type !== "image" ) {
12
+ return field;
13
+ }
14
 
15
+ field.content = "";
16
 
17
+ var attachment_id = field.$el.find( "input[type=hidden]" ).val();
18
 
19
+ attachment_ids.push( attachment_id );
20
 
21
+ if ( attachmentCache.get( attachment_id, "attachment" ) ) {
22
+ var attachment = attachmentCache.get( attachment_id, "attachment" );
23
 
24
+ field.content += '<img src="' + attachment.url + '" alt="' + attachment.alt + '" title="' + attachment.title + '">';
25
+ }
26
 
 
 
27
 
28
+ return field;
29
+ } );
30
 
31
+ attachmentCache.refresh( attachment_ids );
32
 
33
+ return fields;
34
  };
35
 
36
+ module.exports = Scraper;
js/src/scraper/scraper.link.js ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global _ */
2
+ require( "./../scraper-store.js" );
3
+
4
+ var Scraper = function() {};
5
+
6
+ /**
7
+ * Scraper for the link field type.
8
+ *
9
+ * @param {Object} fields Fields to parse.
10
+ *
11
+ * @returns {Object} Mapped list of fields.
12
+ */
13
+ Scraper.prototype.scrape = function( fields ) {
14
+ /**
15
+ * Set content for all link fields as a-tag with title, url and target.
16
+ * Return the fields object containing all fields.
17
+ */
18
+ return _.map( fields, function( field ) {
19
+ if ( field.type !== "link" ) {
20
+ return field;
21
+ }
22
+
23
+ var title = field.$el.find( "input[type=hidden].input-title" ).val(),
24
+ url = field.$el.find( "input[type=hidden].input-url" ).val(),
25
+ target = field.$el.find( "input[type=hidden].input-target" ).val();
26
+
27
+ field.content = "<a href=\"" + url + "\" target=\"" + target + "\">" + title + "</a>";
28
+
29
+ return field;
30
+ } );
31
+ };
32
+
33
+ module.exports = Scraper;
js/src/scraper/scraper.taxonomy.js CHANGED
@@ -1,66 +1,54 @@
1
- var scrapers = require( "./../scraper-store.js" );
2
- var helper = require( "./../helper.js" );
3
 
4
  var Scraper = function() {};
5
 
6
- Scraper.prototype.scrape = function(fields){
7
-
8
- var that = this;
9
-
10
- fields = _.map(fields, function(field){
11
-
12
- if(field.type !== 'taxonomy'){
13
- return field;
14
- }
15
-
16
- var terms = [];
17
-
18
- if( field.$el.find('.acf-taxonomy-field[data-type="multi_select"]').length > 0 ){
19
-
20
- var select2Target = (helper.acf_version >= 5.6)?'select':'input';
21
-
22
- terms = _.pluck(
23
- field.$el.find('.acf-taxonomy-field[data-type="multi_select"] ' + select2Target )
24
- .select2('data')
25
- , 'text'
26
- );
27
-
28
- }else if( field.$el.find('.acf-taxonomy-field[data-type="checkbox"]').length > 0 ){
29
-
30
- terms = _.pluck(
31
- field.$el.find('.acf-taxonomy-field[data-type="checkbox"] input[type="checkbox"]:checked')
32
- .next(),
33
- 'textContent'
34
- );
35
-
36
- }else if( field.$el.find('input[type=checkbox]:checked').length > 0 ){
37
-
38
- terms = _.pluck(
39
- field.$el.find('input[type=checkbox]:checked')
40
- .parent(),
41
- 'textContent'
42
- );
43
-
44
- }else if( field.$el.find('select option:checked').length > 0 ){
45
-
46
- terms = _.pluck(
47
- field.$el.find('select option:checked'),
48
- 'textContent'
49
- );
50
-
51
- }
52
-
53
- terms = _.map( terms, function(term){ return term.trim(); } );
54
-
55
- if(terms.length>0){
56
- field.content = '<ul>\n<li>' + terms.join('</li>\n<li>') + '</li>\n</ul>';
57
- }
58
-
59
- return field;
60
- });
61
-
62
- return fields;
63
-
64
  };
65
 
66
- module.exports = Scraper;
1
+ /* global _, acf */
 
2
 
3
  var Scraper = function() {};
4
 
5
+ Scraper.prototype.scrape = function( fields ) {
6
+ fields = _.map( fields, function( field ) {
7
+ if ( field.type !== "taxonomy" ) {
8
+ return field;
9
+ }
10
+
11
+ var terms = [];
12
+
13
+ if ( field.$el.find( '.acf-taxonomy-field[data-type="multi_select"]' ).length > 0 ) {
14
+ var select2Target = ( acf.select2.version >= 4 ) ? "select" : "input";
15
+
16
+ terms = _.pluck(
17
+ field.$el.find( '.acf-taxonomy-field[data-type="multi_select"] ' + select2Target )
18
+ .select2( "data" )
19
+ , "text"
20
+ );
21
+ } else if ( field.$el.find( '.acf-taxonomy-field[data-type="checkbox"]' ).length > 0 ) {
22
+ terms = _.pluck(
23
+ field.$el.find( '.acf-taxonomy-field[data-type="checkbox"] input[type="checkbox"]:checked' )
24
+ .next(),
25
+ "textContent"
26
+ );
27
+ } else if ( field.$el.find( "input[type=checkbox]:checked" ).length > 0 ) {
28
+ terms = _.pluck(
29
+ field.$el.find( "input[type=checkbox]:checked" )
30
+ .parent(),
31
+ "textContent"
32
+ );
33
+ } else if ( field.$el.find( "select option:checked" ).length > 0 ) {
34
+ terms = _.pluck(
35
+ field.$el.find( "select option:checked" ),
36
+ "textContent"
37
+ );
38
+ }
39
+
40
+ terms = _.map( terms, function( term ) {
41
+ return term.trim();
42
+ } );
43
+
44
+ if ( terms.length > 0 ) {
45
+ field.content = "<ul>\n<li>" + terms.join( "</li>\n<li>" ) + "</li>\n</ul>";
46
+ }
47
+
48
+ return field;
49
+ } );
50
+
51
+ return fields;
 
 
 
 
 
 
 
 
 
 
 
52
  };
53
 
54
+ module.exports = Scraper;
js/src/scraper/scraper.text.js CHANGED
@@ -1,59 +1,51 @@
 
 
1
  var config = require( "./../config/config.js" );
2
- var scrapers = require( "./../scraper-store.js" );
3
 
4
  var Scraper = function() {};
5
 
6
- Scraper.prototype.scrape = function(fields){
7
-
8
- var that = this;
9
-
10
- fields = _.map(fields, function(field){
11
-
12
- if(field.type !== 'text'){
13
- return field;
14
- }
15
-
16
- field.content = field.$el.find('input[type=text][id^=acf]').val();
17
 
18
- field = that.wrapInHeadline(field);
 
 
 
19
 
20
- return field;
21
- });
22
 
23
- return fields;
 
24
 
 
25
  };
26
 
27
- Scraper.prototype.wrapInHeadline = function(field){
 
 
 
 
28
 
29
- var level = this.isHeadline(field);
30
- if(level){
31
- field.content = '<h' + level + '>' + field.content + '</h' + level + '>';
32
- }
33
-
34
- return field;
35
  };
36
 
37
- Scraper.prototype.isHeadline = function(field){
38
-
39
- var level = false;
40
-
41
- var level = _.find(config.scraper.text.headlines, function(value, key){
42
- return field.key === key;
43
- });
44
-
45
- //It has to be an integer
46
- if(level){
47
- level = parseInt(level, 10);
48
- }
49
 
50
- //Headlines only exist from h1 to h6
51
- if(level<1 || level>6){
52
- level = false;
53
- }
54
 
55
- return level;
 
 
 
56
 
 
57
  };
58
 
59
- module.exports = Scraper;
1
+ /* global _ */
2
+
3
  var config = require( "./../config/config.js" );
 
4
 
5
  var Scraper = function() {};
6
 
7
+ Scraper.prototype.scrape = function( fields ) {
8
+ var that = this;
 
 
 
 
 
 
 
 
 
9
 
10
+ fields = _.map( fields, function( field ) {
11
+ if ( field.type !== "text" ) {
12
+ return field;
13
+ }
14
 
15
+ field.content = field.$el.find( "input[type=text][id^=acf]" ).val();
16
+ field = that.wrapInHeadline( field );
17
 
18
+ return field;
19
+ } );
20
 
21
+ return fields;
22
  };
23
 
24
+ Scraper.prototype.wrapInHeadline = function( field ) {
25
+ var level = this.isHeadline( field );
26
+ if ( level ) {
27
+ field.content = "<h" + level + ">" + field.content + "</h" + level + ">";
28
+ }
29
 
30
+ return field;
 
 
 
 
 
31
  };
32
 
33
+ Scraper.prototype.isHeadline = function( field ) {
34
+ var level = _.find( config.scraper.text.headlines, function( value, key ) {
35
+ return field.key === key;
36
+ } );
 
 
 
 
 
 
 
 
37
 
38
+ // It has to be an integer
39
+ if ( level ) {
40
+ level = parseInt( level, 10 );
41
+ }
42
 
43
+ // Headlines only exist from h1 to h6
44
+ if ( level < 1 || level > 6 ) {
45
+ level = false;
46
+ }
47
 
48
+ return level;
49
  };
50
 
51
+ module.exports = Scraper;
js/src/scraper/scraper.textarea.js CHANGED
@@ -1,24 +1,19 @@
1
- var scrapers = require( "./../scraper-store.js" );
2
 
3
  var Scraper = function() {};
4
 
5
- Scraper.prototype.scrape = function(fields){
 
 
 
 
6
 
7
- var that = this;
8
 
9
- fields = _.map(fields, function(field){
10
-
11
- if(field.type !== 'textarea'){
12
- return field;
13
- }
14
-
15
- field.content = field.$el.find('textarea[id^=acf]').val();
16
-
17
- return field;
18
- });
19
-
20
- return fields;
21
 
 
22
  };
23
 
24
- module.exports = Scraper;
1
+ /* global _ */
2
 
3
  var Scraper = function() {};
4
 
5
+ Scraper.prototype.scrape = function( fields ) {
6
+ fields = _.map( fields, function( field ) {
7
+ if ( field.type !== "textarea" ) {
8
+ return field;
9
+ }
10
 
11
+ field.content = field.$el.find( "textarea[id^=acf]" ).val();
12
 
13
+ return field;
14
+ } );
 
 
 
 
 
 
 
 
 
 
15
 
16
+ return fields;
17
  };
18
 
19
+ module.exports = Scraper;
js/src/scraper/scraper.url.js CHANGED
@@ -1,24 +1,19 @@
1
- var scrapers = require( "./../scraper-store.js" );
2
 
3
  var Scraper = function() {};
4
 
5
- Scraper.prototype.scrape = function(fields){
 
 
 
 
6
 
7
- var that = this;
8
 
9
- fields = _.map(fields, function(field){
10
-
11
- if(field.type !== 'url'){
12
- return field;
13
- }
14
-
15
- field.content = field.$el.find('input[type=url][id^=acf]').val();
16
-
17
- return field;
18
- });
19
-
20
- return fields;
21
 
 
22
  };
23
 
24
- module.exports = Scraper;
1
+ /* global _ */
2
 
3
  var Scraper = function() {};
4
 
5
+ Scraper.prototype.scrape = function( fields ) {
6
+ fields = _.map( fields, function( field ) {
7
+ if ( field.type !== "url" ) {
8
+ return field;
9
+ }
10
 
11
+ field.content = field.$el.find( "input[type=url][id^=acf]" ).val();
12
 
13
+ return field;
14
+ } );
 
 
 
 
 
 
 
 
 
 
15
 
16
+ return fields;
17
  };
18
 
19
+ module.exports = Scraper;
js/src/scraper/scraper.wysiwyg.js CHANGED
@@ -1,62 +1,57 @@
1
- var scrapers = require( "./../scraper-store.js" );
2
 
3
  var Scraper = function() {};
4
 
5
- Scraper.prototype.scrape = function(fields){
6
-
7
- var that = this;
8
-
9
- fields = _.map(fields, function(field){
10
-
11
- if(field.type !== 'wysiwyg'){
12
- return field;
13
- }
14
-