1 | define([ |
---|
2 | "dojo", |
---|
3 | "dijit", |
---|
4 | "dojox", |
---|
5 | "dijit/_editor/_Plugin", |
---|
6 | "dijit/form/Button", |
---|
7 | "dijit/form/ToggleButton", |
---|
8 | "dojo/_base/connect", |
---|
9 | "dojo/_base/declare", |
---|
10 | "dojo/i18n", |
---|
11 | "dojo/i18n!dojox/editor/plugins/nls/ShowBlockNodes" |
---|
12 | ], function(dojo, dijit, dojox, _Plugin) { |
---|
13 | |
---|
14 | var ShowBlockNodes = dojo.declare("dojox.editor.plugins.ShowBlockNodes", _Plugin, { |
---|
15 | // summary: |
---|
16 | // This plugin provides ShowBlockNodes capability to the editor. When |
---|
17 | // clicked, the document in the editor will apply a class to specific |
---|
18 | // block nodes to make them visible in the layout. This info is not |
---|
19 | // exposed/extracted when the editor value is obtained, it is purely for help |
---|
20 | // while working on the page. |
---|
21 | |
---|
22 | // Over-ride indicating that the command processing is done all by this plugin. |
---|
23 | useDefaultCommand: false, |
---|
24 | |
---|
25 | // iconClassPrefix: [const] String |
---|
26 | // The CSS class name for the button node is formed from `iconClassPrefix` and `command` |
---|
27 | iconClassPrefix: "dijitAdditionalEditorIcon", |
---|
28 | |
---|
29 | // _styled: [private] boolean |
---|
30 | // Flag indicating the document has had the style updates applied. |
---|
31 | _styled: false, |
---|
32 | |
---|
33 | _initButton: function(){ |
---|
34 | // summary: |
---|
35 | // Over-ride for creation of the preview button. |
---|
36 | var strings = dojo.i18n.getLocalization("dojox.editor.plugins", "ShowBlockNodes"); |
---|
37 | this.button = new dijit.form.ToggleButton({ |
---|
38 | label: strings["showBlockNodes"], |
---|
39 | showLabel: false, |
---|
40 | iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "ShowBlockNodes", |
---|
41 | tabIndex: "-1", |
---|
42 | onChange: dojo.hitch(this, "_showBlocks") |
---|
43 | }); |
---|
44 | this.editor.addKeyHandler(dojo.keys.F9, true, true, dojo.hitch(this, this.toggle)); |
---|
45 | }, |
---|
46 | |
---|
47 | updateState: function(){ |
---|
48 | // summary: |
---|
49 | // Over-ride for button state control for disabled to work. |
---|
50 | this.button.set("disabled", this.get("disabled")); |
---|
51 | }, |
---|
52 | |
---|
53 | setEditor: function(editor){ |
---|
54 | // summary: |
---|
55 | // Over-ride for the setting of the editor. |
---|
56 | // editor: Object |
---|
57 | // The editor to configure for this plugin to use. |
---|
58 | this.editor = editor; |
---|
59 | this._initButton(); |
---|
60 | }, |
---|
61 | |
---|
62 | toggle: function(){ |
---|
63 | // summary: |
---|
64 | // Function to allow programmatic toggling of the view. |
---|
65 | this.button.set("checked", !this.button.get("checked")); |
---|
66 | }, |
---|
67 | |
---|
68 | _showBlocks: function(show){ |
---|
69 | // summary: |
---|
70 | // Function to trigger printing of the editor document |
---|
71 | // tags: |
---|
72 | // private |
---|
73 | var doc = this.editor.document; |
---|
74 | if(!this._styled){ |
---|
75 | try{ |
---|
76 | //Attempt to inject our specialized style rules for doing this. |
---|
77 | this._styled = true; |
---|
78 | |
---|
79 | var style = ""; |
---|
80 | var blocks = ["div", "p", "ul", "ol", "table", "h1", |
---|
81 | "h2", "h3", "h4", "h5", "h6", "pre", "dir", "center", |
---|
82 | "blockquote", "form", "fieldset", "address", "object", |
---|
83 | "pre", "hr", "ins", "noscript", "li", "map", "button", |
---|
84 | "dd", "dt"]; |
---|
85 | |
---|
86 | var template = "@media screen {\n" + |
---|
87 | "\t.editorShowBlocks {TAG} {\n" + |
---|
88 | "\t\tbackground-image: url({MODURL}/images/blockelems/{TAG}.gif);\n" + |
---|
89 | "\t\tbackground-repeat: no-repeat;\n" + |
---|
90 | "\t\tbackground-position: top left;\n" + |
---|
91 | "\t\tborder-width: 1px;\n" + |
---|
92 | "\t\tborder-style: dashed;\n" + |
---|
93 | "\t\tborder-color: #D0D0D0;\n" + |
---|
94 | "\t\tpadding-top: 15px;\n" + |
---|
95 | "\t\tpadding-left: 15px;\n" + |
---|
96 | "\t}\n" + |
---|
97 | "}\n"; |
---|
98 | |
---|
99 | dojo.forEach(blocks, function(tag){ |
---|
100 | style += template.replace(/\{TAG\}/gi, tag); |
---|
101 | }); |
---|
102 | |
---|
103 | //Finally associate in the image locations based off the module url. |
---|
104 | var modurl = dojo.moduleUrl(dojox._scopeName, "editor/plugins/resources").toString(); |
---|
105 | if(!(modurl.match(/^https?:\/\//i)) && |
---|
106 | !(modurl.match(/^file:\/\//i))){ |
---|
107 | // We have to root it to the page location on webkit for some nutball reason. |
---|
108 | // Probably has to do with how iframe was loaded. |
---|
109 | var bUrl; |
---|
110 | if(modurl.charAt(0) === "/"){ |
---|
111 | //Absolute path on the server, so lets handle... |
---|
112 | var proto = dojo.doc.location.protocol; |
---|
113 | var hostn = dojo.doc.location.host; |
---|
114 | bUrl = proto + "//" + hostn; |
---|
115 | }else{ |
---|
116 | bUrl = this._calcBaseUrl(dojo.global.location.href); |
---|
117 | } |
---|
118 | if(bUrl[bUrl.length - 1] !== "/" && modurl.charAt(0) !== "/"){ |
---|
119 | bUrl += "/"; |
---|
120 | } |
---|
121 | modurl = bUrl + modurl; |
---|
122 | } |
---|
123 | // Update all the urls. |
---|
124 | style = style.replace(/\{MODURL\}/gi, modurl); |
---|
125 | if(!dojo.isIE){ |
---|
126 | var sNode = doc.createElement("style"); |
---|
127 | sNode.appendChild(doc.createTextNode(style)); |
---|
128 | doc.getElementsByTagName("head")[0].appendChild(sNode); |
---|
129 | }else{ |
---|
130 | var ss = doc.createStyleSheet(""); |
---|
131 | ss.cssText = style; |
---|
132 | } |
---|
133 | }catch(e){ |
---|
134 | console.warn(e); |
---|
135 | } |
---|
136 | } |
---|
137 | |
---|
138 | // Apply/remove the classes based on state. |
---|
139 | if(show){ |
---|
140 | dojo.addClass(this.editor.editNode, "editorShowBlocks"); |
---|
141 | }else{ |
---|
142 | dojo.removeClass(this.editor.editNode, "editorShowBlocks"); |
---|
143 | } |
---|
144 | }, |
---|
145 | |
---|
146 | _calcBaseUrl: function(fullUrl) { |
---|
147 | // summary: |
---|
148 | // Internal function used to figure out the full root url (no relatives) |
---|
149 | // for loading images in the styles in the iframe. |
---|
150 | // fullUrl: String |
---|
151 | // The full url to tear down to the base. |
---|
152 | // tags: |
---|
153 | // private |
---|
154 | var baseUrl = null; |
---|
155 | if (fullUrl !== null) { |
---|
156 | // Check to see if we need to strip off any query parameters from the Url. |
---|
157 | var index = fullUrl.indexOf("?"); |
---|
158 | if (index != -1) { |
---|
159 | fullUrl = fullUrl.substring(0,index); |
---|
160 | } |
---|
161 | |
---|
162 | // Now we need to trim if necessary. If it ends in /, then we don't |
---|
163 | // have a filename to trim off so we can return. |
---|
164 | index = fullUrl.lastIndexOf("/"); |
---|
165 | if (index > 0 && index < fullUrl.length) { |
---|
166 | baseUrl = fullUrl.substring(0,index); |
---|
167 | }else{ |
---|
168 | baseUrl = fullUrl; |
---|
169 | } |
---|
170 | } |
---|
171 | return baseUrl; //String |
---|
172 | } |
---|
173 | }); |
---|
174 | |
---|
175 | // Register this plugin. |
---|
176 | dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){ |
---|
177 | if(o.plugin){ return; } |
---|
178 | var name = o.args.name.toLowerCase(); |
---|
179 | if(name === "showblocknodes"){ |
---|
180 | o.plugin = new ShowBlockNodes(); |
---|
181 | } |
---|
182 | }); |
---|
183 | |
---|
184 | return ShowBlockNodes; |
---|
185 | |
---|
186 | }); |
---|