vinsol_spree_themes 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +36 -0
  3. data/.ruby-version +1 -0
  4. data/Appraisals +16 -0
  5. data/Gemfile +9 -0
  6. data/Gemfile.lock +386 -0
  7. data/LICENSE +26 -0
  8. data/README.md +250 -0
  9. data/Rakefile +21 -0
  10. data/app/assets/javascripts/spree/backend/codemirror/codemirror.js +9351 -0
  11. data/app/assets/javascripts/spree/backend/codemirror/css-hint.js +60 -0
  12. data/app/assets/javascripts/spree/backend/codemirror/fullscreen.js +41 -0
  13. data/app/assets/javascripts/spree/backend/codemirror/html-hint.js +348 -0
  14. data/app/assets/javascripts/spree/backend/codemirror/javascript-hint.js +155 -0
  15. data/app/assets/javascripts/spree/backend/codemirror/javascript.js +813 -0
  16. data/app/assets/javascripts/spree/backend/codemirror/markdown.js +796 -0
  17. data/app/assets/javascripts/spree/backend/codemirror/ruby.js +295 -0
  18. data/app/assets/javascripts/spree/backend/codemirror/show-hint.js +438 -0
  19. data/app/assets/javascripts/spree/backend/editor.js +11 -0
  20. data/app/assets/javascripts/spree/backend/jquery.treemenu.js +87 -0
  21. data/app/assets/javascripts/spree/backend/main.js +26 -0
  22. data/app/assets/javascripts/spree/backend/spree_themes.js +2 -0
  23. data/app/assets/javascripts/spree/backend/template.js +51 -0
  24. data/app/assets/javascripts/spree/backend/theme.js +17 -0
  25. data/app/assets/javascripts/spree/frontend/spree_themes.js +2 -0
  26. data/app/assets/stylesheets/spree/backend/codemirror/codemirror.css +340 -0
  27. data/app/assets/stylesheets/spree/backend/codemirror/fullscreen.css +6 -0
  28. data/app/assets/stylesheets/spree/backend/codemirror/show-hint.css +36 -0
  29. data/app/assets/stylesheets/spree/backend/editor.css +7 -0
  30. data/app/assets/stylesheets/spree/backend/jquery.treemenu.css +8 -0
  31. data/app/assets/stylesheets/spree/backend/spree_themes.css +7 -0
  32. data/app/assets/stylesheets/spree/backend/style.css +239 -0
  33. data/app/assets/stylesheets/spree/backend/template_editor.css +39 -0
  34. data/app/assets/stylesheets/spree/frontend/spree_themes.css +6 -0
  35. data/app/assets/stylesheets/spree/frontend/theme_preview.css +9 -0
  36. data/app/controllers/spree/admin/themes_controller.rb +80 -0
  37. data/app/controllers/spree/admin/themes_preview_controller.rb +30 -0
  38. data/app/controllers/spree/admin/themes_templates_controller.rb +60 -0
  39. data/app/controllers/spree/fragment_cache_controller.rb +13 -0
  40. data/app/controllers/spree/store_controller_decorator.rb +37 -0
  41. data/app/helpers/spree/base_helper_decorator.rb +45 -0
  42. data/app/models/spree/theme.rb +153 -0
  43. data/app/models/spree/themes_template.rb +67 -0
  44. data/app/models/spree/themes_template/cache_resolver.rb +37 -0
  45. data/app/overrides/spree/add_preview_bar_to_store.html.rb +6 -0
  46. data/app/overrides/spree/add_theme_meta_details_to_store.html.rb +6 -0
  47. data/app/overrides/spree/admin/add_themes_tab.html.rb +6 -0
  48. data/app/services/assets_precompiler_service.rb +86 -0
  49. data/app/services/file_generator_service.rb +29 -0
  50. data/app/services/template_generator_service.rb +101 -0
  51. data/app/services/zip_file_builder.rb +87 -0
  52. data/app/services/zip_file_extractor.rb +52 -0
  53. data/app/views/spree/admin/shared/_theme_menu_button.html.erb +5 -0
  54. data/app/views/spree/admin/themes/_themes.html.erb +44 -0
  55. data/app/views/spree/admin/themes/_upload.html.erb +17 -0
  56. data/app/views/spree/admin/themes/index.html.erb +50 -0
  57. data/app/views/spree/admin/themes_templates/_editor.html.erb +29 -0
  58. data/app/views/spree/admin/themes_templates/_template.html.erb +12 -0
  59. data/app/views/spree/admin/themes_templates/edit.html.erb +13 -0
  60. data/app/views/spree/admin/themes_templates/edit.js.erb +1 -0
  61. data/app/views/spree/admin/themes_templates/index.html.erb +27 -0
  62. data/app/views/spree/admin/themes_templates/new.html.erb +56 -0
  63. data/app/views/spree/shared/_preview_bar.html.erb +7 -0
  64. data/app/views/spree/shared/_theme_metadata.html.erb +9 -0
  65. data/bin/rails +7 -0
  66. data/config/initializers/assets.rb +24 -0
  67. data/config/initializers/sprockets.rb +85 -0
  68. data/config/locales/en.yml +52 -0
  69. data/config/routes.rb +22 -0
  70. data/db/migrate/20170628072452_vinsol_spree_themes_create_themes_and_themes_templates_table.rb +24 -0
  71. data/gemfiles/spree_3_1.gemfile +8 -0
  72. data/gemfiles/spree_3_2.gemfile +9 -0
  73. data/gemfiles/spree_master.gemfile +9 -0
  74. data/lib/generators/themes/default.zip +0 -0
  75. data/lib/generators/vinsol_spree_themes/install/install_generator.rb +50 -0
  76. data/lib/tasks/sync_templates.rake +47 -0
  77. data/lib/vinsol_spree_themes.rb +3 -0
  78. data/lib/vinsol_spree_themes/engine.rb +22 -0
  79. data/lib/vinsol_spree_themes/factories.rb +6 -0
  80. data/lib/vinsol_spree_themes/version.rb +18 -0
  81. data/spec/spec_helper.rb +93 -0
  82. data/vinsol_spree_themes.gemspec +43 -0
  83. metadata +374 -0
@@ -0,0 +1,60 @@
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"), require("../../mode/css/css"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror", "../../mode/css/css"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ var pseudoClasses = {link: 1, visited: 1, active: 1, hover: 1, focus: 1,
15
+ "first-letter": 1, "first-line": 1, "first-child": 1,
16
+ before: 1, after: 1, lang: 1};
17
+
18
+ CodeMirror.registerHelper("hint", "css", function(cm) {
19
+ var cur = cm.getCursor(), token = cm.getTokenAt(cur);
20
+ var inner = CodeMirror.innerMode(cm.getMode(), token.state);
21
+ if (inner.mode.name != "css") return;
22
+
23
+ if (token.type == "keyword" && "!important".indexOf(token.string) == 0)
24
+ return {list: ["!important"], from: CodeMirror.Pos(cur.line, token.start),
25
+ to: CodeMirror.Pos(cur.line, token.end)};
26
+
27
+ var start = token.start, end = cur.ch, word = token.string.slice(0, end - start);
28
+ if (/[^\w$_-]/.test(word)) {
29
+ word = ""; start = end = cur.ch;
30
+ }
31
+
32
+ var spec = CodeMirror.resolveMode("text/css");
33
+
34
+ var result = [];
35
+ function add(keywords) {
36
+ for (var name in keywords)
37
+ if (!word || name.lastIndexOf(word, 0) == 0)
38
+ result.push(name);
39
+ }
40
+
41
+ var st = inner.state.state;
42
+ if (st == "pseudo" || token.type == "variable-3") {
43
+ add(pseudoClasses);
44
+ } else if (st == "block" || st == "maybeprop") {
45
+ add(spec.propertyKeywords);
46
+ } else if (st == "prop" || st == "parens" || st == "at" || st == "params") {
47
+ add(spec.valueKeywords);
48
+ add(spec.colorKeywords);
49
+ } else if (st == "media" || st == "media_parens") {
50
+ add(spec.mediaTypes);
51
+ add(spec.mediaFeatures);
52
+ }
53
+
54
+ if (result.length) return {
55
+ list: result,
56
+ from: CodeMirror.Pos(cur.line, start),
57
+ to: CodeMirror.Pos(cur.line, end)
58
+ };
59
+ });
60
+ });
@@ -0,0 +1,41 @@
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ CodeMirror.defineOption("fullScreen", false, function(cm, val, old) {
15
+ if (old == CodeMirror.Init) old = false;
16
+ if (!old == !val) return;
17
+ if (val) setFullscreen(cm);
18
+ else setNormal(cm);
19
+ });
20
+
21
+ function setFullscreen(cm) {
22
+ var wrap = cm.getWrapperElement();
23
+ cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset,
24
+ width: wrap.style.width, height: wrap.style.height};
25
+ wrap.style.width = "";
26
+ wrap.style.height = "auto";
27
+ wrap.className += " CodeMirror-fullscreen";
28
+ document.documentElement.style.overflow = "hidden";
29
+ cm.refresh();
30
+ }
31
+
32
+ function setNormal(cm) {
33
+ var wrap = cm.getWrapperElement();
34
+ wrap.className = wrap.className.replace(/\s*CodeMirror-fullscreen\b/, "");
35
+ document.documentElement.style.overflow = "";
36
+ var info = cm.state.fullScreenRestore;
37
+ wrap.style.width = info.width; wrap.style.height = info.height;
38
+ window.scrollTo(info.scrollLeft, info.scrollTop);
39
+ cm.refresh();
40
+ }
41
+ });
@@ -0,0 +1,348 @@
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"), require("./xml-hint"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror", "./xml-hint"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ var langs = "ab aa af ak sq am ar an hy as av ae ay az bm ba eu be bn bh bi bs br bg my ca ch ce ny zh cv kw co cr hr cs da dv nl dz en eo et ee fo fj fi fr ff gl ka de el gn gu ht ha he hz hi ho hu ia id ie ga ig ik io is it iu ja jv kl kn kr ks kk km ki rw ky kv kg ko ku kj la lb lg li ln lo lt lu lv gv mk mg ms ml mt mi mr mh mn na nv nb nd ne ng nn no ii nr oc oj cu om or os pa pi fa pl ps pt qu rm rn ro ru sa sc sd se sm sg sr gd sn si sk sl so st es su sw ss sv ta te tg th ti bo tk tl tn to tr ts tt tw ty ug uk ur uz ve vi vo wa cy wo fy xh yi yo za zu".split(" ");
15
+ var targets = ["_blank", "_self", "_top", "_parent"];
16
+ var charsets = ["ascii", "utf-8", "utf-16", "latin1", "latin1"];
17
+ var methods = ["get", "post", "put", "delete"];
18
+ var encs = ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"];
19
+ var media = ["all", "screen", "print", "embossed", "braille", "handheld", "print", "projection", "screen", "tty", "tv", "speech",
20
+ "3d-glasses", "resolution [>][<][=] [X]", "device-aspect-ratio: X/Y", "orientation:portrait",
21
+ "orientation:landscape", "device-height: [X]", "device-width: [X]"];
22
+ var s = { attrs: {} }; // Simple tag, reused for a whole lot of tags
23
+
24
+ var data = {
25
+ a: {
26
+ attrs: {
27
+ href: null, ping: null, type: null,
28
+ media: media,
29
+ target: targets,
30
+ hreflang: langs
31
+ }
32
+ },
33
+ abbr: s,
34
+ acronym: s,
35
+ address: s,
36
+ applet: s,
37
+ area: {
38
+ attrs: {
39
+ alt: null, coords: null, href: null, target: null, ping: null,
40
+ media: media, hreflang: langs, type: null,
41
+ shape: ["default", "rect", "circle", "poly"]
42
+ }
43
+ },
44
+ article: s,
45
+ aside: s,
46
+ audio: {
47
+ attrs: {
48
+ src: null, mediagroup: null,
49
+ crossorigin: ["anonymous", "use-credentials"],
50
+ preload: ["none", "metadata", "auto"],
51
+ autoplay: ["", "autoplay"],
52
+ loop: ["", "loop"],
53
+ controls: ["", "controls"]
54
+ }
55
+ },
56
+ b: s,
57
+ base: { attrs: { href: null, target: targets } },
58
+ basefont: s,
59
+ bdi: s,
60
+ bdo: s,
61
+ big: s,
62
+ blockquote: { attrs: { cite: null } },
63
+ body: s,
64
+ br: s,
65
+ button: {
66
+ attrs: {
67
+ form: null, formaction: null, name: null, value: null,
68
+ autofocus: ["", "autofocus"],
69
+ disabled: ["", "autofocus"],
70
+ formenctype: encs,
71
+ formmethod: methods,
72
+ formnovalidate: ["", "novalidate"],
73
+ formtarget: targets,
74
+ type: ["submit", "reset", "button"]
75
+ }
76
+ },
77
+ canvas: { attrs: { width: null, height: null } },
78
+ caption: s,
79
+ center: s,
80
+ cite: s,
81
+ code: s,
82
+ col: { attrs: { span: null } },
83
+ colgroup: { attrs: { span: null } },
84
+ command: {
85
+ attrs: {
86
+ type: ["command", "checkbox", "radio"],
87
+ label: null, icon: null, radiogroup: null, command: null, title: null,
88
+ disabled: ["", "disabled"],
89
+ checked: ["", "checked"]
90
+ }
91
+ },
92
+ data: { attrs: { value: null } },
93
+ datagrid: { attrs: { disabled: ["", "disabled"], multiple: ["", "multiple"] } },
94
+ datalist: { attrs: { data: null } },
95
+ dd: s,
96
+ del: { attrs: { cite: null, datetime: null } },
97
+ details: { attrs: { open: ["", "open"] } },
98
+ dfn: s,
99
+ dir: s,
100
+ div: s,
101
+ dl: s,
102
+ dt: s,
103
+ em: s,
104
+ embed: { attrs: { src: null, type: null, width: null, height: null } },
105
+ eventsource: { attrs: { src: null } },
106
+ fieldset: { attrs: { disabled: ["", "disabled"], form: null, name: null } },
107
+ figcaption: s,
108
+ figure: s,
109
+ font: s,
110
+ footer: s,
111
+ form: {
112
+ attrs: {
113
+ action: null, name: null,
114
+ "accept-charset": charsets,
115
+ autocomplete: ["on", "off"],
116
+ enctype: encs,
117
+ method: methods,
118
+ novalidate: ["", "novalidate"],
119
+ target: targets
120
+ }
121
+ },
122
+ frame: s,
123
+ frameset: s,
124
+ h1: s, h2: s, h3: s, h4: s, h5: s, h6: s,
125
+ head: {
126
+ attrs: {},
127
+ children: ["title", "base", "link", "style", "meta", "script", "noscript", "command"]
128
+ },
129
+ header: s,
130
+ hgroup: s,
131
+ hr: s,
132
+ html: {
133
+ attrs: { manifest: null },
134
+ children: ["head", "body"]
135
+ },
136
+ i: s,
137
+ iframe: {
138
+ attrs: {
139
+ src: null, srcdoc: null, name: null, width: null, height: null,
140
+ sandbox: ["allow-top-navigation", "allow-same-origin", "allow-forms", "allow-scripts"],
141
+ seamless: ["", "seamless"]
142
+ }
143
+ },
144
+ img: {
145
+ attrs: {
146
+ alt: null, src: null, ismap: null, usemap: null, width: null, height: null,
147
+ crossorigin: ["anonymous", "use-credentials"]
148
+ }
149
+ },
150
+ input: {
151
+ attrs: {
152
+ alt: null, dirname: null, form: null, formaction: null,
153
+ height: null, list: null, max: null, maxlength: null, min: null,
154
+ name: null, pattern: null, placeholder: null, size: null, src: null,
155
+ step: null, value: null, width: null,
156
+ accept: ["audio/*", "video/*", "image/*"],
157
+ autocomplete: ["on", "off"],
158
+ autofocus: ["", "autofocus"],
159
+ checked: ["", "checked"],
160
+ disabled: ["", "disabled"],
161
+ formenctype: encs,
162
+ formmethod: methods,
163
+ formnovalidate: ["", "novalidate"],
164
+ formtarget: targets,
165
+ multiple: ["", "multiple"],
166
+ readonly: ["", "readonly"],
167
+ required: ["", "required"],
168
+ type: ["hidden", "text", "search", "tel", "url", "email", "password", "datetime", "date", "month",
169
+ "week", "time", "datetime-local", "number", "range", "color", "checkbox", "radio",
170
+ "file", "submit", "image", "reset", "button"]
171
+ }
172
+ },
173
+ ins: { attrs: { cite: null, datetime: null } },
174
+ kbd: s,
175
+ keygen: {
176
+ attrs: {
177
+ challenge: null, form: null, name: null,
178
+ autofocus: ["", "autofocus"],
179
+ disabled: ["", "disabled"],
180
+ keytype: ["RSA"]
181
+ }
182
+ },
183
+ label: { attrs: { "for": null, form: null } },
184
+ legend: s,
185
+ li: { attrs: { value: null } },
186
+ link: {
187
+ attrs: {
188
+ href: null, type: null,
189
+ hreflang: langs,
190
+ media: media,
191
+ sizes: ["all", "16x16", "16x16 32x32", "16x16 32x32 64x64"]
192
+ }
193
+ },
194
+ map: { attrs: { name: null } },
195
+ mark: s,
196
+ menu: { attrs: { label: null, type: ["list", "context", "toolbar"] } },
197
+ meta: {
198
+ attrs: {
199
+ content: null,
200
+ charset: charsets,
201
+ name: ["viewport", "application-name", "author", "description", "generator", "keywords"],
202
+ "http-equiv": ["content-language", "content-type", "default-style", "refresh"]
203
+ }
204
+ },
205
+ meter: { attrs: { value: null, min: null, low: null, high: null, max: null, optimum: null } },
206
+ nav: s,
207
+ noframes: s,
208
+ noscript: s,
209
+ object: {
210
+ attrs: {
211
+ data: null, type: null, name: null, usemap: null, form: null, width: null, height: null,
212
+ typemustmatch: ["", "typemustmatch"]
213
+ }
214
+ },
215
+ ol: { attrs: { reversed: ["", "reversed"], start: null, type: ["1", "a", "A", "i", "I"] } },
216
+ optgroup: { attrs: { disabled: ["", "disabled"], label: null } },
217
+ option: { attrs: { disabled: ["", "disabled"], label: null, selected: ["", "selected"], value: null } },
218
+ output: { attrs: { "for": null, form: null, name: null } },
219
+ p: s,
220
+ param: { attrs: { name: null, value: null } },
221
+ pre: s,
222
+ progress: { attrs: { value: null, max: null } },
223
+ q: { attrs: { cite: null } },
224
+ rp: s,
225
+ rt: s,
226
+ ruby: s,
227
+ s: s,
228
+ samp: s,
229
+ script: {
230
+ attrs: {
231
+ type: ["text/javascript"],
232
+ src: null,
233
+ async: ["", "async"],
234
+ defer: ["", "defer"],
235
+ charset: charsets
236
+ }
237
+ },
238
+ section: s,
239
+ select: {
240
+ attrs: {
241
+ form: null, name: null, size: null,
242
+ autofocus: ["", "autofocus"],
243
+ disabled: ["", "disabled"],
244
+ multiple: ["", "multiple"]
245
+ }
246
+ },
247
+ small: s,
248
+ source: { attrs: { src: null, type: null, media: null } },
249
+ span: s,
250
+ strike: s,
251
+ strong: s,
252
+ style: {
253
+ attrs: {
254
+ type: ["text/css"],
255
+ media: media,
256
+ scoped: null
257
+ }
258
+ },
259
+ sub: s,
260
+ summary: s,
261
+ sup: s,
262
+ table: s,
263
+ tbody: s,
264
+ td: { attrs: { colspan: null, rowspan: null, headers: null } },
265
+ textarea: {
266
+ attrs: {
267
+ dirname: null, form: null, maxlength: null, name: null, placeholder: null,
268
+ rows: null, cols: null,
269
+ autofocus: ["", "autofocus"],
270
+ disabled: ["", "disabled"],
271
+ readonly: ["", "readonly"],
272
+ required: ["", "required"],
273
+ wrap: ["soft", "hard"]
274
+ }
275
+ },
276
+ tfoot: s,
277
+ th: { attrs: { colspan: null, rowspan: null, headers: null, scope: ["row", "col", "rowgroup", "colgroup"] } },
278
+ thead: s,
279
+ time: { attrs: { datetime: null } },
280
+ title: s,
281
+ tr: s,
282
+ track: {
283
+ attrs: {
284
+ src: null, label: null, "default": null,
285
+ kind: ["subtitles", "captions", "descriptions", "chapters", "metadata"],
286
+ srclang: langs
287
+ }
288
+ },
289
+ tt: s,
290
+ u: s,
291
+ ul: s,
292
+ "var": s,
293
+ video: {
294
+ attrs: {
295
+ src: null, poster: null, width: null, height: null,
296
+ crossorigin: ["anonymous", "use-credentials"],
297
+ preload: ["auto", "metadata", "none"],
298
+ autoplay: ["", "autoplay"],
299
+ mediagroup: ["movie"],
300
+ muted: ["", "muted"],
301
+ controls: ["", "controls"]
302
+ }
303
+ },
304
+ wbr: s
305
+ };
306
+
307
+ var globalAttrs = {
308
+ accesskey: ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"],
309
+ "class": null,
310
+ contenteditable: ["true", "false"],
311
+ contextmenu: null,
312
+ dir: ["ltr", "rtl", "auto"],
313
+ draggable: ["true", "false", "auto"],
314
+ dropzone: ["copy", "move", "link", "string:", "file:"],
315
+ hidden: ["hidden"],
316
+ id: null,
317
+ inert: ["inert"],
318
+ itemid: null,
319
+ itemprop: null,
320
+ itemref: null,
321
+ itemscope: ["itemscope"],
322
+ itemtype: null,
323
+ lang: ["en", "es"],
324
+ spellcheck: ["true", "false"],
325
+ style: null,
326
+ tabindex: ["1", "2", "3", "4", "5", "6", "7", "8", "9"],
327
+ title: null,
328
+ translate: ["yes", "no"],
329
+ onclick: null,
330
+ rel: ["stylesheet", "alternate", "author", "bookmark", "help", "license", "next", "nofollow", "noreferrer", "prefetch", "prev", "search", "tag"]
331
+ };
332
+ function populate(obj) {
333
+ for (var attr in globalAttrs) if (globalAttrs.hasOwnProperty(attr))
334
+ obj.attrs[attr] = globalAttrs[attr];
335
+ }
336
+
337
+ populate(s);
338
+ for (var tag in data) if (data.hasOwnProperty(tag) && data[tag] != s)
339
+ populate(data[tag]);
340
+
341
+ CodeMirror.htmlSchema = data;
342
+ function htmlHint(cm, options) {
343
+ var local = {schemaInfo: data};
344
+ if (options) for (var opt in options) local[opt] = options[opt];
345
+ return CodeMirror.hint.xml(cm, local);
346
+ }
347
+ CodeMirror.registerHelper("hint", "html", htmlHint);
348
+ });