ecrire 0.21.0 → 0.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b9187d5d3cf47bd6d98975d2c7e98f78fca7e724
4
- data.tar.gz: bb54f17491247dfe317ca7ba9ef3fe78089936c7
3
+ metadata.gz: 1ca953837db65f9e27113c5399ce13c2353939bf
4
+ data.tar.gz: 2289e12808f0202798eb783bbd30fd055cbbc8e6
5
5
  SHA512:
6
- metadata.gz: d7887948635cf02da8caaed5c802c34e2f8ca0baa3e6d53f8cf04caccec39444a542a67a45a9b2026b739b9ca5ff290544f0908e9b3fefb96b4724e2ab8c9d60
7
- data.tar.gz: b12bfee9bd7bde93f8d37b514df86f01add1c972884998af6fa05a930aae3e610eee4b1f9000fe1c5ac281940dc0b42fa9f40bc288498c617c2741965e1375d5
6
+ metadata.gz: e64e5dd7ce4c0aba279e3385837b6e3d6057e29c6f2db4f221f0da51c59780575dbe872b82366a0d97e7fc73c9ac5a612f6ca44633f2558f662ef47b398ae2e8
7
+ data.tar.gz: e208f922deb272f90de0d89df47c7299c10a33ff267109589e0d1f83cdcc43eb19bde09e8a299a98b996fe9d21b0fec6234ec52caeaa9e2ccf2fc3879215ccc8
@@ -260,11 +260,21 @@ Joint.bind 'Editor.Content', class @Editor
260
260
 
261
261
 
262
262
  same: (node1, node2) =>
263
+ node1 = node1.cloneNode(true)
264
+ node2 = node2.cloneNode(true)
265
+
266
+ for el in node1.querySelectorAll('[contenteditable=false]')
267
+ el.remove()
268
+
269
+ for el in node2.querySelectorAll('[contenteditable=false]')
270
+ el.remove()
271
+
263
272
  node1.nodeName == node2.nodeName &&
264
273
  node1.innerHTML.trim() == node2.innerHTML.trim()
265
274
 
266
275
 
267
276
 
277
+
268
278
  parse: (fragment) =>
269
279
  for p in @parsers
270
280
  line = fragment.firstChild
@@ -74,7 +74,6 @@ Editor.Extensions.push class ClipBoard
74
74
 
75
75
 
76
76
  insert: (texts, sel) =>
77
-
78
77
  node = sel.anchorNode
79
78
  str = node.textContent
80
79
  text = texts.map((t) ->
@@ -89,7 +88,9 @@ Editor.Extensions.push class ClipBoard
89
88
  while line.parentElement != @editor.element()
90
89
  line = line.parentElement
91
90
 
92
- offset = @nodeOffset(node,line) + sel.anchorOffset + text.length
91
+ offset = sel.anchorOffset + text.length
92
+ if node != line
93
+ offset += @nodeOffset(node, line)
93
94
 
94
95
  fragment = @editor.parse(@editor.cloneNodesFrom(line))
95
96
 
@@ -99,15 +100,13 @@ Editor.Extensions.push class ClipBoard
99
100
  cursor.update(@editor.walker(cursor.focus(lines[0])), true)
100
101
 
101
102
  nodeOffset: (node, line) ->
102
- if !line.contains(node)
103
- raise "Looking for a node that is not inside the given line"
104
- return
105
-
106
103
  offset = 0
107
104
 
108
105
  for n in line.childNodes
109
106
  if n == node
110
107
  break
108
+ else if n.childNodes.length > 0
109
+ offset += @nodeOffset(node, n)
111
110
  else
112
111
  offset += n.textContent.length
113
112
 
@@ -3,6 +3,7 @@ Joint.bind 'Editor.Save', class
3
3
  @button = @element().querySelector('button')
4
4
  @time = @element().querySelector('div.update > p')
5
5
 
6
+ @on 'keydown', document, @shouldSave
6
7
  @on 'Editor:loaded', document, @cache
7
8
  @on 'Editor:updated', document, @update
8
9
  @on 'posts:update', document, @saved
@@ -32,11 +33,36 @@ Joint.bind 'Editor.Save', class
32
33
  cache
33
34
  @cache()
34
35
 
36
+ dirty: =>
37
+ @cache()? && @cache() != PostBody.instance.toString()
38
+
39
+ shouldSave: (e) =>
40
+ if e.metaKey isnt true || e.which isnt 83
41
+ return
42
+
43
+ e.preventDefault()
44
+ e.stopPropagation()
45
+
46
+ if @dirty()
47
+ @save(e)
48
+ else
49
+ @nudge()
50
+
51
+ nudge: =>
52
+ button = document.querySelector("[as='Editor.Save'] button")
53
+ clean = ->
54
+ button.classList.remove('nudge')
55
+
56
+ button.addEventListener 'animationend', clean
57
+ button.addEventListener 'webkitAnimationEnd', clean
58
+ button.classList.add('nudge')
59
+
35
60
  save: (e) =>
36
61
  e.preventDefault()
37
62
  e.stopPropagation()
38
63
 
39
- xhr = new Joint.XHR(e.target.form)
64
+ form = document.querySelector("[as='Editor.Save']")
65
+ xhr = new Joint.XHR(form)
40
66
  xhr.data.set('post[content]', PostBody.instance.toString())
41
67
  xhr.data.set('context', 'content')
42
68
  xhr.send()
@@ -48,11 +74,9 @@ Joint.bind 'Editor.Save', class
48
74
  @cache(true)
49
75
 
50
76
  update: (e) =>
51
- return unless @cache()?
52
- if @cache() != PostBody.instance.toString()
77
+ if @dirty()
53
78
  @button.removeAttribute('disabled')
54
79
  @button.textContent = @button.getAttribute('dirty')
55
80
  else
56
81
  @button.setAttribute('disabled', 'disabled')
57
82
  @button.textContent = @button.getAttribute('persisted')
58
-
@@ -6,27 +6,29 @@ body.edit.posts > main > section {
6
6
  padding-bottom: 10em;
7
7
 
8
8
  h1 {
9
- font-size: 2.6em;
9
+ font-size: 2.4em;
10
10
  }
11
11
 
12
12
  h2 {
13
- font-size: 2.3em;
13
+ font-size: 2.1em;
14
14
  }
15
15
 
16
16
  h3 {
17
- font-size: 2.0em;
17
+ font-size: 1.8em;
18
18
  }
19
19
 
20
20
  h4 {
21
- font-size: 1.7em;
21
+ font-size: 1.6em;
22
22
  }
23
23
 
24
24
  h5 {
25
- font-size: 1.6em;
25
+ font-weight: bold;
26
+ font-size: 1.4em;
26
27
  }
27
28
 
28
29
  h6 {
29
- font-size: 1.3em;
30
+ font-weight: bold;
31
+ font-size: 1.2em;
30
32
  }
31
33
 
32
34
  & > *, & > ul > li, & > ol > li {
@@ -29,6 +29,11 @@ body.posts > main > section > div.save {
29
29
  &:hover:not([disabled]) {
30
30
  background: #68B2A7;
31
31
  }
32
+
33
+ &.nudge {
34
+ @include animation(nudge 0.1s ease);
35
+ @include animation-iteration-count(2);
36
+ }
32
37
  }
33
38
 
34
39
  div.update {
@@ -42,3 +47,24 @@ body.posts > main > section > div.save {
42
47
  }
43
48
  }
44
49
 
50
+ @include keyframes(nudge) {
51
+ 0% {
52
+ margin-left: 0;
53
+ margin-right: 0;
54
+ }
55
+
56
+ 25% {
57
+ margin-left: 10px;
58
+ margin-right: 0;
59
+ }
60
+
61
+ 75% {
62
+ margin-left: 0;
63
+ margin-right: 10px;
64
+ }
65
+
66
+ 100% {
67
+ margin-left: 0;
68
+ margin-right: 0;
69
+ }
70
+ }
@@ -3,10 +3,3 @@
3
3
  @import 'shared/**/*';
4
4
  @import 'admin/navigation';
5
5
  @import 'sessions';
6
-
7
- ol, ul {
8
- list-style-type: none;
9
- margin: 0;
10
- padding: 0;
11
- }
12
-
@@ -10,16 +10,16 @@ module Admin
10
10
  href: admin_post_path(@post.id) do |div|
11
11
 
12
12
  if Rails.application.secrets.has_key?(:s3)
13
- div[:bucket] = Rails.application.secrets.s3['bucket'],
14
- div[:access_key] = Rails.application.secrets.s3['access_key'],
15
- div[:signature] = image_form_signature(image_form_policy(@post)),
13
+ div[:bucket] = Rails.application.secrets.s3['bucket']
14
+ div[:access_key] = Rails.application.secrets.s3['access_key']
15
+ div[:signature] = image_form_signature(image_form_policy(@post))
16
16
  div[:policy] = image_form_policy(@post)
17
17
  if Rails.application.secrets.s3.has_key?('namespace')
18
18
  div['namespace'] = Rails.application.secrets.s3['namespace']
19
19
  end
20
20
  end
21
21
 
22
- post.content
22
+ h(post.content)
23
23
  end
24
24
  end
25
25
  end
@@ -17,9 +17,14 @@ ActiveRecord::Schema.define(version: 20150120093481) do
17
17
  enable_extension "plpgsql"
18
18
  enable_extension "hstore"
19
19
 
20
+ create_table "abtests", force: :cascade do |t|
21
+ t.datetime "created_at"
22
+ t.datetime "updated_at"
23
+ end
24
+
20
25
  create_table "images", force: :cascade do |t|
21
- t.string "url"
22
- t.string "key"
26
+ t.string "url", limit: 255
27
+ t.string "key", limit: 255
23
28
  t.integer "post_id"
24
29
  t.datetime "created_at"
25
30
  t.datetime "updated_at"
@@ -27,7 +32,7 @@ ActiveRecord::Schema.define(version: 20150120093481) do
27
32
  end
28
33
 
29
34
  create_table "labels", force: :cascade do |t|
30
- t.string "name", null: false
35
+ t.string "name", limit: 255, null: false
31
36
  t.datetime "created_at"
32
37
  t.datetime "updated_at"
33
38
  end
@@ -37,15 +42,15 @@ ActiveRecord::Schema.define(version: 20150120093481) do
37
42
  create_table "partials", force: :cascade do |t|
38
43
  t.datetime "created_at"
39
44
  t.datetime "updated_at"
40
- t.string "title", null: false
45
+ t.string "title", limit: 255, null: false
41
46
  t.text "content"
42
47
  t.text "stylesheet"
43
48
  t.text "javascript"
44
49
  end
45
50
 
46
51
  create_table "posts", force: :cascade do |t|
47
- t.string "title", null: false
48
- t.string "slug", null: false
52
+ t.string "title", limit: 255, null: false
53
+ t.string "slug", limit: 255, null: false
49
54
  t.text "content"
50
55
  t.text "stylesheet"
51
56
  t.datetime "published_at"
@@ -60,8 +65,8 @@ ActiveRecord::Schema.define(version: 20150120093481) do
60
65
  add_index "posts", ["title"], name: "index_posts_on_title", unique: true, using: :btree
61
66
 
62
67
  create_table "users", force: :cascade do |t|
63
- t.string "email", null: false
64
- t.string "encrypted_password", null: false
68
+ t.string "email", limit: 255, null: false
69
+ t.string "encrypted_password", limit: 255, null: false
65
70
  t.datetime "created_at"
66
71
  t.datetime "updated_at"
67
72
  end
@@ -1,6 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'ecrire', path: '~/Develop/ecrire'
3
+ gem 'ecrire', git: 'https://github.com/pothibo/ecrire'
4
4
 
5
5
  group :required do
6
6
  gem 'rails', '~> 4.2'
@@ -1,3 +1,3 @@
1
1
  module Ecrire
2
- VERSION = '0.21.0'
2
+ VERSION = '0.22.1'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ecrire
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.21.0
4
+ version: 0.22.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pier-Olivier Thibault
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-28 00:00:00.000000000 Z
11
+ date: 2015-03-08 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Blog engine on Rails
14
14
  email: pothibo@gmail.com
@@ -271,7 +271,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
271
271
  version: '0'
272
272
  requirements: []
273
273
  rubyforge_project:
274
- rubygems_version: 2.2.2
274
+ rubygems_version: 2.0.14
275
275
  signing_key:
276
276
  specification_version: 4
277
277
  summary: Blog engine