seopro.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. var seoPro = function(config) {
  2. config = config || {};
  3. seoPro.superclass.constructor.call(this, config);
  4. };
  5. Ext.extend(seoPro, Ext.Component, {
  6. page: {}, window: {}, grid: {}, tree: {}, panel: {}, combo: {}, config: {}, view: {},
  7. initialize: function() {
  8. seoPro.config.loaded = true;
  9. seoPro.config.delimiter = MODx.isEmpty(MODx.config['seopro.delimiter']) ? '|' : MODx.config['seopro.delimiter'];
  10. seoPro.config.siteNameShow = !MODx.isEmpty(MODx.config['seopro.usesitename']);
  11. seoPro.config.searchEngine = MODx.isEmpty(MODx.config['seopro.searchengine']) ? 'google' : MODx.config['seopro.searchengine'];
  12. seoPro.config.titleFormat = MODx.isEmpty(MODx.config['seopro.title_format']) ? '' : MODx.config['seopro.title_format'];
  13. seoPro.addKeywords();
  14. seoPro.addPanel();
  15. Ext.each(seoPro.config.fields.split(','), function(field) {
  16. seoPro.addCounter(field);
  17. if (field !== 'alias' && field !== 'menutitle') {
  18. seoPro.changePrevBox(field);
  19. }
  20. });
  21. Ext.getCmp('modx-panel-resource').on('success', function() {
  22. if(Ext.get('seopro-replace-alias')) {
  23. Ext.get('seopro-replace-alias').dom.innerHTML = this.record.alias;
  24. }
  25. });
  26. },
  27. addCounter: function(field) {
  28. var Field = Ext.getCmp('modx-resource-' + field);
  29. /*
  30. if (!Field && field === 'description') {
  31. field = 'introtext';
  32. Field = Ext.getCmp('modx-resource-' + field);
  33. seoPro.config.chars[field] = "155";
  34. }*/
  35. if (Field) {
  36. seoPro.config.values[field] = Field.getValue();
  37. Field.maxLength = Number(seoPro.config.chars[field]);
  38. Field.reset();
  39. Field.on('keyup', function() {
  40. seoPro.config.values[field] = Field.getValue();
  41. seoPro.count(field);
  42. seoPro.changePrevBox(field);
  43. });
  44. Field.on('blur', function() {
  45. seoPro.config.values[field] = Field.getValue();
  46. seoPro.changePrevBox(field);
  47. });
  48. Ext.get('x-form-el-modx-resource-' + field).createChild({
  49. tag: 'div',
  50. id: 'seopro-resource-' + field,
  51. class: 'seopro-counter',
  52. html: '<span class="seopro-counter-wrap seopro-counter-keywords" id="seopro-counter-keywords-' + field + '" title="' + _('seopro.keywords') + '"><strong>' + _('seopro.keywords') + ':&nbsp;&nbsp;</strong><span id="seopro-counter-keywords-' + field + '-current">0</span></span>\
  53. <span class="seopro-counter-wrap seopro-counter-chars" id="seopro-counter-chars-' + field + '" title="' + _('seopro.characters.allowed') + '"><strong>' + _('seopro.characters') + ': </strong><span class="current" id="seopro-counter-chars-' + field + '-current">1</span>/<span class="allowed" id="seopro-counter-chars-' + field + '-allowed">' + seoPro.config.chars[field] + '</span></span>'
  54. });
  55. seoPro.count(field);
  56. }
  57. },
  58. addKeywords: function() {
  59. var fp = Ext.getCmp('modx-resource-main-left');
  60. var field = new Ext.form.TextField({
  61. xtype: 'textfield',
  62. name: 'keywords',
  63. id: 'seopro-keywords',
  64. fieldLabel: _('seopro.focuskeywords'),
  65. description: '[[+seoPro.keywords]]',
  66. value: seoPro.config.record,
  67. enableKeyEvents: true,
  68. anchor: '100%',
  69. listeners: {
  70. 'keyup': function() {
  71. MODx.fireResourceFormChange();
  72. Ext.each(seoPro.config.fields.split(','), function(field) {
  73. var Field = Ext.getCmp('modx-resource-' + field);
  74. if (Field) {
  75. seoPro.count(field);
  76. }
  77. });
  78. }
  79. }
  80. });
  81. var fieldDesc = new Ext.form.Label({
  82. forId: 'pagetitle',
  83. text: _('seopro.focuskeywords_desc'),
  84. cls: 'desc-under'
  85. });
  86. fp.add(field);
  87. fp.add(fieldDesc);
  88. fp.doLayout();
  89. },
  90. addPanel: function() {
  91. var fp = Ext.getCmp('modx-resource-main-left');
  92. fp.add({
  93. xtype: 'panel',
  94. anchor: '100%',
  95. border: false,
  96. fieldLabel: (seoPro.config.searchEngine == 'yandex' ? _('seopro.prevbox_yandex') : _('seopro.prevbox')),
  97. layout: 'form',
  98. items: [{
  99. columnWidth: .67,
  100. xtype: 'panel',
  101. baseCls: 'seopro-panel',
  102. cls: seoPro.config.searchEngine,
  103. bodyStyle: 'padding: 10px;',
  104. border: false,
  105. autoHeight: true,
  106. items: [{
  107. xtype: 'box',
  108. id: 'seopro-google-title',
  109. style: 'background-color: #fbfbfb; background-image: url(https://www.google.com/s2/favicons?domain='+MODx.config.site_url+');',
  110. cls: seoPro.config.searchEngine,
  111. html: '',
  112. border: false
  113. }, {
  114. xtype: 'box',
  115. id: 'seopro-google-url',
  116. bodyStyle: 'background-color: #fbfbfb;',
  117. cls: seoPro.config.searchEngine,
  118. html: seoPro.config.url,
  119. border: false
  120. }, {
  121. xtype: 'box',
  122. id: 'seopro-google-description',
  123. bodyStyle: 'background-color: #fbfbfb;',
  124. cls: seoPro.config.searchEngine,
  125. html: '',
  126. border: false
  127. }]
  128. }]
  129. });
  130. fp.doLayout();
  131. },
  132. count: function(field, overrideCount) {
  133. var Value = Ext.get('modx-resource-' + field).getValue();
  134. var maxchars = Ext.get('seopro-counter-chars-' + field + '-allowed').dom.innerHTML;
  135. var charCount;
  136. if (overrideCount) {
  137. charCount = overrideCount;
  138. } else {
  139. charCount = Value.length;
  140. // console.log(Ext.get('seopro-google-title').length);
  141. // console.log(Ext.get('seopro-google-title').dom.innerHTML);
  142. if (seoPro.config.siteNameShow && (field === 'pagetitle' || field === 'longtitle')) {
  143. var extra = ' ' + seoPro.config.delimiter + ' ' + MODx.config.site_name;
  144. charCount = charCount + extra.length;
  145. }
  146. }
  147. var keywordCount = 0;
  148. Ext.each(Ext.get('seopro-keywords').getValue().split(','), function(keyword) {
  149. keyword = keyword.replace(/^\s+/, '').toLowerCase();
  150. if (keyword) {
  151. var counter = Value.toLowerCase().match(new RegExp("(^|[ \s\n\r\t\.,'\(\"\+;!?:\-])" + keyword + "($|[ \s\n\r\t.,'\)\"\+!?:;\-])", 'gim'));
  152. // var counter = Value.toLowerCase().match(new RegExp('\\b' + keyword + '\\b', 'g'));
  153. if (counter) {
  154. keywordCount = keywordCount + counter.length;
  155. }
  156. }
  157. });
  158. Ext.get('seopro-counter-chars-' + field + '-current').dom.innerHTML = charCount;
  159. Ext.get('seopro-counter-keywords-' + field + '-current').dom.innerHTML = keywordCount;
  160. var maxKeywords = MODx.isEmpty(MODx.config['seopro.max_keywords_title']) ? '4' : MODx.config['seopro.max_keywords_title'];
  161. if (field === 'description') {
  162. // use different limit for the description
  163. maxKeywords = MODx.isEmpty(MODx.config['seopro.max_keywords_description']) ? '8' : MODx.config['seopro.max_keywords_description'];
  164. }
  165. maxKeywords = parseInt(maxKeywords);
  166. if (keywordCount > 0 && keywordCount <= maxKeywords) {
  167. Ext.get('seopro-counter-keywords-' + field).removeClass('red').addClass('green');
  168. } else {
  169. Ext.get('seopro-counter-keywords-' + field).removeClass('green').addClass('red');
  170. }
  171. if (charCount > maxchars || charCount === 0) {
  172. Ext.get('seopro-counter-chars-' + field).removeClass('green').addClass('red');
  173. } else {
  174. Ext.get('seopro-counter-chars-' + field).removeClass('red').addClass('green');
  175. }
  176. },
  177. changePrevBox: function(field) {
  178. switch (field) {
  179. case 'pagetitle':
  180. case 'longtitle':
  181. var title;
  182. var resourceId = MODx.request.id;
  183. var pagetitle = Ext.get('modx-resource-pagetitle').getValue();
  184. var longtitle = Ext.get('modx-resource-longtitle').getValue();
  185. if (seoPro.config.titleFormat && resourceId) {
  186. MODx.Ajax.request({
  187. url: seoPro.config.connectorUrl
  188. ,params: {
  189. action: 'mgr/resource/parse',
  190. id: resourceId,
  191. pagetitle: pagetitle,
  192. longtitle: longtitle,
  193. html: seoPro.config.titleFormat,
  194. }
  195. ,listeners: {
  196. 'success':{fn:function(r) {
  197. title = r.results.output;
  198. Ext.get('seopro-google-title').dom.innerHTML = title;
  199. var count = title.length;
  200. seoPro.count(field, count);
  201. },scope:this}
  202. }
  203. });
  204. } else {
  205. title = seoPro.config.values['pagetitle'];
  206. if (!MODx.isEmpty(seoPro.config.values['longtitle'])) {
  207. title = seoPro.config.values['longtitle'];
  208. }
  209. if (seoPro.config.siteNameShow) {
  210. title += ' ' + seoPro.config.delimiter + ' ' + MODx.config.site_name;
  211. }
  212. Ext.get('seopro-google-title').dom.innerHTML = title;
  213. }
  214. break;
  215. case 'description':
  216. case 'introtext':
  217. var description;
  218. if (MODx.isEmpty(seoPro.config.values['description'])) {
  219. var introCheck = Ext.getCmp('modx-resource-description');
  220. if (!MODx.isEmpty(seoPro.config.values['introtext']) && !introCheck) {
  221. description = seoPro.config.values['introtext'];
  222. } else {
  223. description = _('seopro.emptymetadescription');
  224. }
  225. } else {
  226. description = seoPro.config.values['description'];
  227. }
  228. Ext.get('seopro-google-description').dom.innerHTML = description;
  229. break;
  230. case 'alias':
  231. Ext.get('seopro-replace-alias').dom.innerHTML = seoPro.config.values['alias'];
  232. break;
  233. }
  234. }
  235. });
  236. Ext.reg('seopro', seoPro);
  237. seoPro = new seoPro();
  238. Ext.onReady(function() {
  239. if (!seoPro.config.loaded) {
  240. seoPro.initialize();
  241. }
  242. });