dante-editor-seo 0.0.13

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.
Files changed (105) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +40 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +4 -0
  5. data/Gemfile +23 -0
  6. data/Gemfile.lock +140 -0
  7. data/Procfile +1 -0
  8. data/README.md +187 -0
  9. data/ROADMAP.md +10 -0
  10. data/TODO.md +30 -0
  11. data/app/assets/fonts/dante/dante.eot +0 -0
  12. data/app/assets/fonts/dante/dante.svg +14 -0
  13. data/app/assets/fonts/dante/dante.ttf +0 -0
  14. data/app/assets/fonts/dante/dante.woff +0 -0
  15. data/app/assets/fonts/dante/fontello.eot +0 -0
  16. data/app/assets/fonts/dante/fontello.svg +36 -0
  17. data/app/assets/fonts/dante/fontello.ttf +0 -0
  18. data/app/assets/fonts/dante/fontello.woff +0 -0
  19. data/app/assets/images/dante/media-loading-placeholder.png +0 -0
  20. data/app/assets/javascripts/dante/dante.js.coffee.erb +10 -0
  21. data/app/assets/javascripts/dante/editor.js.coffee +1250 -0
  22. data/app/assets/javascripts/dante/menu.js.coffee +216 -0
  23. data/app/assets/javascripts/dante/popover.js.coffee +75 -0
  24. data/app/assets/javascripts/dante/tooltip.js.coffee +82 -0
  25. data/app/assets/javascripts/dante/tooltip_widget.js.coffee +10 -0
  26. data/app/assets/javascripts/dante/tooltip_widgets/embed.js.coffee +60 -0
  27. data/app/assets/javascripts/dante/tooltip_widgets/extract.js.coffee +64 -0
  28. data/app/assets/javascripts/dante/tooltip_widgets/uploader.js.coffee +248 -0
  29. data/app/assets/javascripts/dante/utils.js.coffee +235 -0
  30. data/app/assets/javascripts/dante/view.js.coffee +101 -0
  31. data/app/assets/javascripts/dante.js +12 -0
  32. data/app/assets/stylesheets/dante/_animations.scss +54 -0
  33. data/app/assets/stylesheets/dante/_caption.scss +52 -0
  34. data/app/assets/stylesheets/dante/_debug.scss +11 -0
  35. data/app/assets/stylesheets/dante/_fonts.scss +17 -0
  36. data/app/assets/stylesheets/dante/_graf.scss +238 -0
  37. data/app/assets/stylesheets/dante/_icons.scss +57 -0
  38. data/app/assets/stylesheets/dante/_media.scss +39 -0
  39. data/app/assets/stylesheets/dante/_menu.scss +153 -0
  40. data/app/assets/stylesheets/dante/_needsorder.scss +209 -0
  41. data/app/assets/stylesheets/dante/_popover.scss +134 -0
  42. data/app/assets/stylesheets/dante/_post.scss +69 -0
  43. data/app/assets/stylesheets/dante/_scaffold.scss +20 -0
  44. data/app/assets/stylesheets/dante/_tooltip.scss +131 -0
  45. data/app/assets/stylesheets/dante/_utilities.scss +55 -0
  46. data/app/assets/stylesheets/dante/_variables.scss +46 -0
  47. data/app/assets/stylesheets/dante.scss +18 -0
  48. data/bower.json +44 -0
  49. data/config.rb +86 -0
  50. data/config.ru +42 -0
  51. data/dante-editor.gemspec +19 -0
  52. data/dist/css/dante-editor.css +1116 -0
  53. data/dist/fonts/dante/dante.eot +0 -0
  54. data/dist/fonts/dante/dante.svg +14 -0
  55. data/dist/fonts/dante/dante.ttf +0 -0
  56. data/dist/fonts/dante/dante.woff +0 -0
  57. data/dist/fonts/dante/fontello.eot +0 -0
  58. data/dist/fonts/dante/fontello.svg +36 -0
  59. data/dist/fonts/dante/fontello.ttf +0 -0
  60. data/dist/fonts/dante/fontello.woff +0 -0
  61. data/dist/images/dante/media-loading-placeholder.png +0 -0
  62. data/dist/js/dante-editor.js +2878 -0
  63. data/lib/dante-editor/rails.rb +4 -0
  64. data/lib/dante-editor/version.rb +5 -0
  65. data/lib/dante-editor.rb +5 -0
  66. data/license.md +22 -0
  67. data/rakefile +2 -0
  68. data/source/assets/images/dante-editor-logo.png +0 -0
  69. data/source/assets/images/github-logo.png +0 -0
  70. data/source/assets/javascripts/all.js +3 -0
  71. data/source/assets/javascripts/dante-editor.js +1 -0
  72. data/source/assets/javascripts/deps.js +4 -0
  73. data/source/assets/javascripts/examples/custom_toolbar.js.coffee +30 -0
  74. data/source/assets/javascripts/spec.js +2 -0
  75. data/source/assets/javascripts/specs/cleaner.js.coffee +8 -0
  76. data/source/assets/javascripts/specs/dante_view.js.coffee +74 -0
  77. data/source/assets/javascripts/specs/editor.js.coffee +78 -0
  78. data/source/assets/stylesheets/_layout.scss +51 -0
  79. data/source/assets/stylesheets/_scaffold.scss +8 -0
  80. data/source/assets/stylesheets/_tooltips.scss +216 -0
  81. data/source/assets/stylesheets/all.css.scss +5 -0
  82. data/source/assets/stylesheets/dante-editor.css.scss +1 -0
  83. data/source/assets/stylesheets/normalize.css +375 -0
  84. data/source/custom_toolbar.erb +29 -0
  85. data/source/embeds.html.erb +27 -0
  86. data/source/icons/dante.json +143 -0
  87. data/source/icons/embed.svg +13 -0
  88. data/source/icons/image.svg +13 -0
  89. data/source/icons/plus.svg +13 -0
  90. data/source/icons/video.svg +13 -0
  91. data/source/index.html.erb +18 -0
  92. data/source/layouts/layout.erb +26 -0
  93. data/source/layouts/spec.html.erb +22 -0
  94. data/source/lists.html.erb +18 -0
  95. data/source/partials/_content.erb +6 -0
  96. data/source/partials/_example_1.erb +45 -0
  97. data/source/partials/_example_2.erb +32 -0
  98. data/source/partials/_example_3.erb +4 -0
  99. data/source/partials/_lists.erb +13 -0
  100. data/source/partials/_readme.markdown +24 -0
  101. data/source/partials/test/_example_1.erb +39 -0
  102. data/source/tests/dante_view.html.erb +11 -0
  103. data/source/tests/index.html.erb +39 -0
  104. data/tmp/.gitkeep +0 -0
  105. metadata +151 -0
@@ -0,0 +1,248 @@
1
+ utils = Dante.utils
2
+
3
+ class Dante.View.TooltipWidget.Uploader extends Dante.View.TooltipWidget
4
+
5
+ initialize: (opts={})->
6
+ #super
7
+ #@name = "menu-image"
8
+ @icon = opts.icon || "icon-image"
9
+ @title = opts.title || "Add an image"
10
+ @action = opts.action || "menu-image"
11
+ @current_editor = opts.current_editor
12
+
13
+ handleClick: (ev)->
14
+ @imageSelect(ev)
15
+
16
+ insertTemplate: ()->
17
+ "<figure contenteditable='false' class='graf graf--figure is-defaultValue' name='#{utils.generateUniqueName()}' tabindex='0'>
18
+ <div style='' class='aspectRatioPlaceholder is-locked'>
19
+ <div style='padding-bottom: 100%;' class='aspect-ratio-fill'></div>
20
+ <img src='' data-height='' data-width='' data-image-id='' class='graf-image' data-delayed-src=''>
21
+ </div>
22
+ <figcaption contenteditable='true' data-default-value='Type caption for image (optional)' class='imageCaption'>
23
+ <span class='defaultValue'>Type caption for image (optional)</span>
24
+ <br>
25
+ </figcaption>
26
+ </figure>"
27
+
28
+ #UPLOADER
29
+ #replace existing img tag , and wrap it in insertTamplate
30
+ #TODO: take the url and upload it
31
+ uploadExistentImage: (image_element, opts = {})->
32
+
33
+ utils.log ("process image here!")
34
+ tmpl = $(@insertTemplate())
35
+ tmpl.find("img").attr('src', @current_editor.default_loading_placeholder )
36
+ #is a child element or a first level element ?
37
+
38
+ if $(image_element).parents(".graf").length > 0
39
+ #return if its already wrapped in graf--figure
40
+ if $(image_element).parents(".graf").hasClass("graf--figure")
41
+ return
42
+ utils.log "UNO"
43
+ tmpl.insertBefore( $(image_element).parents(".graf") )
44
+ node = @current_editor.getNode()
45
+ if node
46
+ @current_editor.preCleanNode($(node))
47
+ @current_editor.addClassesToElement(node)
48
+ else
49
+ utils.log "DOS"
50
+ img = $(image_element).parentsUntil(".section-inner").first()
51
+ $(img).replaceWith(tmpl)
52
+
53
+ utils.log $("[name='#{tmpl.attr('name')}']").attr("name")
54
+ @replaceImg(image_element, $("[name='#{tmpl.attr('name')}']"))
55
+
56
+ #in case we found that graf--image is nested element, unwrap * nested times
57
+ n = $("[name='#{tmpl.attr('name')}']").parentsUntil(".section-inner").length
58
+ unless n is 0
59
+ for i in [0..n-1] by 1
60
+ $("[name='#{tmpl.attr('name')}']").unwrap()
61
+
62
+ utils.log "FIG"
63
+ #utils.log $("[name='#{tmpl.attr('name')}']").attr("name")
64
+
65
+ replaceImg: (image_element, figure)->
66
+ utils.log figure.attr("name")
67
+ utils.log figure
68
+ $(image_element).remove()
69
+ img = new Image()
70
+ img.src = image_element.src
71
+ self = this
72
+ img.onload = ()->
73
+ utils.log "replace image with loaded info"
74
+ utils.log figure.attr("name")
75
+ utils.log(this.width + 'x' + this.height);
76
+
77
+ ar = self.getAspectRatio(this.width, this.height)
78
+ #debugger
79
+ figure.find(".aspectRatioPlaceholder").css
80
+ 'max-width': ar.width
81
+ 'max-height': ar.height
82
+
83
+ figure.find(".graf-image").attr
84
+ "data-height": this.height
85
+ "data-width": this.width
86
+
87
+ figure.find(".aspect-ratio-fill").css
88
+ "padding-bottom": "#{ar.ratio}%"
89
+
90
+ #TODO: upload file to server
91
+ #@uploadFile file, replaced_node
92
+
93
+ figure.find("img").attr("src", image_element.src)
94
+
95
+ displayAndUploadImages: (file)->
96
+ @displayCachedImage file
97
+
98
+ imageSelect: (ev)->
99
+ $selectFile = $('<input type="file" multiple="multiple">').click()
100
+ self = @
101
+ $selectFile.change ()->
102
+ t = this
103
+ self.uploadFiles(t.files)
104
+
105
+ displayCachedImage: (file)->
106
+ @current_editor.tooltip_view.hide()
107
+
108
+ reader = new FileReader()
109
+ reader.onload = (e)=>
110
+ img = new Image
111
+ img.src = e.target.result
112
+ node = @current_editor.getNode()
113
+ self = this
114
+ img.onload = ()->
115
+ new_tmpl = $(self.insertTemplate())
116
+
117
+ replaced_node = $( new_tmpl ).insertBefore($(node))
118
+
119
+ img_tag = new_tmpl.find('img.graf-image').attr('src', e.target.result)
120
+ img_tag.height = this.height
121
+ img_tag.width = this.width
122
+
123
+ utils.log "UPLOADED SHOW FROM CACHE"
124
+
125
+ ar = self.getAspectRatio(this.width, this.height)
126
+
127
+ replaced_node.find(".aspectRatioPlaceholder").css
128
+ 'max-width': ar.width
129
+ 'max-height': ar.height
130
+
131
+ replaced_node.find(".graf-image").attr
132
+ "data-height": this.height
133
+ "data-width": this.width
134
+
135
+ replaced_node.find(".aspect-ratio-fill").css
136
+ "padding-bottom": "#{ar.ratio}%"
137
+
138
+ self.uploadFile file, replaced_node
139
+
140
+ reader.readAsDataURL(file)
141
+
142
+ getAspectRatio: (w , h)->
143
+ maxWidth = 700
144
+ maxHeight = 700
145
+ ratio = 0
146
+ width = w # Current image width
147
+ height = h # Current image height
148
+
149
+ # Check if the current width is larger than the max
150
+ if width > maxWidth
151
+ ratio = maxWidth / width # get ratio for scaling image
152
+ height = height * ratio # Reset height to match scaled image
153
+ width = width * ratio # Reset width to match scaled image
154
+
155
+ # Check if current height is larger than max
156
+ else if height > maxHeight
157
+ ratio = maxHeight / height # get ratio for scaling image
158
+ width = width * ratio # Reset width to match scaled image
159
+ height = height * ratio # Reset height to match scaled image
160
+
161
+ fill_ratio = height / width * 100
162
+ result = { width: width, height: height, ratio: fill_ratio }
163
+ utils.log result
164
+ result
165
+
166
+ formatData: (file, upload_params)->
167
+ formData = new FormData()
168
+ formData.append('file', file)
169
+ formData.append('upload_params', upload_params)
170
+ return formData
171
+
172
+ uploadFiles: (files)=>
173
+ acceptedTypes =
174
+ "image/png": true
175
+ "image/jpeg": true
176
+ "image/gif": true
177
+
178
+ i = 0
179
+ while i < files.length
180
+ file = files[i]
181
+ if acceptedTypes[file.type] is true
182
+ $(@placeholder).append "<progress class=\"progress\" min=\"0\" max=\"100\" value=\"0\">0</progress>"
183
+ @displayAndUploadImages(file)
184
+ i++
185
+
186
+ uploadFile: (file, node)=>
187
+ n = node
188
+ handleUp = (jqxhr)=>
189
+ @uploadCompleted jqxhr, n
190
+
191
+ $.ajax
192
+ type: "post"
193
+ url: @current_editor.upload_url
194
+ xhr: =>
195
+ xhr = new XMLHttpRequest()
196
+ xhr.upload.onprogress = @updateProgressBar
197
+ xhr
198
+ cache: false
199
+ contentType: false
200
+
201
+ success: (response) =>
202
+ response = @current_editor.upload_callback(response) if @current_editor.upload_callback
203
+ handleUp(response)
204
+ return
205
+ error: (jqxhr)=>
206
+ utils.log("ERROR: got error uploading file #{jqxhr.responseText}")
207
+
208
+ processData: false
209
+ data: @formatData(file, @upload_params)
210
+
211
+ updateProgressBar: (e)=>
212
+ $progress = $('.progress:first', this.$el)
213
+ complete = ""
214
+
215
+ if (e.lengthComputable)
216
+ complete = e.loaded / e.total * 100
217
+ complete = complete ? complete : 0
218
+ #$progress.attr('value', complete)
219
+ #$progress.html(complete)
220
+ utils.log "complete"
221
+ utils.log complete
222
+
223
+ uploadCompleted: (url, node)=>
224
+ node.find("img").attr("src", url)
225
+ #return false
226
+
227
+ ###
228
+ # Handles the behavior of deleting images when using the backspace key
229
+ #
230
+ # @param {Event} e - The backspace event that is being handled
231
+ # @param {Node} node - The node the backspace was used in, assumed to be from te editor's getNode() function
232
+ #
233
+ # @return {Boolean} true if this function handled the backspace event, otherwise false
234
+ ###
235
+ handleBackspaceKey: (e, node) =>
236
+
237
+ #remove graf figure is is selected but not in range (not focus on caption)
238
+ if $(".is-selected").hasClass("graf--figure") && !anchor_node?
239
+ utils.log("Replacing selected node")
240
+ @current_editor.replaceWith("p", $(".is-selected"))
241
+
242
+ e.preventDefault() #without this line, the browser may interpret the backspace as a "go pack a page" command
243
+
244
+ @current_editor.setRangeAt($(".is-selected")[0])
245
+ return true
246
+
247
+ return false
248
+
@@ -0,0 +1,235 @@
1
+ String.prototype.killWhiteSpace = ()->
2
+ this.replace(/\s/g, '')
3
+
4
+ String.prototype.reduceWhiteSpace = ()->
5
+ this.replace(/\s+/g, ' ')
6
+
7
+ utils = {}
8
+ window.Dante.utils = utils
9
+
10
+ utils.log = (message, force) ->
11
+ if (window.debugMode || force)
12
+ #console.log('%cDANTE DEBUGGER: %c' + message, 'font-family:arial,sans-serif;color:#1abf89;line-height:2em;', 'font-family:cursor,monospace;color:#333;');
13
+ #console.log('%cDANTE DEBUGGER: %c', 'font-family:arial,sans-serif;color:#1abf89;line-height:2em;', 'font-family:cursor,monospace;color:#333;');
14
+ console.log( message );
15
+
16
+ utils.getBase64Image = (img) ->
17
+ canvas = document.createElement("canvas")
18
+ canvas.width = img.width
19
+ canvas.height = img.height
20
+ ctx = canvas.getContext("2d")
21
+ ctx.drawImage img, 0, 0
22
+ dataURL = canvas.toDataURL("image/png")
23
+
24
+ # escape data:image prefix
25
+ # dataURL.replace /^data:image\/(png|jpg);base64,/, ""
26
+
27
+ # or just return dataURL
28
+ return dataURL
29
+
30
+ utils.generateUniqueName = ()->
31
+ Math.random().toString(36).slice(8)
32
+
33
+ #http://stackoverflow.com/questions/5605401/insert-link-in-contenteditable-element
34
+ utils.saveSelection = ()->
35
+ if window.getSelection
36
+ sel = window.getSelection()
37
+ if sel.getRangeAt and sel.rangeCount
38
+ ranges = []
39
+ i = 0
40
+ len = sel.rangeCount
41
+
42
+ while i < len
43
+ ranges.push sel.getRangeAt(i)
44
+ ++i
45
+ return ranges
46
+ else return document.selection.createRange() if document.selection and document.selection.createRange
47
+ null
48
+
49
+ utils.restoreSelection = (savedSel) ->
50
+ if savedSel
51
+ if window.getSelection
52
+ sel = window.getSelection()
53
+ sel.removeAllRanges()
54
+ i = 0
55
+ len = savedSel.length
56
+
57
+ while i < len
58
+ sel.addRange savedSel[i]
59
+ ++i
60
+ else savedSel.select() if document.selection and savedSel.select
61
+ return
62
+
63
+ utils.getNode = ()->
64
+ range = undefined
65
+ sel = undefined
66
+ container = undefined
67
+ if document.selection and document.selection.createRange
68
+
69
+ # IE case
70
+ range = document.selection.createRange()
71
+ range.parentElement()
72
+ else if window.getSelection
73
+ sel = window.getSelection()
74
+ if sel.getRangeAt
75
+ range = sel.getRangeAt(0) if sel.rangeCount > 0
76
+ else
77
+
78
+ # Old WebKit selection object has no getRangeAt, so
79
+ # create a range from other selection properties
80
+ range = document.createRange()
81
+ range.setStart sel.anchorNode, sel.anchorOffset
82
+ range.setEnd sel.focusNode, sel.focusOffset
83
+
84
+ # Handle the case when the selection was selected backwards (from the end to the start in the document)
85
+ if range.collapsed isnt sel.isCollapsed
86
+ range.setStart sel.focusNode, sel.focusOffset
87
+ range.setEnd sel.anchorNode, sel.anchorOffset
88
+ if range
89
+ container = range.commonAncestorContainer
90
+
91
+ # Check if the container is a text node and return its parent if so
92
+ (if container.nodeType is 3 then container.parentNode else container)
93
+
94
+ #http://stackoverflow.com/questions/12603397/calculate-width-height-of-the-selected-text-javascript
95
+ utils.getSelectionDimensions = ->
96
+ sel = document.selection
97
+ range = undefined
98
+ width = 0
99
+ height = 0
100
+ left = 0
101
+ top = 0
102
+ if sel
103
+ unless sel.type is "Control"
104
+ range = sel.createRange()
105
+ width = range.boundingWidth
106
+ height = range.boundingHeight
107
+ else if window.getSelection
108
+ sel = window.getSelection()
109
+ if sel.rangeCount
110
+ range = sel.getRangeAt(0).cloneRange()
111
+ if range.getBoundingClientRect
112
+ rect = range.getBoundingClientRect()
113
+ width = rect.right - rect.left
114
+ height = rect.bottom - rect.top
115
+
116
+ width: width
117
+ height: height
118
+ top: rect.top
119
+ left: rect.left
120
+
121
+ #http://stackoverflow.com/questions/3972014/get-caret-position-in-contenteditable-div
122
+ utils.getCaretPosition = (editableDiv) ->
123
+ caretPos = 0
124
+ containerEl = null
125
+ sel = undefined
126
+ range = undefined
127
+ if window.getSelection
128
+ sel = window.getSelection()
129
+ if sel.rangeCount
130
+ range = sel.getRangeAt(0)
131
+ caretPos = range.endOffset if range.commonAncestorContainer.parentNode is editableDiv
132
+ else if document.selection and document.selection.createRange
133
+ range = document.selection.createRange()
134
+ if range.parentElement() is editableDiv
135
+ tempEl = document.createElement("span")
136
+ editableDiv.insertBefore tempEl, editableDiv.firstChild
137
+ tempRange = range.duplicate()
138
+ tempRange.moveToElementText tempEl
139
+ tempRange.setEndPoint "EndToEnd", range
140
+ caretPos = tempRange.text.length
141
+ caretPos
142
+
143
+ #http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
144
+ utils.isElementInViewport = (el) ->
145
+ #special bonus for those using jQuery
146
+ el = el[0] if typeof jQuery is "function" and el instanceof jQuery
147
+ rect = el.getBoundingClientRect()
148
+ #or $(window).height()
149
+ rect.top >= 0 and rect.left >= 0 and rect.bottom <= (window.innerHeight or document.documentElement.clientHeight) and rect.right <= (window.innerWidth or document.documentElement.clientWidth) #or $(window).width()
150
+
151
+ #http://brianmhunt.github.io/articles/taming-contenteditable/
152
+
153
+ LINE_HEIGHT = 20
154
+
155
+ is_caret_at_start_of_node = (node, range) ->
156
+ # See: http://stackoverflow.com/questions/7451468
157
+ pre_range = document.createRange()
158
+ pre_range.selectNodeContents(node)
159
+ pre_range.setEnd(range.startContainer, range.startOffset)
160
+ return pre_range.toString().trim().length == 0
161
+
162
+ is_caret_at_end_of_node = (node, range) ->
163
+ post_range = document.createRange()
164
+ post_range.selectNodeContents(node)
165
+ post_range.setStart(range.endContainer, range.endOffset)
166
+ return post_range.toString().trim().length == 0
167
+
168
+ $.fn.editableIsCaret = ->
169
+ return window.getSelection().type == 'Caret'
170
+ # alt test:
171
+ # return sel.rangeCount == 1 and sel.getRangeAt(0).collapsed
172
+
173
+ $.fn.editableRange = ->
174
+ # Return the range for the selection
175
+ sel = window.getSelection()
176
+ return unless sel.rangeCount > 0
177
+ return sel.getRangeAt(0)
178
+
179
+ $.fn.editableCaretRange = ->
180
+ return unless @editableIsCaret()
181
+ return @editableRange()
182
+
183
+ $.fn.editableSetRange = (range) ->
184
+ sel = window.getSelection()
185
+ sel.removeAllRanges() if sel.rangeCount > 0
186
+ sel.addRange(range)
187
+
188
+ $.fn.editableFocus = (at_start=true) ->
189
+ return unless @attr('contenteditable')
190
+ sel = window.getSelection()
191
+ sel.removeAllRanges() if sel.rangeCount > 0
192
+ range = document.createRange()
193
+ range.selectNodeContents(@[0])
194
+ range.collapse(at_start)
195
+ sel.addRange(range)
196
+
197
+ $.fn.editableCaretAtStart = ->
198
+ range = @editableRange()
199
+ return false unless range
200
+ return is_caret_at_start_of_node(@[0], range)
201
+
202
+ $.fn.editableCaretAtEnd = ->
203
+ range = @editableRange()
204
+ return false unless range
205
+ return is_caret_at_end_of_node(@[0], range)
206
+
207
+ $.fn.editableCaretOnFirstLine = ->
208
+ range = @editableRange()
209
+ return false unless range
210
+ # At the start of a node, the getClientRects() is [], so we have to
211
+ # use the getBoundingClientRect (which seems to work).
212
+ if is_caret_at_start_of_node(@[0], range)
213
+ return true
214
+ else if is_caret_at_end_of_node(@[0], range)
215
+ ctop = @[0].getBoundingClientRect().bottom - LINE_HEIGHT
216
+ else
217
+ ctop = range.getClientRects()[0].top
218
+ etop = @[0].getBoundingClientRect().top
219
+ return ctop < etop + LINE_HEIGHT
220
+
221
+ $.fn.editableCaretOnLastLine = ->
222
+ range = @editableRange()
223
+ return false unless range
224
+ if is_caret_at_end_of_node(@[0], range)
225
+ return true
226
+ else if is_caret_at_start_of_node(@[0], range)
227
+ # We are on the first line.
228
+ cbtm = @[0].getBoundingClientRect().top + LINE_HEIGHT
229
+ else
230
+ cbtm = range.getClientRects()[0].bottom
231
+ ebtm = @[0].getBoundingClientRect().bottom
232
+ return cbtm > ebtm - LINE_HEIGHT
233
+
234
+ $.fn.exists = ->
235
+ @.length > 0
@@ -0,0 +1,101 @@
1
+ #a very light backbone.view like version
2
+
3
+ class Dante.View
4
+
5
+ constructor: (opts = {})->
6
+ @el = opts.el if opts.el
7
+ @._ensureElement()
8
+ @initialize.apply(@, arguments)
9
+ @._ensureEvents()
10
+
11
+ initialize: (opts={})->
12
+
13
+ events: ->
14
+
15
+ render: ()->
16
+ return @
17
+
18
+ remove: ()->
19
+ @._removeElement()
20
+ @.stopListening()
21
+ return @
22
+
23
+ _removeElement: ()->
24
+ @.$el.remove();
25
+
26
+ setElement: (element)->
27
+ #@.undelegateEvents()
28
+ @._setElement(element)
29
+ #@.delegateEvents()
30
+ return @
31
+
32
+ setEvent: (opts)->
33
+ if !_.isEmpty(opts)
34
+ _.each opts, (f, key)=>
35
+ key_arr = key.split(" ")
36
+
37
+ if _.isFunction(f)
38
+ func = f
39
+ else if _.isString(f)
40
+ func = @[f]
41
+ else
42
+ throw "error event needs a function or string"
43
+
44
+ element = if key_arr.length > 1 then key_arr.splice(1 , 3).join(" ") else null
45
+
46
+ $( @el ).on( key_arr[0], element, _.bind(func, this) )
47
+
48
+ _ensureElement: ()->
49
+ @.setElement(_.result(@, 'el'))
50
+
51
+ _ensureEvents: ()->
52
+ @.setEvent(_.result(@, 'events'))
53
+
54
+ _setElement: (el)->
55
+ @.$el = if el instanceof $ then el else $(el)
56
+ @.el = @.$el[0]
57
+
58
+
59
+ # Helper function to correctly set up the prototype chain, for subclasses.
60
+ # Similar to `goog.inherits`, but uses a hash of prototype properties and
61
+ # class properties to be extended.
62
+
63
+ # This is borrowed from Backbone .extend function
64
+
65
+ extend = (protoProps, staticProps) ->
66
+ parent = this
67
+ child = undefined
68
+ # The constructor function for the new subclass is either defined by you
69
+ # (the "constructor" property in your `extend` definition), or defaulted
70
+ # by us to simply call the parent's constructor.
71
+ if protoProps and _.has(protoProps, 'constructor')
72
+ child = protoProps.constructor
73
+ else
74
+
75
+ child = ->
76
+ parent.apply this, arguments
77
+
78
+ # Add static properties to the constructor function, if supplied.
79
+ _.extend child, parent, staticProps
80
+ # Set the prototype chain to inherit from `parent`, without calling
81
+ # `parent`'s constructor function.
82
+
83
+ Surrogate = ->
84
+ @constructor = child
85
+ return
86
+
87
+ Surrogate.prototype = parent.prototype
88
+ child.prototype = new Surrogate
89
+ # Add prototype properties (instance properties) to the subclass,
90
+ # if supplied.
91
+ if protoProps
92
+ _.extend child.prototype, protoProps
93
+ # Set a convenience property in case the parent's prototype is needed
94
+ # later.
95
+ child.__super__ = parent.prototype
96
+ child
97
+
98
+ #Set up inheritance for the model, collection, router, view and history.
99
+ #Dante.View.extend = utils.extend;
100
+
101
+ Dante.View.extend = extend
@@ -0,0 +1,12 @@
1
+ //Editor components
2
+ //= require dante/dante
3
+ //= require dante/utils
4
+ //= require dante/view
5
+ //= require dante/editor
6
+ //= require dante/tooltip_widget
7
+ //= require dante/tooltip_widgets/uploader
8
+ //= require dante/tooltip_widgets/embed
9
+ //= require dante/tooltip_widgets/extract
10
+ //= require dante/tooltip
11
+ //= require dante/popover
12
+ //= require dante/menu
@@ -0,0 +1,54 @@
1
+ @-webkit-keyframes pop-upwards {
2
+ 0% {
3
+ -webkit-transform: matrix(.97, 0, 0, 1, 0, 12);
4
+ transform: matrix(.97, 0, 0, 1, 0, 12);
5
+ opacity: 0;
6
+ }
7
+ 20% {
8
+ -webkit-transform: matrix(.99, 0, 0, 1, 0, 2);
9
+ transform: matrix(.99, 0, 0, 1, 0, 2);
10
+ opacity: .7;
11
+ }
12
+ 40% {
13
+ -webkit-transform: matrix(1, 0, 0, 1, 0, -1);
14
+ transform: matrix(1, 0, 0, 1, 0, -1);
15
+ opacity: 1;
16
+ }
17
+ 70% {
18
+ -webkit-transform: matrix(1, 0, 0, 1, 0, 0);
19
+ transform: matrix(1, 0, 0, 1, 0, 0);
20
+ opacity: 1;
21
+ }
22
+ 100% {
23
+ -webkit-transform: matrix(1, 0, 0, 1, 0, 0);
24
+ transform: matrix(1, 0, 0, 1, 0, 0);
25
+ opacity: 1;
26
+ }
27
+ }
28
+ @keyframes pop-upward {
29
+ 0% {
30
+ -webkit-transform: matrix(.97, 0, 0, 1, 0, 12);
31
+ transform: matrix(.97, 0, 0, 1, 0, 12);
32
+ opacity: 0;
33
+ }
34
+ 20% {
35
+ -webkit-transform: matrix(.99, 0, 0, 1, 0, 2);
36
+ transform: matrix(.99, 0, 0, 1, 0, 2);
37
+ opacity: .7;
38
+ }
39
+ 40% {
40
+ -webkit-transform: matrix(1, 0, 0, 1, 0, -1);
41
+ transform: matrix(1, 0, 0, 1, 0, -1);
42
+ opacity: 1;
43
+ }
44
+ 70% {
45
+ -webkit-transform: matrix(1, 0, 0, 1, 0, 0);
46
+ transform: matrix(1, 0, 0, 1, 0, 0);
47
+ opacity: 1;
48
+ }
49
+ 100% {
50
+ -webkit-transform: matrix(1, 0, 0, 1, 0, 0);
51
+ transform: matrix(1, 0, 0, 1, 0, 0);
52
+ opacity: 1;
53
+ }
54
+ }
@@ -0,0 +1,52 @@
1
+ .imageCaption {
2
+ & {
3
+ position: absolute;
4
+ left: -172px;
5
+ width: 150px;
6
+ top: 0;
7
+ text-align: right;
8
+ margin-top: 0;
9
+ font-family: "freight-text-pro",Georgia,Cambria,"Times New Roman",Times,serif;
10
+ letter-spacing: 0.01rem;
11
+ font-weight: 400;
12
+ font-style: italic;
13
+ font-size: 14px;
14
+ line-height: 1.4;
15
+ color: rgba(0,0,0,0.6);
16
+ outline: 0;
17
+ z-index: 300;
18
+ }
19
+ &:before {
20
+ width: 25%;
21
+ margin-left: 75%;
22
+ border-top: 1px solid rgba(0,0,0,0.15);
23
+ display: block;
24
+ content: "";
25
+ margin-bottom: 10px;
26
+ }
27
+ }
28
+ @media (max-width: 1200px) {
29
+ .imageCaption,
30
+ .postField--outsetCenterImage > .imageCaption {
31
+ position: relative;
32
+ width: 100%;
33
+ text-align: center;
34
+ left: 0;
35
+ margin-top: 10px;
36
+ }
37
+ .imageCaption:before {
38
+ display: none;
39
+ }
40
+ }
41
+
42
+ figure.is-defaultValue .imageCaption,
43
+ .graf--sectionCaption.is-defaultValue {
44
+ display: none;
45
+ }
46
+
47
+ .graf--figure.is-mediaFocused .imageCaption,
48
+ .graf--figure.is-defaultValue.is-selected .imageCaption,
49
+ section.is-mediaFocused .graf--sectionCaption,
50
+ .graf--sectionCaption.is-defaultValue.is-selected {
51
+ display: block;
52
+ }