phrasing 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/.gitignore +2 -0
  2. data/Gemfile +10 -0
  3. data/Gemfile.lock +142 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +93 -0
  6. data/Rakefile +35 -0
  7. data/app/assets/fonts/icomoon.dev.svg +38 -0
  8. data/app/assets/fonts/icomoon.eot +0 -0
  9. data/app/assets/fonts/icomoon.svg +38 -0
  10. data/app/assets/fonts/icomoon.ttf +0 -0
  11. data/app/assets/fonts/icomoon.woff +0 -0
  12. data/app/assets/images/phrasing_information_icon.png +0 -0
  13. data/app/assets/javascripts/editor.js +318 -0
  14. data/app/assets/javascripts/head.js +423 -0
  15. data/app/assets/javascripts/phrasing.js.erb +148 -0
  16. data/app/assets/javascripts/spin.js +355 -0
  17. data/app/assets/stylesheets/phrasing.css.scss +240 -0
  18. data/app/assets/stylesheets/phrasing_edit_mode_bubble.css.scss +117 -0
  19. data/app/assets/stylesheets/phrasing_engine.css +470 -0
  20. data/app/assets/stylesheets/phrasing_fonts.css.scss +60 -0
  21. data/app/controllers/phrasing_phrases_controller.rb +126 -0
  22. data/app/helpers/inline_helper.rb +47 -0
  23. data/app/models/phrasing_phrase.rb +97 -0
  24. data/app/views/layouts/phrasing.html.haml +12 -0
  25. data/app/views/phrasing/_initializer.html.haml +25 -0
  26. data/app/views/phrasing/_menu.html.haml +8 -0
  27. data/app/views/phrasing/_messages.html.haml +4 -0
  28. data/app/views/phrasing/_production_warning.html.haml +4 -0
  29. data/app/views/phrasing_phrases/edit.html.haml +7 -0
  30. data/app/views/phrasing_phrases/help.html.haml +17 -0
  31. data/app/views/phrasing_phrases/import_export.html.haml +18 -0
  32. data/app/views/phrasing_phrases/index.html.haml +17 -0
  33. data/config/routes.rb +12 -0
  34. data/db/migrate/20120313191745_create_phrasing_phrases.rb +11 -0
  35. data/lib/phrasing.rb +72 -0
  36. data/lib/phrasing/ambiguous_phrases_error.rb +3 -0
  37. data/lib/phrasing/implementation.rb +19 -0
  38. data/lib/phrasing/phrasable_error_handler.rb +9 -0
  39. data/lib/phrasing/simple.rb +3 -0
  40. data/lib/phrasing/version.rb +3 -0
  41. data/lib/tasks/phrasing_tasks.rake +57 -0
  42. data/phrasing.gemspec +21 -0
  43. metadata +135 -0
@@ -0,0 +1,423 @@
1
+ (function (a, w) {
2
+ function f(a) {
3
+ p[p.length] = a
4
+ }
5
+
6
+ function m(a) {
7
+ q.className = q.className.replace(RegExp("\\b" + a + "\\b"), "")
8
+ }
9
+
10
+ function k(a, d) {
11
+ for (var b = 0, c = a.length; b < c; b++) d.call(a, a[b], b)
12
+ }
13
+
14
+ function s() {
15
+ q.className = q.className.replace(/ (w-|eq-|gt-|gte-|lt-|lte-|portrait|no-portrait|landscape|no-landscape)\d+/g, "");
16
+ var b = a.innerWidth || q.clientWidth,
17
+ d = a.outerWidth || a.screen.width;
18
+ h.screen.innerWidth = b;
19
+ h.screen.outerWidth = d;
20
+ f("w-" + b);
21
+ k(c.screens, function (a) {
22
+ b > a ? (c.screensCss.gt && f("gt-" + a), c.screensCss.gte && f("gte-" +
23
+ a)) : b < a ? (c.screensCss.lt && f("lt-" + a), c.screensCss.lte && f("lte-" + a)) : b === a && (c.screensCss.lte && f("lte-" + a), c.screensCss.eq && f("e-q" + a), c.screensCss.gte && f("gte-" + a))
24
+ });
25
+ var d = a.innerHeight || q.clientHeight,
26
+ g = a.outerHeight || a.screen.height;
27
+ h.screen.innerHeight = d;
28
+ h.screen.outerHeight = g;
29
+ h.feature("portrait", d > b);
30
+ h.feature("landscape", d < b)
31
+ }
32
+
33
+ function r() {
34
+ a.clearTimeout(u);
35
+ u = a.setTimeout(s, 100)
36
+ }
37
+ var n = a.document,
38
+ g = a.navigator,
39
+ t = a.location,
40
+ q = n.documentElement,
41
+ p = [],
42
+ c = {
43
+ screens: [240, 320, 480, 640, 768, 800, 1024, 1280,
44
+ 1440, 1680, 1920
45
+ ],
46
+ screensCss: {
47
+ gt: !0,
48
+ gte: !1,
49
+ lt: !0,
50
+ lte: !1,
51
+ eq: !1
52
+ },
53
+ browsers: [{
54
+ ie: {
55
+ min: 6,
56
+ max: 10
57
+ }
58
+ }],
59
+ browserCss: {
60
+ gt: !0,
61
+ gte: !1,
62
+ lt: !0,
63
+ lte: !1,
64
+ eq: !0
65
+ },
66
+ section: "-section",
67
+ page: "-page",
68
+ head: "head"
69
+ };
70
+ if (a.head_conf)
71
+ for (var b in a.head_conf) a.head_conf[b] !== w && (c[b] = a.head_conf[b]);
72
+ var h = a[c.head] = function () {
73
+ h.ready.apply(null, arguments)
74
+ };
75
+ h.feature = function (a, b, c) {
76
+ if (!a) return q.className += " " + p.join(" "), p = [], h;
77
+ "[object Function]" === Object.prototype.toString.call(b) && (b = b.call());
78
+ f((b ? "" : "no-") + a);
79
+ h[a] = !! b;
80
+ c || (m("no-" +
81
+ a), m(a), h.feature());
82
+ return h
83
+ };
84
+ h.feature("js", !0);
85
+ b = g.userAgent.toLowerCase();
86
+ g = /mobile|midp/.test(b);
87
+ h.feature("mobile", g, !0);
88
+ h.feature("desktop", !g, !0);
89
+ b = /(chrome|firefox)[ \/]([\w.]+)/.exec(b) || /(iphone|ipad|ipod)(?:.*version)?[ \/]([\w.]+)/.exec(b) || /(android)(?:.*version)?[ \/]([\w.]+)/.exec(b) || /(webkit|opera)(?:.*version)?[ \/]([\w.]+)/.exec(b) || /(msie) ([\w.]+)/.exec(b) || [];
90
+ g = b[1];
91
+ b = parseFloat(b[2]);
92
+ switch (g) {
93
+ case "msie":
94
+ g = "ie";
95
+ b = n.documentMode || b;
96
+ break;
97
+ case "firefox":
98
+ g = "ff";
99
+ break;
100
+ case "ipod":
101
+ case "ipad":
102
+ case "iphone":
103
+ g =
104
+ "ios";
105
+ break;
106
+ case "webkit":
107
+ g = "safari"
108
+ }
109
+ h.browser = {
110
+ name: g,
111
+ version: b
112
+ };
113
+ h.browser[g] = !0;
114
+ for (var v = 0, x = c.browsers.length; v < x; v++)
115
+ for (var i in c.browsers[v])
116
+ if (g === i) {
117
+ f(i);
118
+ for (var A = c.browsers[v][i].max, l = c.browsers[v][i].min; l <= A; l++) b > l ? (c.browserCss.gt && f("gt-" + i + l), c.browserCss.gte && f("gte-" + i + l)) : b < l ? (c.browserCss.lt && f("lt-" + i + l), c.browserCss.lte && f("lte-" + i + l)) : b === l && (c.browserCss.lte && f("lte-" + i + l), c.browserCss.eq && f("eq-" + i + l), c.browserCss.gte && f("gte-" + i + l))
119
+ } else f("no-" + i);
120
+ "ie" === g && 9 > b && k("abbr article aside audio canvas details figcaption figure footer header hgroup mark meter nav output progress section summary time video".split(" "),
121
+ function (a) {
122
+ n.createElement(a)
123
+ });
124
+ k(t.pathname.split("/"), function (a, b) {
125
+ if (2 < this.length && this[b + 1] !== w) b && f(this.slice(1, b + 1).join("-").toLowerCase() + c.section);
126
+ else {
127
+ var g = a || "index",
128
+ h = g.indexOf(".");
129
+ 0 < h && (g = g.substring(0, h));
130
+ q.id = g.toLowerCase() + c.page;
131
+ b || f("root" + c.section)
132
+ }
133
+ });
134
+ h.screen = {
135
+ height: a.screen.height,
136
+ width: a.screen.width
137
+ };
138
+ s();
139
+ var u = 0;
140
+ a.addEventListener ? a.addEventListener("resize", r, !1) : a.attachEvent("onresize", r)
141
+ })(window);
142
+ (function (a, w) {
143
+ function f(a) {
144
+ var f = a.charAt(0).toUpperCase() + a.substr(1),
145
+ a = (a + " " + r.join(f + " ") + f).split(" "),
146
+ c;
147
+ a: {
148
+ for (c in a)
149
+ if (k[a[c]] !== w) {
150
+ c = !0;
151
+ break a
152
+ }
153
+ c = !1
154
+ }
155
+ return !!c
156
+ }
157
+ var m = a.document.createElement("i"),
158
+ k = m.style,
159
+ s = " -o- -moz- -ms- -webkit- -khtml- ".split(" "),
160
+ r = ["Webkit", "Moz", "O", "ms", "Khtml"],
161
+ n = a[a.head_conf && a.head_conf.head || "head"],
162
+ g = {
163
+ gradient: function () {
164
+ k.cssText = ("background-image:" + s.join("gradient(linear,left top,right bottom,from(#9f9),to(#fff));background-image:") + s.join("linear-gradient(left top,#eee,#fff);background-image:")).slice(0, -17);
165
+ return !!k.backgroundImage
166
+ },
167
+ rgba: function () {
168
+ k.cssText = "background-color:rgba(0,0,0,0.5)";
169
+ return !!k.backgroundColor
170
+ },
171
+ opacity: function () {
172
+ return "" === m.style.opacity
173
+ },
174
+ textshadow: function () {
175
+ return "" === k.textShadow
176
+ },
177
+ multiplebgs: function () {
178
+ k.cssText = "background:url(//:),url(//:),red url(//:)";
179
+ return /(url\s*\(.*?){3}/.test(k.background)
180
+ },
181
+ boxshadow: function () {
182
+ return f("boxShadow")
183
+ },
184
+ borderimage: function () {
185
+ return f("borderImage")
186
+ },
187
+ borderradius: function () {
188
+ return f("borderRadius")
189
+ },
190
+ cssreflections: function () {
191
+ return f("boxReflect")
192
+ },
193
+ csstransforms: function () {
194
+ return f("transform")
195
+ },
196
+ csstransitions: function () {
197
+ return f("transition")
198
+ },
199
+ touch: function () {
200
+ return "ontouchstart" in a
201
+ },
202
+ retina: function () {
203
+ return 1 < a.devicePixelRatio
204
+ },
205
+ fontface: function () {
206
+ var a = n.browser.version;
207
+ switch (n.browser.name) {
208
+ case "ie":
209
+ return 9 <= a;
210
+ case "chrome":
211
+ return 13 <= a;
212
+ case "ff":
213
+ return 6 <= a;
214
+ case "ios":
215
+ return 5 <= a;
216
+ case "android":
217
+ return !1;
218
+ case "webkit":
219
+ return 5.1 <= a;
220
+ case "opera":
221
+ return 10 <= a;
222
+ default:
223
+ return !1
224
+ }
225
+ }
226
+ }, t;
227
+ for (t in g) g[t] && n.feature(t, g[t].call(), !0);
228
+ n.feature()
229
+ })(window);
230
+ (function (a, w) {
231
+ function f() {}
232
+
233
+ function m(j, a) {
234
+ if (j) {
235
+ "object" === typeof j && (j = [].slice.call(j));
236
+ for (var b = 0, c = j.length; b < c; b++) a.call(j, j[b], b)
237
+ }
238
+ }
239
+
240
+ function k(a, b) {
241
+ var e = Object.prototype.toString.call(b).slice(8, -1);
242
+ return b !== w && null !== b && e === a
243
+ }
244
+
245
+ function s(a) {
246
+ return k("Function", a)
247
+ }
248
+
249
+ function r(a) {
250
+ a = a || f;
251
+ a._done || (a(), a._done = 1)
252
+ }
253
+
254
+ function n(a) {
255
+ var b = {};
256
+ if ("object" === typeof a)
257
+ for (var e in a) a[e] && (b = {
258
+ name: e,
259
+ url: a[e]
260
+ });
261
+ else b = a.split("/"), b = b[b.length - 1], e = b.indexOf("?"), b = {
262
+ name: -1 !== e ? b.substring(0, e) : b,
263
+ url: a
264
+ };
265
+ return (a = i[b.name]) && a.url === b.url ? a : i[b.name] = b
266
+ }
267
+
268
+ function g(a) {
269
+ var a = a || i,
270
+ b;
271
+ for (b in a)
272
+ if (a.hasOwnProperty(b) && a[b].state !== y) return !1;
273
+ return !0
274
+ }
275
+
276
+ function t(a, b) {
277
+ b = b || f;
278
+ a.state === y ? b() : a.state === D ? d.ready(a.name, b) : a.state === C ? a.onpreload.push(function () {
279
+ t(a, b)
280
+ }) : (a.state = D, q(a, function () {
281
+ a.state = y;
282
+ b();
283
+ m(x[a.name], function (a) {
284
+ r(a)
285
+ });
286
+ u && g() && m(x.ALL, function (a) {
287
+ r(a)
288
+ })
289
+ }))
290
+ }
291
+
292
+ function q(j, c) {
293
+ var c = c || f,
294
+ e;
295
+ /\.css[^\.]*$/.test(j.url) ? (e = b.createElement("link"), e.type = "text/" + (j.type || "css"), e.rel = "stylesheet",
296
+ e.href = j.url) : (e = b.createElement("script"), e.type = "text/" + (j.type || "javascript"), e.src = j.url);
297
+ e.onload = e.onreadystatechange = function (j) {
298
+ j = j || a.event;
299
+ if ("load" === j.type || /loaded|complete/.test(e.readyState) && (!b.documentMode || 9 > b.documentMode)) e.onload = e.onreadystatechange = e.onerror = null, c()
300
+ };
301
+ e.onerror = function () {
302
+ e.onload = e.onreadystatechange = e.onerror = null;
303
+ c()
304
+ };
305
+ e.async = !1;
306
+ e.defer = !1;
307
+ var d = b.head || b.getElementsByTagName("head")[0];
308
+ d.insertBefore(e, d.lastChild)
309
+ }
310
+
311
+ function p() {
312
+ b.body ? u || (u = !0, m(h, function (a) {
313
+ r(a)
314
+ })) :
315
+ (a.clearTimeout(d.readyTimeout), d.readyTimeout = a.setTimeout(p, 50))
316
+ }
317
+
318
+ function c() {
319
+ b.addEventListener ? (b.removeEventListener("DOMContentLoaded", c, !1), p()) : "complete" === b.readyState && (b.detachEvent("onreadystatechange", c), p())
320
+ }
321
+ var b = a.document,
322
+ h = [],
323
+ v = [],
324
+ x = {}, i = {}, A = "async" in b.createElement("script") || "MozAppearance" in b.documentElement.style || a.opera,
325
+ l, u, B = a.head_conf && a.head_conf.head || "head",
326
+ d = a[B] = a[B] || function () {
327
+ d.ready.apply(null, arguments)
328
+ }, C = 1,
329
+ D = 3,
330
+ y = 4;
331
+ d.load = A ? function () {
332
+ var a = arguments,
333
+ b = a[a.length -
334
+ 1],
335
+ e = {};
336
+ s(b) || (b = null);
337
+ m(a, function (c, d) {
338
+ c !== b && (c = n(c), e[c.name] = c, t(c, b && d === a.length - 2 ? function () {
339
+ g(e) && r(b)
340
+ } : null))
341
+ });
342
+ return d
343
+ } : function () {
344
+ var a = arguments,
345
+ b = [].slice.call(a, 1),
346
+ c = b[0];
347
+ if (!l) return v.push(function () {
348
+ d.load.apply(null, a)
349
+ }), d;
350
+ c ? (m(b, function (a) {
351
+ if (!s(a)) {
352
+ var b = n(a);
353
+ b.state === w && (b.state = C, b.onpreload = [], q({
354
+ url: b.url,
355
+ type: "cache"
356
+ }, function () {
357
+ b.state = 2;
358
+ m(b.onpreload, function (a) {
359
+ a.call()
360
+ })
361
+ }))
362
+ }
363
+ }), t(n(a[0]), s(c) ? c : function () {
364
+ d.load.apply(null, b)
365
+ })) : t(n(a[0]));
366
+ return d
367
+ };
368
+ d.js = d.load;
369
+ d.test =
370
+ function (a, b, c, g) {
371
+ a = "object" === typeof a ? a : {
372
+ test: a,
373
+ success: b ? k("Array", b) ? b : [b] : !1,
374
+ failure: c ? k("Array", c) ? c : [c] : !1,
375
+ callback: g || f
376
+ };
377
+ (b = !! a.test) && a.success ? (a.success.push(a.callback), d.load.apply(null, a.success)) : !b && a.failure ? (a.failure.push(a.callback), d.load.apply(null, a.failure)) : g();
378
+ return d
379
+ };
380
+ d.ready = function (a, c) {
381
+ if (a === b) return u ? r(c) : h.push(c), d;
382
+ s(a) && (c = a, a = "ALL");
383
+ if ("string" !== typeof a || !s(c)) return d;
384
+ var e = i[a];
385
+ if (e && e.state === y || "ALL" === a && g() && u) return r(c), d;
386
+ (e = x[a]) ? e.push(c) : x[a] = [c];
387
+ return d
388
+ };
389
+ d.ready(b, function () {
390
+ g() && m(x.ALL, function (a) {
391
+ r(a)
392
+ });
393
+ d.feature && d.feature("domloaded", !0)
394
+ });
395
+ if ("complete" === b.readyState) p();
396
+ else if (b.addEventListener) b.addEventListener("DOMContentLoaded", c, !1), a.addEventListener("load", p, !1);
397
+ else {
398
+ b.attachEvent("onreadystatechange", c);
399
+ a.attachEvent("onload", p);
400
+ var z = !1;
401
+ try {
402
+ z = null == a.frameElement && b.documentElement
403
+ } catch (F) {}
404
+ z && z.doScroll && function E() {
405
+ if (!u) {
406
+ try {
407
+ z.doScroll("left")
408
+ } catch (b) {
409
+ a.clearTimeout(d.readyTimeout);
410
+ d.readyTimeout = a.setTimeout(E, 50);
411
+ return
412
+ }
413
+ p()
414
+ }
415
+ }()
416
+ }
417
+ setTimeout(function () {
418
+ l = !0;
419
+ m(v, function (a) {
420
+ a()
421
+ })
422
+ }, 300)
423
+ })(window);
@@ -0,0 +1,148 @@
1
+ //= require head
2
+ //= require spin
3
+ var phrasing_setup = function(){
4
+
5
+ /// INITIALIZE THE BUBBLE
6
+ head.js( "<%= asset_path 'editor.js' %>",
7
+ function(){
8
+ editor.init();
9
+ });
10
+
11
+ // SPINNER
12
+ var opts = {
13
+ lines: 9, // The number of lines to draw
14
+ length: 0, // The length of each line
15
+ width: 7, // The line thickness
16
+ radius: 12, // The radius of the inner circle
17
+ corners: 1, // Corner roundness (0..1)
18
+ rotate: 0, // The rotation offset
19
+ direction: 1, // 1: clockwise, -1: counterclockwise
20
+ color: '#FFF', // #rgb or #rrggbb or array of colors
21
+ speed: 1.9, // Rounds per second
22
+ trail: 58, // Afterglow percentage
23
+ shadow: false, // Whether to render a shadow
24
+ hwaccel: false, // Whether to use hardware acceleration
25
+ className: 'spinner', // The CSS class to assign to the spinner
26
+ zIndex: 2e9, // The z-index (defaults to 2000000000)
27
+ top: 'auto', // Top position relative to parent in px
28
+ left: 'auto' // Left position relative to parent in px
29
+ };
30
+
31
+ var target = document.getElementById('phrasing-spinner');
32
+ var spinner = new Spinner(opts).spin(target);
33
+ spinner.stop();
34
+
35
+ // Hash size function
36
+
37
+ Object.size = function(obj) {
38
+ var size = 0, key;
39
+ for (key in obj) {
40
+ if (obj.hasOwnProperty(key)) size++;
41
+ }
42
+ return size;
43
+ };
44
+
45
+
46
+
47
+ ///ON TEXTCHANGE TRIGGER AJAX
48
+ var trigger_binded_events_for_phrasable_class = 1;
49
+ var timer = {}
50
+ var timer_status = {}
51
+
52
+ $('.phrasable').on('DOMNodeInserted DOMNodeRemoved DOMCharacterDataModified', function(e){
53
+
54
+ $('#phrasing-edit-mode-bubble #phrasing-spinner p').css("color", "red").text("Currently editing..")
55
+
56
+ if (trigger_binded_events_for_phrasable_class == 1){
57
+
58
+ var record = this;
59
+
60
+ // console.log(timer)
61
+
62
+ clearTimeout(timer[$(record).data("url")]);
63
+ timer_status[$(record).data("url")] = 0;
64
+
65
+ timer[$(record).data("url")] = setTimeout(function(){
66
+ savePhraseViaAjax(record);
67
+ delete timer_status[$(record).data("url")]
68
+ },2500)
69
+ timer_status[$(record).data("url")] = 1;
70
+ }
71
+
72
+ });
73
+
74
+ ///AJAX REQUEST
75
+ function savePhraseViaAjax(record){
76
+
77
+ var url = $(record).data("url");
78
+
79
+ var content = record.innerHTML;
80
+
81
+ if(content.length == 0){
82
+ content= "Empty"
83
+ }
84
+
85
+ $.ajax({
86
+ type: "PUT",
87
+ url: url,
88
+ data: { new_value: content },
89
+ beforeSend: function(){
90
+ spinner.spin(target);
91
+ },
92
+ success: function(e){
93
+ spinner.stop();
94
+
95
+ console.log("I've sent a ajax request: " + content);
96
+
97
+ trigger_binded_events_for_phrasable_class = 0;
98
+ if(content == "Empty"){
99
+ $('span.phrasable[data-url="'+ url +'"]').html(content)
100
+ }else{
101
+ $('span.phrasable[data-url="'+ url +'"]').not(record).html(content)
102
+ }
103
+ trigger_binded_events_for_phrasable_class = 1;
104
+
105
+ if (Object.size(timer_status) == 0){
106
+ $('#phrasing-edit-mode-bubble #phrasing-spinner p').css("color", "green").text("Everything saved.")
107
+ }
108
+ }})
109
+ }
110
+
111
+ // EDIT MODE SWITCH MODE BUTTON
112
+ $('#edit-mode-onoffswitch').on('change', function(){
113
+ if(this.checked){
114
+ $('.phrasable').addClass("phrasable_on").attr("contenteditable", "true");
115
+ $.cookie("editing_mode", "true");
116
+ }
117
+ else{
118
+ $('.phrasable').removeClass("phrasable_on").attr("contenteditable", "false");
119
+ $.cookie("editing_mode", "false");
120
+ }
121
+ });
122
+
123
+ if($.cookie("editing_mode") == null){
124
+ $.cookie("editing_mode", "true");
125
+ $('#edit-mode-onoffswitch').prop('checked', true)
126
+ }
127
+ else if($.cookie("editing_mode") == "true"){
128
+ $('#edit-mode-onoffswitch').prop('checked', true)
129
+ }else{
130
+ $('#edit-mode-onoffswitch').prop('checked', false)
131
+ }
132
+
133
+ // Information icon for the edit mode bubble
134
+
135
+ $('#phrasing-info-icon-container, #phrasing-info-container').on('click',function(){
136
+ if($('#phrasing-info-container').is(':visible')){
137
+ $('#phrasing-edit-mode-bubble').animate({height: 180}, 200, function(){
138
+ $('#phrasing-info-container').hide()
139
+ })
140
+ }else{
141
+ $('#phrasing-info-container').show();
142
+ $('#phrasing-edit-mode-bubble').animate({height: 255}, 200)
143
+ }
144
+ });
145
+ };
146
+
147
+ $(document).ready(phrasing_setup)
148
+ $(document).on('page:load', phrasing_setup)