kuhsaft 2.2.6 → 2.3.0
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 +4 -4
- data/README.md +37 -0
- data/Rakefile +6 -5
- data/app/assets/javascripts/ckeditor/plugins/adv_link/LICENSE.txt +674 -0
- data/app/assets/javascripts/ckeditor/plugins/adv_link/README.md +62 -0
- data/app/assets/javascripts/ckeditor/plugins/adv_link/dialogs/anchor.js.coffee +81 -0
- data/app/assets/javascripts/ckeditor/plugins/adv_link/dialogs/link.js.coffee +1353 -0
- data/app/assets/javascripts/ckeditor/plugins/adv_link/images/anchor.png +0 -0
- data/app/assets/javascripts/ckeditor/plugins/adv_link/images/hidpi/anchor.png +0 -0
- data/app/assets/javascripts/ckeditor/plugins/adv_link/lang/de.js +68 -0
- data/app/assets/javascripts/ckeditor/plugins/adv_link/lang/en.js +68 -0
- data/app/assets/javascripts/ckeditor/plugins/adv_link/plugin.js.coffee +282 -0
- data/app/assets/javascripts/kuhsaft/cms/application.js.coffee.erb +42 -4
- data/app/assets/stylesheets/kuhsaft/application.css.sass +0 -3
- data/app/assets/stylesheets/kuhsaft/cms/application.css.sass +26 -11
- data/app/controllers/kuhsaft/api/pages_controller.rb +14 -0
- data/app/controllers/kuhsaft/cms/admin_controller.rb +1 -1
- data/app/controllers/kuhsaft/cms/assets_controller.rb +7 -7
- data/app/controllers/kuhsaft/cms/bricks_controller.rb +15 -4
- data/app/controllers/kuhsaft/cms/pages_controller.rb +8 -15
- data/app/controllers/kuhsaft/pages_controller.rb +16 -6
- data/app/controllers/kuhsaft/sitemaps_controller.rb +13 -0
- data/app/helpers/cms_helper.rb +4 -4
- data/app/helpers/kuhsaft/admin_helper.rb +0 -1
- data/app/helpers/kuhsaft/cms/admin_helper.rb +1 -2
- data/app/helpers/kuhsaft/cms/pages_helper.rb +2 -7
- data/app/helpers/pages_helper.rb +8 -37
- data/app/helpers/sitemaps_helper.rb +12 -0
- data/app/models/kuhsaft/accordion_item_brick.rb +1 -1
- data/app/models/kuhsaft/anchor_brick.rb +1 -1
- data/app/models/kuhsaft/asset.rb +26 -23
- data/app/models/kuhsaft/asset_brick.rb +2 -1
- data/app/models/kuhsaft/brick.rb +38 -16
- data/app/models/kuhsaft/brick_type.rb +2 -2
- data/app/models/kuhsaft/brick_type_filter.rb +0 -2
- data/app/models/kuhsaft/column_brick.rb +0 -1
- data/app/models/kuhsaft/image_brick.rb +2 -2
- data/app/models/kuhsaft/image_size.rb +0 -1
- data/app/models/kuhsaft/link_brick.rb +1 -1
- data/app/models/kuhsaft/page.rb +111 -107
- data/app/models/kuhsaft/page_type.rb +1 -1
- data/app/models/kuhsaft/partition.rb +12 -12
- data/app/models/kuhsaft/placeholder_brick.rb +8 -0
- data/app/models/kuhsaft/publish_state.rb +9 -10
- data/app/models/kuhsaft/slider_brick.rb +0 -2
- data/app/models/kuhsaft/text_brick.rb +1 -1
- data/app/models/kuhsaft/two_column_brick.rb +0 -1
- data/app/models/kuhsaft/video_brick.rb +1 -2
- data/app/uploaders/kuhsaft/asset_brick_asset_uploader.rb +39 -38
- data/app/uploaders/kuhsaft/asset_uploader.rb +43 -43
- data/app/uploaders/kuhsaft/image_brick_image_uploader.rb +7 -34
- data/app/views/kuhsaft/asset_bricks/asset_brick/_edit.html.haml +3 -2
- data/app/views/kuhsaft/cms/admin/_brick_type_dropdown.html.haml +2 -2
- data/app/views/kuhsaft/cms/bricks/_brick_item.html.haml +17 -10
- data/app/views/kuhsaft/cms/bricks/_new.html.haml +34 -0
- data/app/views/kuhsaft/cms/bricks/create.js.haml +6 -0
- data/app/views/kuhsaft/cms/bricks/destroy.js.haml +4 -0
- data/app/views/kuhsaft/cms/bricks/new.js.haml +11 -0
- data/app/views/kuhsaft/cms/pages/_branch.html.haml +2 -2
- data/app/views/kuhsaft/cms/pages/_form.html.haml +29 -18
- data/app/views/kuhsaft/image_bricks/_image_brick.html.haml +9 -7
- data/app/views/kuhsaft/image_bricks/image_brick/_edit.html.haml +3 -0
- data/app/views/kuhsaft/pages/show.html.haml +1 -9
- data/app/views/kuhsaft/placeholder_bricks/_placeholder_brick.html.haml +1 -1
- data/app/views/kuhsaft/sitemaps/index.xml.haml +9 -0
- data/app/views/kuhsaft/video_bricks/_video_brick.html.haml +4 -4
- data/app/views/layouts/kuhsaft/cms/application.html.haml +4 -3
- data/config/initializers/simple_form.rb +4 -4
- data/config/initializers/simple_form_bootstrap.rb +14 -14
- data/config/locales/de.yml +203 -0
- data/config/locales/en.yml +282 -0
- data/config/locales/kuhsaft.de.yml +14 -0
- data/config/locales/kuhsaft.en.yml +60 -0
- data/config/locales/models/kuhsaft/image_brick/de.yml +1 -0
- data/config/locales/models/kuhsaft/image_brick/en.yml +16 -0
- data/config/locales/models/kuhsaft/text_brick/de.yml +3 -0
- data/config/locales/models/kuhsaft/text_brick/en.yml +16 -0
- data/config/locales/models/kuhsaft/video_brick/en.yml +15 -0
- data/config/locales/views/kuhsaft/cms/pages/de.yml +3 -0
- data/config/locales/views/kuhsaft/cms/video_bricks/de.yml +1 -1
- data/config/routes.rb +18 -9
- data/db/migrate/10_add_redirect_url_to_kuhsaft_pages.rb +1 -1
- data/db/migrate/11_update_url_and_redirect_url_value.rb +4 -4
- data/db/migrate/13_add_page_title_to_pages.rb +1 -1
- data/db/migrate/15_add_alt_text_to_bricks.rb +5 -0
- data/db/migrate/16_update_default_value_for_page_type.rb +9 -0
- data/db/migrate/17_set_page_type_to_content_for_empty_fields.rb +7 -0
- data/lib/generators/kuhsaft/assets/install_generator.rb +1 -2
- data/lib/generators/kuhsaft/translations/add_generator.rb +19 -4
- data/lib/kuhsaft.rb +1 -0
- data/lib/kuhsaft/brick_list.rb +6 -8
- data/lib/kuhsaft/engine.rb +5 -1
- data/lib/kuhsaft/orderable.rb +22 -19
- data/lib/kuhsaft/partial_extractor.rb +1 -1
- data/lib/kuhsaft/searchable.rb +8 -11
- data/lib/kuhsaft/translatable.rb +35 -19
- data/lib/kuhsaft/version.rb +1 -1
- data/lib/tasks/kuhsaft_tasks.rake +12 -0
- data/lib/templates/kuhsaft/assets/ck-config.js.coffee +7 -0
- data/lib/templates/kuhsaft/translations/add_translation.html.erb +4 -10
- data/spec/controllers/kuhsaft/api/pages_controller_spec.rb +70 -0
- data/spec/controllers/kuhsaft/pages_controller_spec.rb +18 -14
- data/spec/controllers/kuhsaft/sitemaps_controller_spec.rb +13 -0
- data/spec/dummy/app/assets/javascripts/kuhsaft/cms/ck-config.js.coffee +7 -0
- data/spec/dummy/config/application.rb +2 -1
- data/spec/dummy/config/database.yml +1 -1
- data/spec/factories.rb +3 -3
- data/spec/features/cms_pages_spec.rb +13 -13
- data/spec/features/search_spec.rb +16 -18
- data/spec/helpers/kuhsaft/cms/pages_helper_spec.rb +2 -1
- data/spec/kuhsaft_spec.rb +1 -1
- data/spec/lib/brick_list_spec.rb +1 -1
- data/spec/lib/page_tree_spec.rb +10 -6
- data/spec/lib/searchable_spec.rb +4 -4
- data/spec/lib/translatable_spec.rb +114 -44
- data/spec/models/anchor_brick_spec.rb +1 -1
- data/spec/models/asset_spec.rb +1 -1
- data/spec/models/brick_spec.rb +1 -1
- data/spec/models/page_spec.rb +48 -37
- data/spec/models/publish_state_spec.rb +9 -9
- data/spec/spec_helper.rb +43 -21
- data/spec/support/kuhsaft_spec_helper.rb +2 -2
- data/spec/support/write_expectation.rb +57 -0
- data/spec/views/kuhsaft/sitemaps/index.xml.haml_spec.rb +67 -0
- metadata +119 -4
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
ckeditor-adv_link
|
|
2
|
+
=================
|
|
3
|
+
|
|
4
|
+
A CKEditor4 link plugin adding the ability to link to local (CMS) pages. Rely on jQuery for ajax calls (un-intrusive).
|
|
5
|
+
This implementation supports internationalisation (see below).
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Disclaimer
|
|
9
|
+
----------
|
|
10
|
+
|
|
11
|
+
I developed that script for my needs and inspired by this [blog post](http://blog.xoundboy.com/?p=393) and this StackOverflow [answer](http://stackoverflow.com/questions/5293920/ckeditor-dynamic-select-in-a-dialog). I want people to be able to use it but I don't pretend to do any support regarding installation or use. It works well with CKEditor v 4.2.2. You want to make it work with other versions? Just do it and share it back.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
Enhancement
|
|
15
|
+
-----------
|
|
16
|
+
|
|
17
|
+
I really think it would be great to replace the select input by a list of links contained in a HTML div or even better an input text with ajax call (like in WP). I do not have time now to do that. If you want to involve yourself, you're more than welcome.
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
How to install it ?
|
|
21
|
+
--------------------
|
|
22
|
+
|
|
23
|
+
1) Download and extract `adv_link` folder into CKEditor plugins folder
|
|
24
|
+
|
|
25
|
+
2) Disable default link plugin and enable the new one. To do so, in your config.js file :
|
|
26
|
+
|
|
27
|
+
```javascript
|
|
28
|
+
CKEDITOR.editorConfig = function( config )
|
|
29
|
+
{
|
|
30
|
+
// Define changes to default configuration here.
|
|
31
|
+
|
|
32
|
+
config.removePlugins = 'link';
|
|
33
|
+
config.extraPlugins = 'adv_link';
|
|
34
|
+
|
|
35
|
+
// whatever
|
|
36
|
+
|
|
37
|
+
};
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
3) In `dialogs/links.js` file, set the URL of the page which generates inputs to populate the plugin. It is located around line 377. A PHP script sample is given in `sample` folder and can be a good start.
|
|
41
|
+
|
|
42
|
+
4) Test your installation by using the plugin.
|
|
43
|
+
|
|
44
|
+
5) It should be working, adapt your script to get the rights inputs.
|
|
45
|
+
|
|
46
|
+
6) If it does not work, use javascript debugging tool.
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
Internationalization ready
|
|
50
|
+
--------------------------
|
|
51
|
+
|
|
52
|
+
All languages are embedded in the source code. They are just copies of the default `link` plugin. But few of them are translated.
|
|
53
|
+
|
|
54
|
+
3 new vars are defined in language files (at the top) :
|
|
55
|
+
|
|
56
|
+
```javascript
|
|
57
|
+
localPages:'Local pages',
|
|
58
|
+
selectPageLabel:'Select a page',
|
|
59
|
+
selectPageTitle:'Select the page you want to link to',
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
If you can't see them in the selected language file, you'll have to copy-paste from `en.js` file. Please, share your translation with others users.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
|
|
3
|
+
# For licensing, see LICENSE.md or http://ckeditor.com/license
|
|
4
|
+
#
|
|
5
|
+
CKEDITOR.dialog.add "anchor", (c) ->
|
|
6
|
+
d = (a) ->
|
|
7
|
+
@_.selectedElement = a
|
|
8
|
+
@setValueOf "info", "txtName", a.data("cke-saved-name") or ""
|
|
9
|
+
return
|
|
10
|
+
|
|
11
|
+
title: c.lang.link.anchor.title
|
|
12
|
+
minWidth: 300
|
|
13
|
+
minHeight: 60
|
|
14
|
+
onOk: ->
|
|
15
|
+
a = CKEDITOR.tools.trim(@getValueOf("info", "txtName"))
|
|
16
|
+
a =
|
|
17
|
+
id: a
|
|
18
|
+
name: a
|
|
19
|
+
"data-cke-saved-name": a
|
|
20
|
+
|
|
21
|
+
if @_.selectedElement
|
|
22
|
+
(if @_.selectedElement.data("cke-realelement") then (a = c.document.createElement("a",
|
|
23
|
+
attributes: a
|
|
24
|
+
)
|
|
25
|
+
c.createFakeElement(a, "cke_anchor", "anchor").replace(@_.selectedElement)
|
|
26
|
+
) else @_.selectedElement.setAttributes(a))
|
|
27
|
+
else
|
|
28
|
+
b = c.getSelection()
|
|
29
|
+
b = b and b.getRanges()[0]
|
|
30
|
+
(if b.collapsed then (CKEDITOR.plugins.link.synAnchorSelector and (a["class"] = "cke_anchor_empty")
|
|
31
|
+
CKEDITOR.plugins.link.emptyAnchorFix and (a.contenteditable = "false"
|
|
32
|
+
a["data-cke-editable"] = 1
|
|
33
|
+
)
|
|
34
|
+
a = c.document.createElement("a",
|
|
35
|
+
attributes: a
|
|
36
|
+
)
|
|
37
|
+
CKEDITOR.plugins.link.fakeAnchor and (a = c.createFakeElement(a, "cke_anchor", "anchor"))
|
|
38
|
+
b.insertNode(a)
|
|
39
|
+
) else (CKEDITOR.env.ie and 9 > CKEDITOR.env.version and (a["class"] = "cke_anchor")
|
|
40
|
+
a = new CKEDITOR.style(
|
|
41
|
+
element: "a"
|
|
42
|
+
attributes: a
|
|
43
|
+
)
|
|
44
|
+
a.type = CKEDITOR.STYLE_INLINE
|
|
45
|
+
c.applyStyle(a)
|
|
46
|
+
))
|
|
47
|
+
return
|
|
48
|
+
|
|
49
|
+
onHide: ->
|
|
50
|
+
delete @_.selectedElement
|
|
51
|
+
|
|
52
|
+
return
|
|
53
|
+
|
|
54
|
+
onShow: ->
|
|
55
|
+
a = c.getSelection()
|
|
56
|
+
b = a.getSelectedElement()
|
|
57
|
+
if b
|
|
58
|
+
(if CKEDITOR.plugins.link.fakeAnchor then ((a = CKEDITOR.plugins.link.tryRestoreFakeAnchor(c, b)) and d.call(this, a)
|
|
59
|
+
@_.selectedElement = b
|
|
60
|
+
) else b.is("a") and b.hasAttribute("name") and d.call(this, b))
|
|
61
|
+
else if b = CKEDITOR.plugins.link.getSelectedLink(c)
|
|
62
|
+
d.call(this, b)
|
|
63
|
+
a.selectElement(b)
|
|
64
|
+
@getContentElement("info", "txtName").focus()
|
|
65
|
+
return
|
|
66
|
+
|
|
67
|
+
contents: [
|
|
68
|
+
id: "info"
|
|
69
|
+
label: c.lang.link.anchor.title
|
|
70
|
+
accessKey: "I"
|
|
71
|
+
elements: [
|
|
72
|
+
type: "text"
|
|
73
|
+
id: "txtName"
|
|
74
|
+
label: c.lang.link.anchor.name
|
|
75
|
+
required: not 0
|
|
76
|
+
validate: ->
|
|
77
|
+
(if not @getValue() then (alert(c.lang.link.anchor.errorName)
|
|
78
|
+
not 1
|
|
79
|
+
) else not 0)
|
|
80
|
+
]
|
|
81
|
+
]
|
|
@@ -0,0 +1,1353 @@
|
|
|
1
|
+
###
|
|
2
|
+
@license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
|
|
3
|
+
For licensing, see LICENSE.md or http://ckeditor.com/license
|
|
4
|
+
###
|
|
5
|
+
|
|
6
|
+
#
|
|
7
|
+
# Function to get current content locale
|
|
8
|
+
#
|
|
9
|
+
getParameterByName = (name, href) ->
|
|
10
|
+
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]")
|
|
11
|
+
regexS = "[\\?&]" + name + "=([^&#]*)"
|
|
12
|
+
regex = new RegExp(regexS)
|
|
13
|
+
results = regex.exec(href)
|
|
14
|
+
unless results?
|
|
15
|
+
""
|
|
16
|
+
else
|
|
17
|
+
decodeURIComponent results[1].replace(/\+/g, " ")
|
|
18
|
+
|
|
19
|
+
CKEDITOR.dialog.add "link", (editor) ->
|
|
20
|
+
|
|
21
|
+
unescapeSingleQuote = (str) ->
|
|
22
|
+
str.replace /\\'/g, "'"
|
|
23
|
+
|
|
24
|
+
escapeSingleQuote = (str) ->
|
|
25
|
+
str.replace /'/g, "\\$&"
|
|
26
|
+
|
|
27
|
+
# Compile the protection function pattern.
|
|
28
|
+
protectEmailLinkAsFunction = (email) ->
|
|
29
|
+
retval = undefined
|
|
30
|
+
name = compiledProtectionFunction.name
|
|
31
|
+
params = compiledProtectionFunction.params
|
|
32
|
+
paramName = undefined
|
|
33
|
+
paramValue = undefined
|
|
34
|
+
retval = [
|
|
35
|
+
name
|
|
36
|
+
"("
|
|
37
|
+
]
|
|
38
|
+
i = 0
|
|
39
|
+
|
|
40
|
+
while i < params.length
|
|
41
|
+
paramName = params[i].toLowerCase()
|
|
42
|
+
paramValue = email[paramName]
|
|
43
|
+
i > 0 and retval.push(",")
|
|
44
|
+
retval.push "'", (if paramValue then escapeSingleQuote(encodeURIComponent(email[paramName])) else ""), "'"
|
|
45
|
+
i++
|
|
46
|
+
retval.push ")"
|
|
47
|
+
retval.join ""
|
|
48
|
+
|
|
49
|
+
protectEmailAddressAsEncodedString = (address) ->
|
|
50
|
+
charCode = undefined
|
|
51
|
+
length = address.length
|
|
52
|
+
encodedChars = []
|
|
53
|
+
i = 0
|
|
54
|
+
|
|
55
|
+
while i < length
|
|
56
|
+
charCode = address.charCodeAt(i)
|
|
57
|
+
encodedChars.push charCode
|
|
58
|
+
i++
|
|
59
|
+
"String.fromCharCode(" + encodedChars.join(",") + ")"
|
|
60
|
+
|
|
61
|
+
getLinkClass = (ele) ->
|
|
62
|
+
className = ele.getAttribute("class")
|
|
63
|
+
(if className then className.replace(/\s*(?:cke_anchor_empty|cke_anchor)(?:\s*$)?/g, "") else "")
|
|
64
|
+
|
|
65
|
+
plugin = CKEDITOR.plugins.link
|
|
66
|
+
|
|
67
|
+
targetChanged = ->
|
|
68
|
+
dialog = @getDialog()
|
|
69
|
+
popupFeatures = dialog.getContentElement("target", "popupFeatures")
|
|
70
|
+
targetName = dialog.getContentElement("target", "linkTargetName")
|
|
71
|
+
value = @getValue()
|
|
72
|
+
return if not popupFeatures or not targetName
|
|
73
|
+
popupFeatures = popupFeatures.getElement()
|
|
74
|
+
popupFeatures.hide()
|
|
75
|
+
targetName.setValue ""
|
|
76
|
+
switch value
|
|
77
|
+
when "frame"
|
|
78
|
+
targetName.setLabel editor.lang.link.targetFrameName
|
|
79
|
+
targetName.getElement().show()
|
|
80
|
+
when "popup"
|
|
81
|
+
popupFeatures.show()
|
|
82
|
+
targetName.setLabel editor.lang.link.targetPopupName
|
|
83
|
+
targetName.getElement().show()
|
|
84
|
+
else
|
|
85
|
+
targetName.setValue value
|
|
86
|
+
targetName.getElement().hide()
|
|
87
|
+
|
|
88
|
+
# Handles the event when the "Target" selection box is changed.
|
|
89
|
+
linkTypeChanged = ->
|
|
90
|
+
dialog = @getDialog()
|
|
91
|
+
partIds = [
|
|
92
|
+
"urlOptions"
|
|
93
|
+
"localPageOptions"
|
|
94
|
+
"anchorOptions"
|
|
95
|
+
"emailOptions"
|
|
96
|
+
]
|
|
97
|
+
typeValue = @getValue()
|
|
98
|
+
uploadTab = dialog.definition.getContents("upload")
|
|
99
|
+
uploadInitiallyHidden = uploadTab and uploadTab.hidden
|
|
100
|
+
if typeValue is "url"
|
|
101
|
+
dialog.showPage "target" if editor.config.linkShowTargetTab
|
|
102
|
+
dialog.showPage "upload" unless uploadInitiallyHidden
|
|
103
|
+
else
|
|
104
|
+
dialog.hidePage "target"
|
|
105
|
+
dialog.hidePage "upload" unless uploadInitiallyHidden
|
|
106
|
+
i = 0
|
|
107
|
+
|
|
108
|
+
while i < partIds.length
|
|
109
|
+
element = dialog.getContentElement("info", partIds[i])
|
|
110
|
+
continue unless element
|
|
111
|
+
element = element.getElement().getParent().getParent()
|
|
112
|
+
if partIds[i] is typeValue + "Options"
|
|
113
|
+
element.show()
|
|
114
|
+
else
|
|
115
|
+
element.hide()
|
|
116
|
+
i++
|
|
117
|
+
dialog.layout()
|
|
118
|
+
return
|
|
119
|
+
|
|
120
|
+
javascriptProtocolRegex = /^javascript:/
|
|
121
|
+
emailRegex = /^mailto:([^?]+)(?:\?(.+))?$/
|
|
122
|
+
emailSubjectRegex = /subject=([^;?:@&=$,\/]*)/
|
|
123
|
+
emailBodyRegex = /body=([^;?:@&=$,\/]*)/
|
|
124
|
+
anchorRegex = /^#(.*)$/
|
|
125
|
+
urlRegex = /^((?:http|https|ftp|news):\/\/)?(.*)$/
|
|
126
|
+
selectableTargets = /^(_(?:self|top|parent|blank))$/
|
|
127
|
+
encodedEmailLinkRegex = /^javascript:void\(location\.href='mailto:'\+String\.fromCharCode\(([^)]+)\)(?:\+'(.*)')?\)$/
|
|
128
|
+
functionCallProtectedEmailLinkRegex = /^javascript:([^(]+)\(([^)]+)\)$/
|
|
129
|
+
popupRegex = /\s*window.open\(\s*this\.href\s*,\s*(?:'([^']*)'|null)\s*,\s*'([^']*)'\s*\)\s*;\s*return\s*false;*\s*/
|
|
130
|
+
popupFeaturesRegex = /(?:^|,)([^=]+)=(\d+|yes|no)/g
|
|
131
|
+
parseLink = (editor, element) ->
|
|
132
|
+
href = (element and (element.data("cke-saved-href") or element.getAttribute("href"))) or ""
|
|
133
|
+
javascriptMatch = undefined
|
|
134
|
+
emailMatch = undefined
|
|
135
|
+
anchorMatch = undefined
|
|
136
|
+
urlMatch = undefined
|
|
137
|
+
retval = {}
|
|
138
|
+
if javascriptMatch = href.match(javascriptProtocolRegex)
|
|
139
|
+
if emailProtection is "encode"
|
|
140
|
+
href = href.replace(encodedEmailLinkRegex, (match, protectedAddress, rest) ->
|
|
141
|
+
"mailto:" + String.fromCharCode.apply(String, protectedAddress.split(",")) + (rest and unescapeSingleQuote(rest))
|
|
142
|
+
)
|
|
143
|
+
else if emailProtection
|
|
144
|
+
href.replace functionCallProtectedEmailLinkRegex, (match, funcName, funcArgs) ->
|
|
145
|
+
if funcName is compiledProtectionFunction.name
|
|
146
|
+
retval.type = "email"
|
|
147
|
+
email = retval.email = {}
|
|
148
|
+
paramRegex = /[^,\s]+/g
|
|
149
|
+
paramQuoteRegex = /(^')|('$)/g
|
|
150
|
+
paramsMatch = funcArgs.match(paramRegex)
|
|
151
|
+
paramsMatchLength = paramsMatch.length
|
|
152
|
+
paramName = undefined
|
|
153
|
+
paramVal = undefined
|
|
154
|
+
i = 0
|
|
155
|
+
|
|
156
|
+
while i < paramsMatchLength
|
|
157
|
+
paramVal = decodeURIComponent(unescapeSingleQuote(paramsMatch[i].replace(paramQuoteRegex, "")))
|
|
158
|
+
paramName = compiledProtectionFunction.params[i].toLowerCase()
|
|
159
|
+
email[paramName] = paramVal
|
|
160
|
+
i++
|
|
161
|
+
email.address = [
|
|
162
|
+
email.name
|
|
163
|
+
email.domain
|
|
164
|
+
].join("@")
|
|
165
|
+
return
|
|
166
|
+
|
|
167
|
+
unless retval.type
|
|
168
|
+
if anchorMatch = href.match(anchorRegex)
|
|
169
|
+
retval.type = "anchor"
|
|
170
|
+
retval.anchor = {}
|
|
171
|
+
retval.anchor.name = retval.anchor.id = anchorMatch[1]
|
|
172
|
+
else if emailMatch = href.match(emailRegex)
|
|
173
|
+
subjectMatch = href.match(emailSubjectRegex)
|
|
174
|
+
bodyMatch = href.match(emailBodyRegex)
|
|
175
|
+
retval.type = "email"
|
|
176
|
+
email = (retval.email = {})
|
|
177
|
+
email.address = emailMatch[1]
|
|
178
|
+
subjectMatch and (email.subject = decodeURIComponent(subjectMatch[1]))
|
|
179
|
+
bodyMatch and (email.body = decodeURIComponent(bodyMatch[1]))
|
|
180
|
+
else if href and (urlMatch = href.match(urlRegex))
|
|
181
|
+
retval.type = "url"
|
|
182
|
+
retval.url = {}
|
|
183
|
+
retval.url.protocol = urlMatch[1]
|
|
184
|
+
retval.url.url = urlMatch[2]
|
|
185
|
+
else
|
|
186
|
+
retval.type = "url"
|
|
187
|
+
if element
|
|
188
|
+
target = element.getAttribute("target")
|
|
189
|
+
retval.target = {}
|
|
190
|
+
retval.adv = {}
|
|
191
|
+
unless target
|
|
192
|
+
onclick = element.data("cke-pa-onclick") or element.getAttribute("onclick")
|
|
193
|
+
onclickMatch = onclick and onclick.match(popupRegex)
|
|
194
|
+
if onclickMatch
|
|
195
|
+
retval.target.type = "popup"
|
|
196
|
+
retval.target.name = onclickMatch[1]
|
|
197
|
+
featureMatch = undefined
|
|
198
|
+
while (featureMatch = popupFeaturesRegex.exec(onclickMatch[2]))
|
|
199
|
+
if (featureMatch[2] is "yes" or featureMatch[2] is "1") and (featureMatch[1] of
|
|
200
|
+
height: 1
|
|
201
|
+
width: 1
|
|
202
|
+
top: 1
|
|
203
|
+
left: 1
|
|
204
|
+
)
|
|
205
|
+
retval.target[featureMatch[1]] = true
|
|
206
|
+
else retval.target[featureMatch[1]] = featureMatch[2] if isFinite(featureMatch[2])
|
|
207
|
+
else
|
|
208
|
+
targetMatch = target.match(selectableTargets)
|
|
209
|
+
if targetMatch
|
|
210
|
+
retval.target.type = retval.target.name = target
|
|
211
|
+
else
|
|
212
|
+
retval.target.type = "frame"
|
|
213
|
+
retval.target.name = target
|
|
214
|
+
me = this
|
|
215
|
+
advAttr = (inputName, attrName) ->
|
|
216
|
+
value = element.getAttribute(attrName)
|
|
217
|
+
retval.adv[inputName] = value or "" if value isnt null
|
|
218
|
+
return
|
|
219
|
+
|
|
220
|
+
advAttr "advId", "id"
|
|
221
|
+
advAttr "advLangDir", "dir"
|
|
222
|
+
advAttr "advAccessKey", "accessKey"
|
|
223
|
+
retval.adv.advName = element.data("cke-saved-name") or element.getAttribute("name") or ""
|
|
224
|
+
advAttr "advLangCode", "lang"
|
|
225
|
+
advAttr "advTabIndex", "tabindex"
|
|
226
|
+
advAttr "advTitle", "title"
|
|
227
|
+
advAttr "advContentType", "type"
|
|
228
|
+
(if CKEDITOR.plugins.link.synAnchorSelector then retval.adv.advCSSClasses = getLinkClass(element) else advAttr("advCSSClasses", "class"))
|
|
229
|
+
advAttr "advCharset", "charset"
|
|
230
|
+
advAttr "advStyles", "style"
|
|
231
|
+
advAttr "advRel", "rel"
|
|
232
|
+
anchors = retval.anchors = []
|
|
233
|
+
i = undefined
|
|
234
|
+
count = undefined
|
|
235
|
+
item = undefined
|
|
236
|
+
if CKEDITOR.plugins.link.emptyAnchorFix
|
|
237
|
+
links = editor.document.getElementsByTag("a")
|
|
238
|
+
i = 0
|
|
239
|
+
count = links.count()
|
|
240
|
+
|
|
241
|
+
while i < count
|
|
242
|
+
item = links.getItem(i)
|
|
243
|
+
if item.data("cke-saved-name") or item.hasAttribute("name")
|
|
244
|
+
anchors.push
|
|
245
|
+
name: item.data("cke-saved-name") or item.getAttribute("name")
|
|
246
|
+
id: item.getAttribute("id")
|
|
247
|
+
|
|
248
|
+
i++
|
|
249
|
+
else
|
|
250
|
+
anchorList = new CKEDITOR.dom.nodeList(editor.document.$.anchors)
|
|
251
|
+
i = 0
|
|
252
|
+
count = anchorList.count()
|
|
253
|
+
|
|
254
|
+
while i < count
|
|
255
|
+
item = anchorList.getItem(i)
|
|
256
|
+
anchors[i] =
|
|
257
|
+
name: item.getAttribute("name")
|
|
258
|
+
id: item.getAttribute("id")
|
|
259
|
+
i++
|
|
260
|
+
if CKEDITOR.plugins.link.fakeAnchor
|
|
261
|
+
imgs = editor.document.getElementsByTag("img")
|
|
262
|
+
i = 0
|
|
263
|
+
count = imgs.count()
|
|
264
|
+
|
|
265
|
+
while i < count
|
|
266
|
+
if item = CKEDITOR.plugins.link.tryRestoreFakeAnchor(editor, imgs.getItem(i))
|
|
267
|
+
anchors.push
|
|
268
|
+
name: item.getAttribute("name")
|
|
269
|
+
id: item.getAttribute("id")
|
|
270
|
+
|
|
271
|
+
i++
|
|
272
|
+
@_.selectedElement = element
|
|
273
|
+
retval
|
|
274
|
+
|
|
275
|
+
setupParams = (page, data) ->
|
|
276
|
+
@setValue data[page][@id] or "" if data[page]
|
|
277
|
+
return
|
|
278
|
+
|
|
279
|
+
setupPopupParams = (data) ->
|
|
280
|
+
setupParams.call this, "target", data
|
|
281
|
+
|
|
282
|
+
setupAdvParams = (data) ->
|
|
283
|
+
setupParams.call this, "adv", data
|
|
284
|
+
|
|
285
|
+
commitParams = (page, data) ->
|
|
286
|
+
data[page] = {} unless data[page]
|
|
287
|
+
data[page][@id] = @getValue() or ""
|
|
288
|
+
return
|
|
289
|
+
|
|
290
|
+
commitPopupParams = (data) ->
|
|
291
|
+
commitParams.call this, "target", data
|
|
292
|
+
|
|
293
|
+
commitAdvParams = (data) ->
|
|
294
|
+
commitParams.call this, "adv", data
|
|
295
|
+
|
|
296
|
+
emailProtection = editor.config.emailProtection or ""
|
|
297
|
+
if emailProtection and emailProtection isnt "encode"
|
|
298
|
+
compiledProtectionFunction = {}
|
|
299
|
+
emailProtection.replace /^([^(]+)\(([^)]+)\)$/, (match, funcName, params) ->
|
|
300
|
+
compiledProtectionFunction.name = funcName
|
|
301
|
+
compiledProtectionFunction.params = []
|
|
302
|
+
params.replace /[^,\s]+/g, (param) ->
|
|
303
|
+
compiledProtectionFunction.params.push param
|
|
304
|
+
return
|
|
305
|
+
|
|
306
|
+
return
|
|
307
|
+
|
|
308
|
+
commonLang = editor.lang.common
|
|
309
|
+
linkLang = editor.lang.adv_link # modified by simo
|
|
310
|
+
title: linkLang.title
|
|
311
|
+
minWidth: 350
|
|
312
|
+
minHeight: 230
|
|
313
|
+
contents: [
|
|
314
|
+
{
|
|
315
|
+
id: "info"
|
|
316
|
+
label: linkLang.info
|
|
317
|
+
title: linkLang.info
|
|
318
|
+
elements: [
|
|
319
|
+
{
|
|
320
|
+
id: "linkType"
|
|
321
|
+
type: "select"
|
|
322
|
+
label: linkLang.type
|
|
323
|
+
default: "url"
|
|
324
|
+
items: [
|
|
325
|
+
[
|
|
326
|
+
linkLang.toUrl
|
|
327
|
+
"url"
|
|
328
|
+
]
|
|
329
|
+
[ # added by @simo - http://blog.xoundboy.com/?p=393
|
|
330
|
+
linkLang.localPages
|
|
331
|
+
"localPage"
|
|
332
|
+
]
|
|
333
|
+
[
|
|
334
|
+
linkLang.toAnchor
|
|
335
|
+
"anchor"
|
|
336
|
+
]
|
|
337
|
+
[
|
|
338
|
+
linkLang.toEmail
|
|
339
|
+
"email"
|
|
340
|
+
]
|
|
341
|
+
]
|
|
342
|
+
onChange: linkTypeChanged
|
|
343
|
+
setup: (data) ->
|
|
344
|
+
@setValue data.type if data.type
|
|
345
|
+
return
|
|
346
|
+
|
|
347
|
+
commit: (data) ->
|
|
348
|
+
data.type = @getValue()
|
|
349
|
+
return
|
|
350
|
+
}
|
|
351
|
+
{
|
|
352
|
+
|
|
353
|
+
# added by @simo - http://blog.xoundboy.com/?p=393
|
|
354
|
+
# see also : http://docs.ckeditor.com/source/dialogDefinition.html#CKEDITOR-dialog-definition-uiElement-property-type
|
|
355
|
+
# http://docs.ckeditor.com/#!/guide/plugin_sdk_sample_1
|
|
356
|
+
type: "vbox"
|
|
357
|
+
id: "localPageOptions"
|
|
358
|
+
children: [
|
|
359
|
+
type: "select"
|
|
360
|
+
label: linkLang.selectPageLabel
|
|
361
|
+
id: "localPage"
|
|
362
|
+
title: linkLang.selectPageTitle
|
|
363
|
+
|
|
364
|
+
# items: eval(decodeURIComponent(document.getElementById("pageListJSON").value)),
|
|
365
|
+
items: []
|
|
366
|
+
onLoad: (element) ->
|
|
367
|
+
element_id = "#" + @getInputElement().$.id
|
|
368
|
+
|
|
369
|
+
# ajax call indpired from http://stackoverflow.com/questions/5293920/ckeditor-dynamic-select-in-a-dialog
|
|
370
|
+
$.ajax
|
|
371
|
+
type: "GET"
|
|
372
|
+
|
|
373
|
+
#contentType: 'application/json; charset=utf-8',
|
|
374
|
+
url: "/" + getParameterByName("content_locale", document.location.href) + "/api/pages.json"
|
|
375
|
+
dataType: "json"
|
|
376
|
+
async: false
|
|
377
|
+
success: (data) ->
|
|
378
|
+
$.each data, (index, item) ->
|
|
379
|
+
$(element_id).get(0).options[$(element_id).get(0).options.length] = new Option(decodeURIComponent(item.title) + ': ' + item.pretty_url, item.url)
|
|
380
|
+
return
|
|
381
|
+
|
|
382
|
+
return
|
|
383
|
+
|
|
384
|
+
error: (xhr, ajaxOptions, thrownError) ->
|
|
385
|
+
alert xhr.status
|
|
386
|
+
alert thrownError
|
|
387
|
+
return
|
|
388
|
+
|
|
389
|
+
return
|
|
390
|
+
|
|
391
|
+
commit: (data) ->
|
|
392
|
+
data.localPage = {} unless data.localPage
|
|
393
|
+
data.localPage = @getValue()
|
|
394
|
+
return
|
|
395
|
+
]
|
|
396
|
+
}
|
|
397
|
+
{
|
|
398
|
+
|
|
399
|
+
# added by @simo - end
|
|
400
|
+
type: "vbox"
|
|
401
|
+
id: "urlOptions"
|
|
402
|
+
children: [
|
|
403
|
+
{
|
|
404
|
+
type: "hbox"
|
|
405
|
+
widths: [
|
|
406
|
+
"25%"
|
|
407
|
+
"75%"
|
|
408
|
+
]
|
|
409
|
+
children: [
|
|
410
|
+
{
|
|
411
|
+
id: "protocol"
|
|
412
|
+
type: "select"
|
|
413
|
+
label: commonLang.protocol
|
|
414
|
+
default: "http://"
|
|
415
|
+
items: [
|
|
416
|
+
|
|
417
|
+
# Force 'ltr' for protocol names in BIDI. (#5433)
|
|
418
|
+
[
|
|
419
|
+
"http://"
|
|
420
|
+
"http://"
|
|
421
|
+
]
|
|
422
|
+
[
|
|
423
|
+
"https://"
|
|
424
|
+
"https://"
|
|
425
|
+
]
|
|
426
|
+
[
|
|
427
|
+
"ftp://"
|
|
428
|
+
"ftp://"
|
|
429
|
+
]
|
|
430
|
+
[
|
|
431
|
+
"news://"
|
|
432
|
+
"news://"
|
|
433
|
+
]
|
|
434
|
+
[
|
|
435
|
+
linkLang.other
|
|
436
|
+
""
|
|
437
|
+
]
|
|
438
|
+
]
|
|
439
|
+
setup: (data) ->
|
|
440
|
+
@setValue data.url.protocol or "" if data.url
|
|
441
|
+
return
|
|
442
|
+
|
|
443
|
+
commit: (data) ->
|
|
444
|
+
data.url = {} unless data.url
|
|
445
|
+
data.url.protocol = @getValue()
|
|
446
|
+
return
|
|
447
|
+
}
|
|
448
|
+
{
|
|
449
|
+
type: "text"
|
|
450
|
+
id: "url"
|
|
451
|
+
label: commonLang.url
|
|
452
|
+
required: true
|
|
453
|
+
onLoad: ->
|
|
454
|
+
@allowOnChange = true
|
|
455
|
+
return
|
|
456
|
+
|
|
457
|
+
onKeyUp: ->
|
|
458
|
+
@allowOnChange = false
|
|
459
|
+
protocolCmb = @getDialog().getContentElement("info", "protocol")
|
|
460
|
+
url = @getValue()
|
|
461
|
+
urlOnChangeProtocol = /^(http|https|ftp|news):\/\/(?=.)/i
|
|
462
|
+
urlOnChangeTestOther = /^((javascript:)|[#\/\.\?])/i
|
|
463
|
+
protocol = urlOnChangeProtocol.exec(url)
|
|
464
|
+
if protocol
|
|
465
|
+
@setValue url.substr(protocol[0].length)
|
|
466
|
+
protocolCmb.setValue protocol[0].toLowerCase()
|
|
467
|
+
else protocolCmb.setValue "" if urlOnChangeTestOther.test(url)
|
|
468
|
+
@allowOnChange = true
|
|
469
|
+
return
|
|
470
|
+
|
|
471
|
+
onChange: ->
|
|
472
|
+
# Dont't call on dialog load.
|
|
473
|
+
@onKeyUp() if @allowOnChange
|
|
474
|
+
return
|
|
475
|
+
|
|
476
|
+
validate: ->
|
|
477
|
+
dialog = @getDialog()
|
|
478
|
+
return true if dialog.getContentElement("info", "linkType") and dialog.getValueOf("info", "linkType") isnt "url"
|
|
479
|
+
if (/javascript\:/).test(@getValue())
|
|
480
|
+
alert commonLang.invalidValue
|
|
481
|
+
return false
|
|
482
|
+
# Edit Anchor.
|
|
483
|
+
return true if @getDialog().fakeObj
|
|
484
|
+
func = CKEDITOR.dialog.validate.notEmpty(linkLang.noUrl)
|
|
485
|
+
func.apply this
|
|
486
|
+
|
|
487
|
+
setup: (data) ->
|
|
488
|
+
@allowOnChange = false
|
|
489
|
+
@setValue data.url.url if data.url
|
|
490
|
+
@allowOnChange = true
|
|
491
|
+
return
|
|
492
|
+
|
|
493
|
+
commit: (data) ->
|
|
494
|
+
|
|
495
|
+
# IE will not trigger the onChange event if the mouse has been used
|
|
496
|
+
# to carry all the operations #4724
|
|
497
|
+
@onChange()
|
|
498
|
+
data.url = {} unless data.url
|
|
499
|
+
data.url.url = @getValue()
|
|
500
|
+
@allowOnChange = false
|
|
501
|
+
return
|
|
502
|
+
}
|
|
503
|
+
]
|
|
504
|
+
setup: (data) ->
|
|
505
|
+
@getElement().show() unless @getDialog().getContentElement("info", "linkType")
|
|
506
|
+
return
|
|
507
|
+
}
|
|
508
|
+
{
|
|
509
|
+
type: "button"
|
|
510
|
+
id: "browse"
|
|
511
|
+
hidden: "true"
|
|
512
|
+
filebrowser: "info:url"
|
|
513
|
+
label: commonLang.browseServer
|
|
514
|
+
}
|
|
515
|
+
]
|
|
516
|
+
}
|
|
517
|
+
{
|
|
518
|
+
type: "vbox"
|
|
519
|
+
id: "anchorOptions"
|
|
520
|
+
width: 260
|
|
521
|
+
align: "center"
|
|
522
|
+
padding: 0
|
|
523
|
+
children: [
|
|
524
|
+
{
|
|
525
|
+
type: "fieldset"
|
|
526
|
+
id: "selectAnchorText"
|
|
527
|
+
label: linkLang.selectAnchor
|
|
528
|
+
setup: (data) ->
|
|
529
|
+
if data.anchors.length > 0
|
|
530
|
+
@getElement().show()
|
|
531
|
+
else
|
|
532
|
+
@getElement().hide()
|
|
533
|
+
return
|
|
534
|
+
|
|
535
|
+
children: [
|
|
536
|
+
type: "hbox"
|
|
537
|
+
id: "selectAnchor"
|
|
538
|
+
children: [
|
|
539
|
+
{
|
|
540
|
+
type: "select"
|
|
541
|
+
id: "anchorName"
|
|
542
|
+
default: ""
|
|
543
|
+
label: linkLang.anchorName
|
|
544
|
+
style: "width: 100%;"
|
|
545
|
+
items: [[""]]
|
|
546
|
+
setup: (data) ->
|
|
547
|
+
@clear()
|
|
548
|
+
@add ""
|
|
549
|
+
i = 0
|
|
550
|
+
|
|
551
|
+
while i < data.anchors.length
|
|
552
|
+
@add data.anchors[i].name if data.anchors[i].name
|
|
553
|
+
i++
|
|
554
|
+
@setValue data.anchor.name if data.anchor
|
|
555
|
+
linkType = @getDialog().getContentElement("info", "linkType")
|
|
556
|
+
@focus() if linkType and linkType.getValue() is "email"
|
|
557
|
+
return
|
|
558
|
+
|
|
559
|
+
commit: (data) ->
|
|
560
|
+
data.anchor = {} unless data.anchor
|
|
561
|
+
data.anchor.name = @getValue()
|
|
562
|
+
return
|
|
563
|
+
}
|
|
564
|
+
{
|
|
565
|
+
type: "select"
|
|
566
|
+
id: "anchorId"
|
|
567
|
+
default: ""
|
|
568
|
+
label: linkLang.anchorId
|
|
569
|
+
style: "width: 100%;"
|
|
570
|
+
items: [[""]]
|
|
571
|
+
setup: (data) ->
|
|
572
|
+
@clear()
|
|
573
|
+
@add ""
|
|
574
|
+
i = 0
|
|
575
|
+
|
|
576
|
+
while i < data.anchors.length
|
|
577
|
+
@add data.anchors[i].id if data.anchors[i].id
|
|
578
|
+
i++
|
|
579
|
+
@setValue data.anchor.id if data.anchor
|
|
580
|
+
return
|
|
581
|
+
|
|
582
|
+
commit: (data) ->
|
|
583
|
+
data.anchor = {} unless data.anchor
|
|
584
|
+
data.anchor.id = @getValue()
|
|
585
|
+
return
|
|
586
|
+
}
|
|
587
|
+
]
|
|
588
|
+
setup: (data) ->
|
|
589
|
+
if data.anchors.length > 0
|
|
590
|
+
@getElement().show()
|
|
591
|
+
else
|
|
592
|
+
@getElement().hide()
|
|
593
|
+
return
|
|
594
|
+
]
|
|
595
|
+
}
|
|
596
|
+
{
|
|
597
|
+
type: "html"
|
|
598
|
+
id: "noAnchors"
|
|
599
|
+
style: "text-align: center;"
|
|
600
|
+
html: "<div role=\"note\" tabIndex=\"-1\">" + CKEDITOR.tools.htmlEncode(linkLang.noAnchors) + "</div>"
|
|
601
|
+
|
|
602
|
+
# Focus the first element defined in above html.
|
|
603
|
+
focus: true
|
|
604
|
+
setup: (data) ->
|
|
605
|
+
if data.anchors.length < 1
|
|
606
|
+
@getElement().show()
|
|
607
|
+
else
|
|
608
|
+
@getElement().hide()
|
|
609
|
+
return
|
|
610
|
+
}
|
|
611
|
+
]
|
|
612
|
+
setup: (data) ->
|
|
613
|
+
@getElement().hide() unless @getDialog().getContentElement("info", "linkType")
|
|
614
|
+
return
|
|
615
|
+
}
|
|
616
|
+
{
|
|
617
|
+
type: "vbox"
|
|
618
|
+
id: "emailOptions"
|
|
619
|
+
padding: 1
|
|
620
|
+
children: [
|
|
621
|
+
{
|
|
622
|
+
type: "text"
|
|
623
|
+
id: "emailAddress"
|
|
624
|
+
label: linkLang.emailAddress
|
|
625
|
+
required: true
|
|
626
|
+
validate: ->
|
|
627
|
+
dialog = @getDialog()
|
|
628
|
+
return true if not dialog.getContentElement("info", "linkType") or dialog.getValueOf("info", "linkType") isnt "email"
|
|
629
|
+
func = CKEDITOR.dialog.validate.notEmpty(linkLang.noEmail)
|
|
630
|
+
func.apply this
|
|
631
|
+
|
|
632
|
+
setup: (data) ->
|
|
633
|
+
@setValue data.email.address if data.email
|
|
634
|
+
linkType = @getDialog().getContentElement("info", "linkType")
|
|
635
|
+
@select() if linkType and linkType.getValue() is "email"
|
|
636
|
+
return
|
|
637
|
+
|
|
638
|
+
commit: (data) ->
|
|
639
|
+
data.email = {} unless data.email
|
|
640
|
+
data.email.address = @getValue()
|
|
641
|
+
return
|
|
642
|
+
}
|
|
643
|
+
{
|
|
644
|
+
type: "text"
|
|
645
|
+
id: "emailSubject"
|
|
646
|
+
label: linkLang.emailSubject
|
|
647
|
+
setup: (data) ->
|
|
648
|
+
@setValue data.email.subject if data.email
|
|
649
|
+
return
|
|
650
|
+
|
|
651
|
+
commit: (data) ->
|
|
652
|
+
data.email = {} unless data.email
|
|
653
|
+
data.email.subject = @getValue()
|
|
654
|
+
return
|
|
655
|
+
}
|
|
656
|
+
{
|
|
657
|
+
type: "textarea"
|
|
658
|
+
id: "emailBody"
|
|
659
|
+
label: linkLang.emailBody
|
|
660
|
+
rows: 3
|
|
661
|
+
default: ""
|
|
662
|
+
setup: (data) ->
|
|
663
|
+
@setValue data.email.body if data.email
|
|
664
|
+
return
|
|
665
|
+
|
|
666
|
+
commit: (data) ->
|
|
667
|
+
data.email = {} unless data.email
|
|
668
|
+
data.email.body = @getValue()
|
|
669
|
+
return
|
|
670
|
+
}
|
|
671
|
+
]
|
|
672
|
+
setup: (data) ->
|
|
673
|
+
@getElement().hide() unless @getDialog().getContentElement("info", "linkType")
|
|
674
|
+
return
|
|
675
|
+
}
|
|
676
|
+
]
|
|
677
|
+
}
|
|
678
|
+
{
|
|
679
|
+
id: "target"
|
|
680
|
+
requiredContent: "a[target]" # This is not fully correct, because some target option requires JS.
|
|
681
|
+
label: linkLang.target
|
|
682
|
+
title: linkLang.target
|
|
683
|
+
elements: [
|
|
684
|
+
{
|
|
685
|
+
type: "hbox"
|
|
686
|
+
widths: [
|
|
687
|
+
"50%"
|
|
688
|
+
"50%"
|
|
689
|
+
]
|
|
690
|
+
children: [
|
|
691
|
+
{
|
|
692
|
+
type: "select"
|
|
693
|
+
id: "linkTargetType"
|
|
694
|
+
label: commonLang.target
|
|
695
|
+
default: "notSet"
|
|
696
|
+
style: "width : 100%;"
|
|
697
|
+
items: [
|
|
698
|
+
[
|
|
699
|
+
commonLang.notSet
|
|
700
|
+
"notSet"
|
|
701
|
+
]
|
|
702
|
+
[
|
|
703
|
+
linkLang.targetFrame
|
|
704
|
+
"frame"
|
|
705
|
+
]
|
|
706
|
+
[
|
|
707
|
+
linkLang.targetPopup
|
|
708
|
+
"popup"
|
|
709
|
+
]
|
|
710
|
+
[
|
|
711
|
+
commonLang.targetNew
|
|
712
|
+
"_blank"
|
|
713
|
+
]
|
|
714
|
+
[
|
|
715
|
+
commonLang.targetTop
|
|
716
|
+
"_top"
|
|
717
|
+
]
|
|
718
|
+
[
|
|
719
|
+
commonLang.targetSelf
|
|
720
|
+
"_self"
|
|
721
|
+
]
|
|
722
|
+
[
|
|
723
|
+
commonLang.targetParent
|
|
724
|
+
"_parent"
|
|
725
|
+
]
|
|
726
|
+
]
|
|
727
|
+
onChange: targetChanged
|
|
728
|
+
setup: (data) ->
|
|
729
|
+
@setValue data.target.type or "notSet" if data.target
|
|
730
|
+
targetChanged.call this
|
|
731
|
+
return
|
|
732
|
+
|
|
733
|
+
commit: (data) ->
|
|
734
|
+
data.target = {} unless data.target
|
|
735
|
+
data.target.type = @getValue()
|
|
736
|
+
return
|
|
737
|
+
}
|
|
738
|
+
{
|
|
739
|
+
type: "text"
|
|
740
|
+
id: "linkTargetName"
|
|
741
|
+
label: linkLang.targetFrameName
|
|
742
|
+
default: ""
|
|
743
|
+
setup: (data) ->
|
|
744
|
+
@setValue data.target.name if data.target
|
|
745
|
+
return
|
|
746
|
+
|
|
747
|
+
commit: (data) ->
|
|
748
|
+
data.target = {} unless data.target
|
|
749
|
+
data.target.name = @getValue().replace(/\W/g, "")
|
|
750
|
+
return
|
|
751
|
+
}
|
|
752
|
+
]
|
|
753
|
+
}
|
|
754
|
+
{
|
|
755
|
+
type: "vbox"
|
|
756
|
+
width: "100%"
|
|
757
|
+
align: "center"
|
|
758
|
+
padding: 2
|
|
759
|
+
id: "popupFeatures"
|
|
760
|
+
children: [
|
|
761
|
+
type: "fieldset"
|
|
762
|
+
label: linkLang.popupFeatures
|
|
763
|
+
children: [
|
|
764
|
+
{
|
|
765
|
+
type: "hbox"
|
|
766
|
+
children: [
|
|
767
|
+
{
|
|
768
|
+
type: "checkbox"
|
|
769
|
+
id: "resizable"
|
|
770
|
+
label: linkLang.popupResizable
|
|
771
|
+
setup: setupPopupParams
|
|
772
|
+
commit: commitPopupParams
|
|
773
|
+
}
|
|
774
|
+
{
|
|
775
|
+
type: "checkbox"
|
|
776
|
+
id: "status"
|
|
777
|
+
label: linkLang.popupStatusBar
|
|
778
|
+
setup: setupPopupParams
|
|
779
|
+
commit: commitPopupParams
|
|
780
|
+
}
|
|
781
|
+
]
|
|
782
|
+
}
|
|
783
|
+
{
|
|
784
|
+
type: "hbox"
|
|
785
|
+
children: [
|
|
786
|
+
{
|
|
787
|
+
type: "checkbox"
|
|
788
|
+
id: "location"
|
|
789
|
+
label: linkLang.popupLocationBar
|
|
790
|
+
setup: setupPopupParams
|
|
791
|
+
commit: commitPopupParams
|
|
792
|
+
}
|
|
793
|
+
{
|
|
794
|
+
type: "checkbox"
|
|
795
|
+
id: "toolbar"
|
|
796
|
+
label: linkLang.popupToolbar
|
|
797
|
+
setup: setupPopupParams
|
|
798
|
+
commit: commitPopupParams
|
|
799
|
+
}
|
|
800
|
+
]
|
|
801
|
+
}
|
|
802
|
+
{
|
|
803
|
+
type: "hbox"
|
|
804
|
+
children: [
|
|
805
|
+
{
|
|
806
|
+
type: "checkbox"
|
|
807
|
+
id: "menubar"
|
|
808
|
+
label: linkLang.popupMenuBar
|
|
809
|
+
setup: setupPopupParams
|
|
810
|
+
commit: commitPopupParams
|
|
811
|
+
}
|
|
812
|
+
{
|
|
813
|
+
type: "checkbox"
|
|
814
|
+
id: "fullscreen"
|
|
815
|
+
label: linkLang.popupFullScreen
|
|
816
|
+
setup: setupPopupParams
|
|
817
|
+
commit: commitPopupParams
|
|
818
|
+
}
|
|
819
|
+
]
|
|
820
|
+
}
|
|
821
|
+
{
|
|
822
|
+
type: "hbox"
|
|
823
|
+
children: [
|
|
824
|
+
{
|
|
825
|
+
type: "checkbox"
|
|
826
|
+
id: "scrollbars"
|
|
827
|
+
label: linkLang.popupScrollBars
|
|
828
|
+
setup: setupPopupParams
|
|
829
|
+
commit: commitPopupParams
|
|
830
|
+
}
|
|
831
|
+
{
|
|
832
|
+
type: "checkbox"
|
|
833
|
+
id: "dependent"
|
|
834
|
+
label: linkLang.popupDependent
|
|
835
|
+
setup: setupPopupParams
|
|
836
|
+
commit: commitPopupParams
|
|
837
|
+
}
|
|
838
|
+
]
|
|
839
|
+
}
|
|
840
|
+
{
|
|
841
|
+
type: "hbox"
|
|
842
|
+
children: [
|
|
843
|
+
{
|
|
844
|
+
type: "text"
|
|
845
|
+
widths: [
|
|
846
|
+
"50%"
|
|
847
|
+
"50%"
|
|
848
|
+
]
|
|
849
|
+
labelLayout: "horizontal"
|
|
850
|
+
label: commonLang.width
|
|
851
|
+
id: "width"
|
|
852
|
+
setup: setupPopupParams
|
|
853
|
+
commit: commitPopupParams
|
|
854
|
+
}
|
|
855
|
+
{
|
|
856
|
+
type: "text"
|
|
857
|
+
labelLayout: "horizontal"
|
|
858
|
+
widths: [
|
|
859
|
+
"50%"
|
|
860
|
+
"50%"
|
|
861
|
+
]
|
|
862
|
+
label: linkLang.popupLeft
|
|
863
|
+
id: "left"
|
|
864
|
+
setup: setupPopupParams
|
|
865
|
+
commit: commitPopupParams
|
|
866
|
+
}
|
|
867
|
+
]
|
|
868
|
+
}
|
|
869
|
+
{
|
|
870
|
+
type: "hbox"
|
|
871
|
+
children: [
|
|
872
|
+
{
|
|
873
|
+
type: "text"
|
|
874
|
+
labelLayout: "horizontal"
|
|
875
|
+
widths: [
|
|
876
|
+
"50%"
|
|
877
|
+
"50%"
|
|
878
|
+
]
|
|
879
|
+
label: commonLang.height
|
|
880
|
+
id: "height"
|
|
881
|
+
setup: setupPopupParams
|
|
882
|
+
commit: commitPopupParams
|
|
883
|
+
}
|
|
884
|
+
{
|
|
885
|
+
type: "text"
|
|
886
|
+
labelLayout: "horizontal"
|
|
887
|
+
label: linkLang.popupTop
|
|
888
|
+
widths: [
|
|
889
|
+
"50%"
|
|
890
|
+
"50%"
|
|
891
|
+
]
|
|
892
|
+
id: "top"
|
|
893
|
+
setup: setupPopupParams
|
|
894
|
+
commit: commitPopupParams
|
|
895
|
+
}
|
|
896
|
+
]
|
|
897
|
+
}
|
|
898
|
+
]
|
|
899
|
+
]
|
|
900
|
+
}
|
|
901
|
+
]
|
|
902
|
+
}
|
|
903
|
+
{
|
|
904
|
+
id: "upload"
|
|
905
|
+
label: linkLang.upload
|
|
906
|
+
title: linkLang.upload
|
|
907
|
+
hidden: true
|
|
908
|
+
filebrowser: "uploadButton"
|
|
909
|
+
elements: [
|
|
910
|
+
{
|
|
911
|
+
type: "file"
|
|
912
|
+
id: "upload"
|
|
913
|
+
label: commonLang.upload
|
|
914
|
+
style: "height:40px"
|
|
915
|
+
size: 29
|
|
916
|
+
}
|
|
917
|
+
{
|
|
918
|
+
type: "fileButton"
|
|
919
|
+
id: "uploadButton"
|
|
920
|
+
label: commonLang.uploadSubmit
|
|
921
|
+
filebrowser: "info:url"
|
|
922
|
+
for: [
|
|
923
|
+
"upload"
|
|
924
|
+
"upload"
|
|
925
|
+
]
|
|
926
|
+
}
|
|
927
|
+
]
|
|
928
|
+
}
|
|
929
|
+
{
|
|
930
|
+
id: "advanced"
|
|
931
|
+
label: linkLang.advanced
|
|
932
|
+
title: linkLang.advanced
|
|
933
|
+
elements: [
|
|
934
|
+
{
|
|
935
|
+
type: "vbox"
|
|
936
|
+
padding: 1
|
|
937
|
+
children: [
|
|
938
|
+
{
|
|
939
|
+
type: "hbox"
|
|
940
|
+
widths: [
|
|
941
|
+
"45%"
|
|
942
|
+
"35%"
|
|
943
|
+
"20%"
|
|
944
|
+
]
|
|
945
|
+
children: [
|
|
946
|
+
{
|
|
947
|
+
type: "text"
|
|
948
|
+
id: "advId"
|
|
949
|
+
requiredContent: "a[id]"
|
|
950
|
+
label: linkLang.id
|
|
951
|
+
setup: setupAdvParams
|
|
952
|
+
commit: commitAdvParams
|
|
953
|
+
}
|
|
954
|
+
{
|
|
955
|
+
type: "select"
|
|
956
|
+
id: "advLangDir"
|
|
957
|
+
requiredContent: "a[dir]"
|
|
958
|
+
label: linkLang.langDir
|
|
959
|
+
default: ""
|
|
960
|
+
style: "width:110px"
|
|
961
|
+
items: [
|
|
962
|
+
[
|
|
963
|
+
commonLang.notSet
|
|
964
|
+
""
|
|
965
|
+
]
|
|
966
|
+
[
|
|
967
|
+
linkLang.langDirLTR
|
|
968
|
+
"ltr"
|
|
969
|
+
]
|
|
970
|
+
[
|
|
971
|
+
linkLang.langDirRTL
|
|
972
|
+
"rtl"
|
|
973
|
+
]
|
|
974
|
+
]
|
|
975
|
+
setup: setupAdvParams
|
|
976
|
+
commit: commitAdvParams
|
|
977
|
+
}
|
|
978
|
+
{
|
|
979
|
+
type: "text"
|
|
980
|
+
id: "advAccessKey"
|
|
981
|
+
requiredContent: "a[accesskey]"
|
|
982
|
+
width: "80px"
|
|
983
|
+
label: linkLang.acccessKey
|
|
984
|
+
maxLength: 1
|
|
985
|
+
setup: setupAdvParams
|
|
986
|
+
commit: commitAdvParams
|
|
987
|
+
}
|
|
988
|
+
]
|
|
989
|
+
}
|
|
990
|
+
{
|
|
991
|
+
type: "hbox"
|
|
992
|
+
widths: [
|
|
993
|
+
"45%"
|
|
994
|
+
"35%"
|
|
995
|
+
"20%"
|
|
996
|
+
]
|
|
997
|
+
children: [
|
|
998
|
+
{
|
|
999
|
+
type: "text"
|
|
1000
|
+
label: linkLang.name
|
|
1001
|
+
id: "advName"
|
|
1002
|
+
requiredContent: "a[name]"
|
|
1003
|
+
setup: setupAdvParams
|
|
1004
|
+
commit: commitAdvParams
|
|
1005
|
+
}
|
|
1006
|
+
{
|
|
1007
|
+
type: "text"
|
|
1008
|
+
label: linkLang.langCode
|
|
1009
|
+
id: "advLangCode"
|
|
1010
|
+
requiredContent: "a[lang]"
|
|
1011
|
+
width: "110px"
|
|
1012
|
+
default: ""
|
|
1013
|
+
setup: setupAdvParams
|
|
1014
|
+
commit: commitAdvParams
|
|
1015
|
+
}
|
|
1016
|
+
{
|
|
1017
|
+
type: "text"
|
|
1018
|
+
label: linkLang.tabIndex
|
|
1019
|
+
id: "advTabIndex"
|
|
1020
|
+
requiredContent: "a[tabindex]"
|
|
1021
|
+
width: "80px"
|
|
1022
|
+
maxLength: 5
|
|
1023
|
+
setup: setupAdvParams
|
|
1024
|
+
commit: commitAdvParams
|
|
1025
|
+
}
|
|
1026
|
+
]
|
|
1027
|
+
}
|
|
1028
|
+
]
|
|
1029
|
+
}
|
|
1030
|
+
{
|
|
1031
|
+
type: "vbox"
|
|
1032
|
+
padding: 1
|
|
1033
|
+
children: [
|
|
1034
|
+
{
|
|
1035
|
+
type: "hbox"
|
|
1036
|
+
widths: [
|
|
1037
|
+
"45%"
|
|
1038
|
+
"55%"
|
|
1039
|
+
]
|
|
1040
|
+
children: [
|
|
1041
|
+
{
|
|
1042
|
+
type: "text"
|
|
1043
|
+
label: linkLang.advisoryTitle
|
|
1044
|
+
requiredContent: "a[title]"
|
|
1045
|
+
default: ""
|
|
1046
|
+
id: "advTitle"
|
|
1047
|
+
setup: setupAdvParams
|
|
1048
|
+
commit: commitAdvParams
|
|
1049
|
+
}
|
|
1050
|
+
{
|
|
1051
|
+
type: "text"
|
|
1052
|
+
label: linkLang.advisoryContentType
|
|
1053
|
+
requiredContent: "a[type]"
|
|
1054
|
+
default: ""
|
|
1055
|
+
id: "advContentType"
|
|
1056
|
+
setup: setupAdvParams
|
|
1057
|
+
commit: commitAdvParams
|
|
1058
|
+
}
|
|
1059
|
+
]
|
|
1060
|
+
}
|
|
1061
|
+
{
|
|
1062
|
+
type: "hbox"
|
|
1063
|
+
widths: [
|
|
1064
|
+
"45%"
|
|
1065
|
+
"55%"
|
|
1066
|
+
]
|
|
1067
|
+
children: [
|
|
1068
|
+
{
|
|
1069
|
+
type: "text"
|
|
1070
|
+
label: linkLang.cssClasses
|
|
1071
|
+
requiredContent: "a(cke-xyz)" # Random text like 'xyz' will check if all are allowed.
|
|
1072
|
+
default: ""
|
|
1073
|
+
id: "advCSSClasses"
|
|
1074
|
+
setup: setupAdvParams
|
|
1075
|
+
commit: commitAdvParams
|
|
1076
|
+
}
|
|
1077
|
+
{
|
|
1078
|
+
type: "text"
|
|
1079
|
+
label: linkLang.charset
|
|
1080
|
+
requiredContent: "a[charset]"
|
|
1081
|
+
default: ""
|
|
1082
|
+
id: "advCharset"
|
|
1083
|
+
setup: setupAdvParams
|
|
1084
|
+
commit: commitAdvParams
|
|
1085
|
+
}
|
|
1086
|
+
]
|
|
1087
|
+
}
|
|
1088
|
+
{
|
|
1089
|
+
type: "hbox"
|
|
1090
|
+
widths: [
|
|
1091
|
+
"45%"
|
|
1092
|
+
"55%"
|
|
1093
|
+
]
|
|
1094
|
+
children: [
|
|
1095
|
+
{
|
|
1096
|
+
type: "text"
|
|
1097
|
+
label: linkLang.rel
|
|
1098
|
+
requiredContent: "a[rel]"
|
|
1099
|
+
default: ""
|
|
1100
|
+
id: "advRel"
|
|
1101
|
+
setup: setupAdvParams
|
|
1102
|
+
commit: commitAdvParams
|
|
1103
|
+
}
|
|
1104
|
+
{
|
|
1105
|
+
type: "text"
|
|
1106
|
+
label: linkLang.styles
|
|
1107
|
+
requiredContent: "a{cke-xyz}" # Random text like 'xyz' will check if all are allowed.
|
|
1108
|
+
default: ""
|
|
1109
|
+
id: "advStyles"
|
|
1110
|
+
validate: CKEDITOR.dialog.validate.inlineStyle(editor.lang.common.invalidInlineStyle)
|
|
1111
|
+
setup: setupAdvParams
|
|
1112
|
+
commit: commitAdvParams
|
|
1113
|
+
}
|
|
1114
|
+
]
|
|
1115
|
+
}
|
|
1116
|
+
]
|
|
1117
|
+
}
|
|
1118
|
+
]
|
|
1119
|
+
}
|
|
1120
|
+
]
|
|
1121
|
+
onShow: ->
|
|
1122
|
+
editor = @getParentEditor()
|
|
1123
|
+
selection = editor.getSelection()
|
|
1124
|
+
element = null
|
|
1125
|
+
|
|
1126
|
+
# Fill in all the relevant fields if there's already one link selected.
|
|
1127
|
+
if (element = plugin.getSelectedLink(editor)) and element.hasAttribute("href")
|
|
1128
|
+
selection.selectElement element
|
|
1129
|
+
else
|
|
1130
|
+
element = null
|
|
1131
|
+
@setupContent parseLink.apply(this, [
|
|
1132
|
+
editor
|
|
1133
|
+
element
|
|
1134
|
+
])
|
|
1135
|
+
return
|
|
1136
|
+
|
|
1137
|
+
onOk: ->
|
|
1138
|
+
attributes = {}
|
|
1139
|
+
removeAttributes = []
|
|
1140
|
+
data = {}
|
|
1141
|
+
me = this
|
|
1142
|
+
editor = @getParentEditor()
|
|
1143
|
+
@commitContent data
|
|
1144
|
+
|
|
1145
|
+
# Compose the URL.
|
|
1146
|
+
switch data.type or "url"
|
|
1147
|
+
when "url"
|
|
1148
|
+
protocol = (if (data.url and data.url.protocol isnt `undefined`) then data.url.protocol else "http://")
|
|
1149
|
+
url = (data.url and CKEDITOR.tools.trim(data.url.url)) or ""
|
|
1150
|
+
attributes["data-cke-saved-href"] = (if (url.indexOf("/") is 0) then url else protocol + url)
|
|
1151
|
+
when "localPage" # added by @simo - http://blog.xoundboy.com/?p=393
|
|
1152
|
+
attributes["data-cke-saved-href"] = data.localPage
|
|
1153
|
+
when "anchor"
|
|
1154
|
+
name = (data.anchor and data.anchor.name)
|
|
1155
|
+
id = (data.anchor and data.anchor.id)
|
|
1156
|
+
attributes["data-cke-saved-href"] = "#" + (name or id or "")
|
|
1157
|
+
when "email"
|
|
1158
|
+
linkHref = undefined
|
|
1159
|
+
email = data.email
|
|
1160
|
+
address = email.address
|
|
1161
|
+
switch emailProtection
|
|
1162
|
+
when "", "encode"
|
|
1163
|
+
subject = encodeURIComponent(email.subject or "")
|
|
1164
|
+
body = encodeURIComponent(email.body or "")
|
|
1165
|
+
|
|
1166
|
+
# Build the e-mail parameters first.
|
|
1167
|
+
argList = []
|
|
1168
|
+
subject and argList.push("subject=" + subject)
|
|
1169
|
+
body and argList.push("body=" + body)
|
|
1170
|
+
argList = (if argList.length then "?" + argList.join("&") else "")
|
|
1171
|
+
if emailProtection is "encode"
|
|
1172
|
+
linkHref = [
|
|
1173
|
+
"javascript:void(location.href='mailto:'+"
|
|
1174
|
+
protectEmailAddressAsEncodedString(address)
|
|
1175
|
+
]
|
|
1176
|
+
|
|
1177
|
+
# parameters are optional.
|
|
1178
|
+
argList and linkHref.push("+'", escapeSingleQuote(argList), "'")
|
|
1179
|
+
linkHref.push ")"
|
|
1180
|
+
else
|
|
1181
|
+
linkHref = [
|
|
1182
|
+
"mailto:"
|
|
1183
|
+
address
|
|
1184
|
+
argList
|
|
1185
|
+
]
|
|
1186
|
+
break
|
|
1187
|
+
else
|
|
1188
|
+
|
|
1189
|
+
# Separating name and domain.
|
|
1190
|
+
nameAndDomain = address.split("@", 2)
|
|
1191
|
+
email.name = nameAndDomain[0]
|
|
1192
|
+
email.domain = nameAndDomain[1]
|
|
1193
|
+
linkHref = [
|
|
1194
|
+
"javascript:"
|
|
1195
|
+
protectEmailLinkAsFunction(email)
|
|
1196
|
+
]
|
|
1197
|
+
attributes["data-cke-saved-href"] = linkHref.join("")
|
|
1198
|
+
|
|
1199
|
+
# Popups and target.
|
|
1200
|
+
if data.target
|
|
1201
|
+
if data.target.type is "popup"
|
|
1202
|
+
onclickList = [
|
|
1203
|
+
"window.open(this.href, '"
|
|
1204
|
+
data.target.name or ""
|
|
1205
|
+
"', '"
|
|
1206
|
+
]
|
|
1207
|
+
featureList = [
|
|
1208
|
+
"resizable"
|
|
1209
|
+
"status"
|
|
1210
|
+
"location"
|
|
1211
|
+
"toolbar"
|
|
1212
|
+
"menubar"
|
|
1213
|
+
"fullscreen"
|
|
1214
|
+
"scrollbars"
|
|
1215
|
+
"dependent"
|
|
1216
|
+
]
|
|
1217
|
+
featureLength = featureList.length
|
|
1218
|
+
addFeature = (featureName) ->
|
|
1219
|
+
featureList.push featureName + "=" + data.target[featureName] if data.target[featureName]
|
|
1220
|
+
return
|
|
1221
|
+
|
|
1222
|
+
i = 0
|
|
1223
|
+
|
|
1224
|
+
while i < featureLength
|
|
1225
|
+
featureList[i] = featureList[i] + ((if data.target[featureList[i]] then "=yes" else "=no"))
|
|
1226
|
+
i++
|
|
1227
|
+
addFeature "width"
|
|
1228
|
+
addFeature "left"
|
|
1229
|
+
addFeature "height"
|
|
1230
|
+
addFeature "top"
|
|
1231
|
+
onclickList.push featureList.join(","), "'); return false;"
|
|
1232
|
+
attributes["data-cke-pa-onclick"] = onclickList.join("")
|
|
1233
|
+
|
|
1234
|
+
# Add the "target" attribute. (#5074)
|
|
1235
|
+
removeAttributes.push "target"
|
|
1236
|
+
else
|
|
1237
|
+
if data.target.type isnt "notSet" and data.target.name
|
|
1238
|
+
attributes.target = data.target.name
|
|
1239
|
+
else
|
|
1240
|
+
removeAttributes.push "target"
|
|
1241
|
+
removeAttributes.push "data-cke-pa-onclick", "onclick"
|
|
1242
|
+
|
|
1243
|
+
# Advanced attributes.
|
|
1244
|
+
if data.adv
|
|
1245
|
+
advAttr = (inputName, attrName) ->
|
|
1246
|
+
value = data.adv[inputName]
|
|
1247
|
+
if value
|
|
1248
|
+
attributes[attrName] = value
|
|
1249
|
+
else
|
|
1250
|
+
removeAttributes.push attrName
|
|
1251
|
+
return
|
|
1252
|
+
|
|
1253
|
+
advAttr "advId", "id"
|
|
1254
|
+
advAttr "advLangDir", "dir"
|
|
1255
|
+
advAttr "advAccessKey", "accessKey"
|
|
1256
|
+
if data.adv["advName"]
|
|
1257
|
+
attributes["name"] = attributes["data-cke-saved-name"] = data.adv["advName"]
|
|
1258
|
+
else
|
|
1259
|
+
removeAttributes = removeAttributes.concat([
|
|
1260
|
+
"data-cke-saved-name"
|
|
1261
|
+
"name"
|
|
1262
|
+
])
|
|
1263
|
+
advAttr "advLangCode", "lang"
|
|
1264
|
+
advAttr "advTabIndex", "tabindex"
|
|
1265
|
+
advAttr "advTitle", "title"
|
|
1266
|
+
advAttr "advContentType", "type"
|
|
1267
|
+
advAttr "advCSSClasses", "class"
|
|
1268
|
+
advAttr "advCharset", "charset"
|
|
1269
|
+
advAttr "advStyles", "style"
|
|
1270
|
+
advAttr "advRel", "rel"
|
|
1271
|
+
selection = editor.getSelection()
|
|
1272
|
+
|
|
1273
|
+
# Browser need the "href" fro copy/paste link to work. (#6641)
|
|
1274
|
+
attributes.href = attributes["data-cke-saved-href"]
|
|
1275
|
+
unless @_.selectedElement
|
|
1276
|
+
range = selection.getRanges(1)[0]
|
|
1277
|
+
|
|
1278
|
+
# Use link URL as text with a collapsed cursor.
|
|
1279
|
+
if range.collapsed
|
|
1280
|
+
|
|
1281
|
+
# Short mailto link text view (#5736).
|
|
1282
|
+
text = new CKEDITOR.dom.text((if data.type is "email" then data.email.address else attributes["data-cke-saved-href"]), editor.document)
|
|
1283
|
+
range.insertNode text
|
|
1284
|
+
range.selectNodeContents text
|
|
1285
|
+
|
|
1286
|
+
# Apply style.
|
|
1287
|
+
style = new CKEDITOR.style(
|
|
1288
|
+
element: "a"
|
|
1289
|
+
attributes: attributes
|
|
1290
|
+
)
|
|
1291
|
+
style.type = CKEDITOR.STYLE_INLINE # need to override... dunno why.
|
|
1292
|
+
style.applyToRange range
|
|
1293
|
+
range.select()
|
|
1294
|
+
else
|
|
1295
|
+
|
|
1296
|
+
# We're only editing an existing link, so just overwrite the attributes.
|
|
1297
|
+
element = @_.selectedElement
|
|
1298
|
+
href = element.data("cke-saved-href")
|
|
1299
|
+
textView = element.getHtml()
|
|
1300
|
+
element.setAttributes attributes
|
|
1301
|
+
element.removeAttributes removeAttributes
|
|
1302
|
+
element.addClass (if element.getChildCount() then "cke_anchor" else "cke_anchor_empty") if data.adv and data.adv.advName and CKEDITOR.plugins.link.synAnchorSelector
|
|
1303
|
+
|
|
1304
|
+
# Update text view when user changes protocol (#4612).
|
|
1305
|
+
|
|
1306
|
+
# Short mailto link text view (#5736).
|
|
1307
|
+
element.setHtml (if data.type is "email" then data.email.address else attributes["data-cke-saved-href"]) if href is textView or data.type is "email" and textView.indexOf("@") isnt -1
|
|
1308
|
+
selection.selectElement element
|
|
1309
|
+
delete @_.selectedElement
|
|
1310
|
+
return
|
|
1311
|
+
|
|
1312
|
+
onLoad: ->
|
|
1313
|
+
@hidePage "advanced" unless editor.config.linkShowAdvancedTab #Hide Advanded tab.
|
|
1314
|
+
@hidePage "target" unless editor.config.linkShowTargetTab #Hide Target tab.
|
|
1315
|
+
return
|
|
1316
|
+
|
|
1317
|
+
|
|
1318
|
+
# Inital focus on 'url' field if link is of type URL.
|
|
1319
|
+
onFocus: ->
|
|
1320
|
+
linkType = @getContentElement("info", "linkType")
|
|
1321
|
+
urlField = undefined
|
|
1322
|
+
if linkType and linkType.getValue() is "url"
|
|
1323
|
+
urlField = @getContentElement("info", "url")
|
|
1324
|
+
urlField.select()
|
|
1325
|
+
return
|
|
1326
|
+
|
|
1327
|
+
|
|
1328
|
+
# The e-mail address anti-spam protection option. The protection will be
|
|
1329
|
+
# applied when creating or modifying e-mail links through the editor interface.
|
|
1330
|
+
#
|
|
1331
|
+
# Two methods of protection can be choosed:
|
|
1332
|
+
#
|
|
1333
|
+
# 1. The e-mail parts (name, domain and any other query string) are
|
|
1334
|
+
# assembled into a function call pattern. Such function must be
|
|
1335
|
+
# provided by the developer in the pages that will use the contents.
|
|
1336
|
+
# 2. Only the e-mail address is obfuscated into a special string that
|
|
1337
|
+
# has no meaning for humans or spam bots, but which is properly
|
|
1338
|
+
# rendered and accepted by the browser.
|
|
1339
|
+
#
|
|
1340
|
+
# Both approaches require JavaScript to be enabled.
|
|
1341
|
+
#
|
|
1342
|
+
# // href="mailto:tester@ckeditor.com?subject=subject&body=body"
|
|
1343
|
+
# config.emailProtection = '';
|
|
1344
|
+
#
|
|
1345
|
+
# // href="<a href=\"javascript:void(location.href=\'mailto:\'+String.fromCharCode(116,101,115,116,101,114,64,99,107,101,100,105,116,111,114,46,99,111,109)+\'?subject=subject&body=body\')\">e-mail</a>"
|
|
1346
|
+
# config.emailProtection = 'encode';
|
|
1347
|
+
#
|
|
1348
|
+
# // href="javascript:mt('tester','ckeditor.com','subject','body')"
|
|
1349
|
+
# config.emailProtection = 'mt(NAME,DOMAIN,SUBJECT,BODY)';
|
|
1350
|
+
#
|
|
1351
|
+
# @since 3.1
|
|
1352
|
+
# @cfg {String} [emailProtection='' (empty string = disabled)]
|
|
1353
|
+
# @member CKEDITOR.config
|