Commit 6a2de75bcd39f596abd5cf618523f45b11f755b9
- Diff rendering mode:
- inline
- side by side
server/alipi.py
(33 / 13)
  | |||
46 | 46 | script_edit = root.makeelement('script') | |
47 | 47 | root.body.append(script_test) | |
48 | 48 | root.body.append(script_edit) | |
49 | script_test.set("src", "http://dev.a11y.in/alipi/ui.js") | ||
49 | script_test.set("src", "http://dev.a11y.in/server/ui.js") | ||
50 | 50 | script_test.set("type", "text/javascript") | |
51 | script_edit.set("src", "http://dev.a11y.in/alipi/wsgi/page_edit.js") | ||
51 | script_edit.set("src", "http://dev.a11y.in/server/wsgi/page_edit.js") | ||
52 | 52 | script_edit.set("type","text/javascript") | |
53 | 53 | ||
54 | 54 | script_jq_mini = root.makeelement('script') | |
… | … | ||
60 | 60 | root.body.append(style) | |
61 | 61 | style.set("rel","stylesheet") | |
62 | 62 | style.set("type", "text/css") | |
63 | style.set("href", "http://dev.a11y.in/alipi/stylesheet.css") | ||
63 | style.set("href", "http://dev.a11y.in/server/stylesheet.css") | ||
64 | |||
65 | # if collection.find_one({"about" : request.args['foruri']}) is not None: | ||
66 | # overlay1 = root.makeelement('div') | ||
67 | # root.body.append(overlay1) | ||
68 | # overlay1.set("id", "overlay1") | ||
69 | |||
70 | # opt = root.makeelement('option') | ||
71 | # opt.text = "Choose a narration" | ||
72 | |||
64 | 73 | script_jq_cust = root.makeelement('script') | |
65 | 74 | root.body.append(script_jq_cust) | |
66 | 75 | script_jq_cust.set("src", "https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js") | |
… | … | ||
96 | 96 | script_jq_mini.set("src", "http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js") | |
97 | 97 | script_jq_mini.set("type", "text/javascript") | |
98 | 98 | ||
99 | script_test.set("src", "http://dev.a11y.in/alipi/ui.js") | ||
99 | script_test.set("src", "http://dev.a11y.in/server/ui.js") | ||
100 | 100 | script_test.set("type", "text/javascript") | |
101 | script_edit.set("src", "http://dev.a11y.in/alipi/wsgi/page_edit.js") | ||
101 | script_edit.set("src", "http://dev.a11y.in/server/wsgi/page_edit.js") | ||
102 | 102 | script_edit.set("type","text/javascript") | |
103 | 103 | script_jqui = root.makeelement('script') | |
104 | 104 | script_jqui.set("type","text/javascript") | |
… | … | ||
152 | 152 | root.body.append(style) | |
153 | 153 | style.set("rel","stylesheet") | |
154 | 154 | style.set("type", "text/css") | |
155 | style.set("href", "http://dev.a11y.in/alipi/stylesheet.css") | ||
155 | style.set("href", "http://dev.a11y.in/server/stylesheet.css") | ||
156 | |||
157 | # overlay2 = root.makeelement('div') | ||
158 | # root.body.append(overlay2) | ||
159 | # overlay2.set("id", "overlay2") | ||
160 | |||
161 | # btn = root.makeelement('input') | ||
162 | # overlay2.append(btn) | ||
163 | # btn.set("id", "edit-button") | ||
164 | # btn.set("type", "submit") | ||
165 | # btn.set("onClick", "a11ypi.testContext();page_edit('4seiz', '4l85060vb9', '336e2nootv6nxjsvyjov', 'VISUAL', 'false', '');") | ||
166 | # btn.set("value", "EDIT") | ||
156 | 167 | root.body.set("onload","a11ypi.ren();a11ypi.tweet(); a11ypi.facebook();a11ypi.loadOverlay();") | |
157 | 168 | return lxml.html.tostring(root) | |
158 | 169 | ||
… | … | ||
175 | 175 | d['lang'] = request.args['lang'] | |
176 | 176 | script_test = root.makeelement('script') | |
177 | 177 | root.body.append(script_test) | |
178 | script_test.set("src", "http://dev.a11y.in/alipi/ui.js") | ||
178 | script_test.set("src", "http://dev.a11y.in/server/ui.js") | ||
179 | 179 | script_test.set("type", "text/javascript") | |
180 | 180 | root.body.set("onload","a11ypi.ren()"); | |
181 | 181 | root.make_links_absolute(d['foruri'], resolve_base_href = True) | |
… | … | ||
185 | 185 | script_jqui = root.makeelement('script') | |
186 | 186 | ||
187 | 187 | script_test = root.makeelement('script') | |
188 | script_test.set("src", "http://dev.a11y.in/alipi/ui.js") | ||
188 | script_test.set("src", "http://dev.a11y.in/server/ui.js") | ||
189 | 189 | script_test.set("type", "text/javascript") | |
190 | 190 | root.body.append(script_test) | |
191 | 191 | ||
… | … | ||
195 | 195 | root.body.append(script_jq_mini) | |
196 | 196 | ||
197 | 197 | script_edit = root.makeelement('script') | |
198 | script_edit.set("src", "http://dev.a11y.in/alipi/wsgi/page_edit.js") | ||
198 | script_edit.set("src", "http://dev.a11y.in/server/wsgi/page_edit.js") | ||
199 | 199 | script_edit.set("type","text/javascript") | |
200 | 200 | root.body.append(script_edit) | |
201 | 201 | ||
… | … | ||
249 | 249 | root.body.append(style) | |
250 | 250 | style.set("rel","stylesheet") | |
251 | 251 | style.set("type", "text/css") | |
252 | style.set("href", "http://dev.a11y.in/alipi/stylesheet.css") | ||
252 | style.set("href", "http://dev.a11y.in/server/stylesheet.css") | ||
253 | 253 | ||
254 | 254 | overlay2 = root.makeelement('div') | |
255 | 255 | root.body.append(overlay2) | |
… | … | ||
264 | 264 | ||
265 | 265 | script_test = root.makeelement('script') | |
266 | 266 | root.body.append(script_test) | |
267 | script_test.set("src", "http://dev.a11y.in/alipi/ui.js") | ||
267 | script_test.set("src", "http://dev.a11y.in/server/ui.js") | ||
268 | 268 | script_test.set("type", "text/javascript") | |
269 | 269 | root.body.set("onload","a11ypi.filter(); a11ypi.tweet(); a11ypi.facebook();"); | |
270 | 270 | root.make_links_absolute(d['foruri'], resolve_base_href = True) | |
… | … | ||
273 | 273 | elif request.args.has_key('interactive') == False and request.args.has_key('blog') == True: | |
274 | 274 | script_test = root.makeelement('script') | |
275 | 275 | root.body.append(script_test) | |
276 | script_test.set("src", "http://dev.a11y.in/alipi/ui.js") | ||
276 | script_test.set("src", "http://dev.a11y.in/server/ui.js") | ||
277 | 277 | script_test.set("type", "text/javascript") | |
278 | 278 | ||
279 | 279 | script_jq_mini = root.makeelement('script') | |
… | … | ||
296 | 296 | root.body.append(style) | |
297 | 297 | style.set("rel","stylesheet") | |
298 | 298 | style.set("type", "text/css") | |
299 | style.set("href", "http://dev.a11y.in/alipi/stylesheet.css") | ||
299 | style.set("href", "http://dev.a11y.in/server/stylesheet.css") | ||
300 | 300 | ||
301 | 301 | collection = g.db['post'] | |
302 | 302 | if collection.find_one({"about" : request.args['foruri']}) is not None: |
server/index.html
(2 / 2)
  | |||
20 | 20 | { | |
21 | 21 | foruri = document.getElementById("inputurl").value; | |
22 | 22 | if(foruri.substring(0,7) == "http://") { | |
23 | window.open("http://127.0.0.1:5000/?foruri=" + encodeURIComponent(foruri)); | ||
23 | window.open("http://dev.a11y.in/web?foruri=" + encodeURIComponent(foruri)); | ||
24 | 24 | } | |
25 | 25 | else if (foruri.substring(0,8) == "https://") { | |
26 | window.open("http://127.0.0.1:5000/?foruri=" + encodeURIComponent(foruri)); | ||
26 | window.open("http://dev.a11y.in/web?foruri=" + encodeURIComponent(foruri)); | ||
27 | 27 | } | |
28 | 28 | else { | |
29 | 29 | alert("Please enter 'HTTP' protocoled URL"); |
test.html
(1 / 1)
  | |||
8 | 8 | </stylesheet> | |
9 | 9 | </head> | |
10 | 10 | <body style="margin: auto 10%;"> | |
11 | <img src="http://localhost/alipi-1/server/images/alipi.gif" style="position:relative; top:50px; left:25px; width:10%; height:20%;"></img> | ||
11 | <img src="http://dev.a11y.in/alipi.gif" style="position:relative; top:50px; left:25px; width:10%; height:20%;"></img> | ||
12 | 12 | <span style="position:relative; top:30px; left:20px; font-size:25px;"> Alipi.us</span> | |
13 | 13 | <hr style="position:relative; top:30px;"> | |
14 | 14 |
wsgi/page_edit.js
(0 / 3970)
  | |||
1 | function page_edit( boltSlug, pageSlug, uploadSlug, editMode, hasEditPermission, successUrl) | ||
2 | { | ||
3 | |||
4 | var console, PopupControl, M4ImageElement,locName='',langName = '',styleName='',authorValue; | ||
5 | var editAttributes, elementAttributes, fontTypeAttributes, normalFontAttributes, popupContainerAttributes, editButtonAttributes, editTextInputAttributes, editSubmitAttributes, editTitleAttributes, panelButtonAttributes, buttonPanelAttributes, actionPanelAttributes, closeButtonAttributes, actionButtonAttributes, redButtonAttributes, leftBorderStyle, rightBorderStyle, titleButtonImageAttributes, titleButtonDisplayTextAttributes, actionButtonImageAttributes, actionButtonDisplayTextAttributes,greyArrowAttributes, pageEditor, splashWindow, loadingTimerId, keepOriginal = false; | ||
6 | |||
7 | /** | ||
8 | * General utility class / functions. | ||
9 | */ | ||
10 | var UTIL = UTIL || {}; | ||
11 | |||
12 | (function(UTIL) { | ||
13 | UTIL.addEvent = function addEvent(node, event, callback) { | ||
14 | if (node.addEventListener) { | ||
15 | node.addEventListener(event, callback, false); | ||
16 | return true; | ||
17 | } else if (node.attachEvent) { | ||
18 | // Simulates W3C event model in IE | ||
19 | return node.attachEvent('on' + event, function() { | ||
20 | callback( { | ||
21 | target : window.event.srcElement, | ||
22 | pageX : window.event.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft), | ||
23 | pageY : window.event.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop), | ||
24 | clientX : window.event.clientX, | ||
25 | clientY : window.event.clientY, | ||
26 | keyCode : window.event.keyCode, | ||
27 | ctrlKey : window.event.ctrlKey, | ||
28 | altKey : window.event.altKey, | ||
29 | shiftKey : window.event.shiftKey, | ||
30 | type : window.event.type, | ||
31 | preventDefault : function() { | ||
32 | window.event.returnValue = false; | ||
33 | }, | ||
34 | stopPropagation : function() { | ||
35 | window.event.cancelBubble = true; | ||
36 | } | ||
37 | }); | ||
38 | }); | ||
39 | } | ||
40 | return false; | ||
41 | }; | ||
42 | |||
43 | // String concatenation in <IE9 is really slow. | ||
44 | UTIL.StringBuffer = function StringBuffer() { | ||
45 | var buffer = []; | ||
46 | this.append = function append(string) { | ||
47 | buffer.push(string); | ||
48 | return this; | ||
49 | }; | ||
50 | |||
51 | this.toString = function toString() { | ||
52 | return buffer.join(''); | ||
53 | }; | ||
54 | }; | ||
55 | |||
56 | UTIL.forEach = function forEach(array, callback) { | ||
57 | var i = 0, length = array.length, value; | ||
58 | |||
59 | if (length) { | ||
60 | for (value = array[0]; i < length && callback.call(value, i, value) !== false; value = array[++i]) { | ||
61 | } | ||
62 | } | ||
63 | }; | ||
64 | |||
65 | UTIL.animate = function animate(callback, steps, delay) { | ||
66 | var index = 1, timer; | ||
67 | |||
68 | timer = window.setInterval(function() { | ||
69 | if (index < steps) { | ||
70 | callback(index, false); | ||
71 | index += 1; | ||
72 | } else { | ||
73 | clearInterval(timer); | ||
74 | callback(index, true); | ||
75 | } | ||
76 | }, delay); | ||
77 | }; | ||
78 | |||
79 | UTIL.hashToQueryString = function hashToQueryString(hash) { | ||
80 | var first = true, buffer = new UTIL.StringBuffer(); | ||
81 | |||
82 | for (var key in hash) { | ||
83 | if (first) { | ||
84 | first = false; | ||
85 | } else { | ||
86 | buffer.append('&'); | ||
87 | } | ||
88 | buffer.append(encodeURIComponent(key)); | ||
89 | buffer.append('='); | ||
90 | buffer.append(encodeURIComponent(hash[key])); | ||
91 | } | ||
92 | |||
93 | return buffer.toString(); | ||
94 | }; | ||
95 | })(UTIL); | ||
96 | // // | ||
97 | |||
98 | /** | ||
99 | * DOM utility class / functions. | ||
100 | */ | ||
101 | var DOM = DOM || {}; | ||
102 | |||
103 | (function(DOM) { | ||
104 | // // | ||
105 | |||
106 | (function(__global__, undefined) | ||
107 | { | ||
108 | |||
109 | var modules = (typeof module !== 'undefined' && module.exports); | ||
110 | |||
111 | var document = (__global__.document || { | ||
112 | // Provide a dummy document object if we're not in a browser, to keep | ||
113 | // interpreters happy. | ||
114 | createElement: function(){}, | ||
115 | createDocumentFragment: function(){}, | ||
116 | createTextNode: function(){}, | ||
117 | getElementById: function(){} | ||
118 | }), | ||
119 | toString = Object.prototype.toString, | ||
120 | slice = Array.prototype.slice, | ||
121 | // Functioms and objects involved in implementing cross-crowser workarounds | ||
122 | createElement, | ||
123 | eventAttrs, | ||
124 | addEvent, | ||
125 | setInnerHTML, | ||
126 | /** Tag names defined in the HTML 4.01 Strict and Frameset DTDs. */ | ||
127 | tagNames = ("a abbr acronym address area b bdo big blockquote body br " + | ||
128 | "button caption cite code col colgroup dd del dfn div dl dt em fieldset " + | ||
129 | "form frame frameset h1 h2 h3 h4 h5 h6 hr head html i iframe img input " + | ||
130 | "ins kbd label legend li link map meta noscript " /* :) */ + "object ol " + | ||
131 | "optgroup option p param pre q samp script select small span strong style " + | ||
132 | "sub sup table tbody td textarea tfoot th thead title tr tt ul var").split(" "), | ||
133 | /** Lookup for known tag names. */ | ||
134 | tagNameLookup = lookup(tagNames), | ||
135 | /** * Lookup for tags defined as EMPTY in the HTML 4.01 Strict and Frameset DTDs. */ | ||
136 | emptyTags = lookup("area base br col frame hr input img link meta param".split(" ")); | ||
137 | |||
138 | // Utility functions ----------------------------------------------------------- | ||
139 | |||
140 | /** | ||
141 | * Naively copies from ``source`` to ``dest``, returning ``dest``. | ||
142 | */ | ||
143 | function extend(dest, source) | ||
144 | { | ||
145 | for (var name in source) | ||
146 | { | ||
147 | dest[name] = source[name]; | ||
148 | } | ||
149 | return dest; | ||
150 | } | ||
151 | |||
152 | /** | ||
153 | * Creates a lookup object from an array of strings. | ||
154 | */ | ||
155 | function lookup(a) | ||
156 | { | ||
157 | var obj = {}, i = 0, l = a.length; | ||
158 | for (; i < l; i++) | ||
159 | { | ||
160 | obj[a[i]] = true; | ||
161 | } | ||
162 | return obj; | ||
163 | } | ||
164 | |||
165 | /** | ||
166 | * Uses a dummy constructor to make a ``child`` constructor inherit from a | ||
167 | * ``parent`` constructor. | ||
168 | */ | ||
169 | function inheritFrom(child, parent) | ||
170 | { | ||
171 | function F() {}; | ||
172 | F.prototype = parent.prototype; | ||
173 | child.prototype = new F(); | ||
174 | child.prototype.constructor = child; | ||
175 | } | ||
176 | |||
177 | function isArray(o) | ||
178 | { | ||
179 | return (toString.call(o) === "[object Array]"); | ||
180 | } | ||
181 | |||
182 | function isFunction(o) | ||
183 | { | ||
184 | return (toString.call(o) === "[object Function]"); | ||
185 | } | ||
186 | |||
187 | /** | ||
188 | * We primarily want to distinguish between Objects and Nodes. | ||
189 | */ | ||
190 | function isObject(o) | ||
191 | { | ||
192 | return (!!o && toString.call(o) === "[object Object]" && | ||
193 | !o.nodeType && | ||
194 | !(o instanceof SafeString)) | ||
195 | } | ||
196 | |||
197 | /** | ||
198 | * Flattens an Array in-place, replacing any Arrays it contains with their | ||
199 | * contents, and flattening their contents in turn. | ||
200 | */ | ||
201 | function flatten(a) | ||
202 | { | ||
203 | for (var i = 0, l = a.length; i < l; i++) | ||
204 | { | ||
205 | var c = a[i]; | ||
206 | if (isArray(c)) | ||
207 | { | ||
208 | // Make sure we loop to the Array's new length | ||
209 | l += c.length - 1; | ||
210 | // Replace the current item with its contents | ||
211 | Array.prototype.splice.apply(a, [i, 1].concat(c)); | ||
212 | // Stay on the current index so we continue looping at the first | ||
213 | // element of the array we just spliced in or removed. | ||
214 | i--; | ||
215 | } | ||
216 | } | ||
217 | } | ||
218 | |||
219 | /** | ||
220 | * Escapes sensitive HTML characters. | ||
221 | */ | ||
222 | function escapeHTML(s) | ||
223 | { | ||
224 | return s.split("&").join("&") | ||
225 | .split("<").join("<") | ||
226 | .split(">").join(">") | ||
227 | .split('"').join(""") | ||
228 | .split("'").join("'"); | ||
229 | } | ||
230 | |||
231 | |||
232 | eventAttrs = lookup( | ||
233 | ("blur focus focusin focusout load resize scroll unload click dblclick " + | ||
234 | "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + | ||
235 | "change select submit keydown keypress keyup error").split(" ")); | ||
236 | |||
237 | if (!modules) | ||
238 | { | ||
239 | // jQuery is not available, implement the most essential workarounds | ||
240 | var supportsStyle = (function() | ||
241 | { | ||
242 | var div = document.createElement("div"); | ||
243 | div.style.display = "none"; | ||
244 | div.innerHTML = '<span style="color:silver;">s<span>'; | ||
245 | return /silver/.test(div.getElementsByTagName("span")[0].getAttribute("style")); | ||
246 | })(), | ||
247 | specialRE = /^(?:href|src|style)$/, | ||
248 | attributeTranslations = { | ||
249 | cellspacing: "cellSpacing", | ||
250 | "class": "className", | ||
251 | colspan: "colSpan", | ||
252 | "for": "htmlFor", | ||
253 | frameborder: "frameBorder", | ||
254 | maxlength: "maxLength", | ||
255 | readonly: "readOnly", | ||
256 | rowspan: "rowSpan", | ||
257 | tabindex: "tabIndex", | ||
258 | usemap: "useMap" | ||
259 | }; | ||
260 | |||
261 | createElement = function(tagName, attributes) | ||
262 | { | ||
263 | var el = document.createElement(tagName); // Damn you, IE | ||
264 | |||
265 | for (var name in attributes) | ||
266 | { | ||
267 | var value = attributes[name], | ||
268 | name = attributeTranslations[name] || name; | ||
269 | |||
270 | if (name in eventAttrs) | ||
271 | { | ||
272 | el["on" + name] = value; | ||
273 | continue; | ||
274 | } | ||
275 | |||
276 | var special = specialRE.test(name); | ||
277 | //if ((name in el || el[name] !== undefined) && !special) | ||
278 | //el[name] = value; | ||
279 | if (!supportsStyle && name == "style") | ||
280 | el.style.cssText = ""+value; | ||
281 | else | ||
282 | el.setAttribute(name, ""+value); | ||
283 | } | ||
284 | |||
285 | return el; | ||
286 | }; | ||
287 | |||
288 | addEvent = function(id, event, handler) | ||
289 | { | ||
290 | document.getElementById(id)["on" + event] = handler; | ||
291 | }; | ||
292 | |||
293 | setInnerHTML = function(el, html) | ||
294 | { | ||
295 | try | ||
296 | { | ||
297 | el.innerHTML = html; | ||
298 | } | ||
299 | catch (e) | ||
300 | { | ||
301 | var div = document.createElement("div"); | ||
302 | div.innerHTML = html; | ||
303 | while (el.firstChild) | ||
304 | el.removeChild(el.firstChild); | ||
305 | while (div.firstChild) | ||
306 | el.appendChild(div.firstChild); | ||
307 | } | ||
308 | }; | ||
309 | } | ||
310 | |||
311 | |||
312 | // HTML Escaping --------------------------------------------------------------- | ||
313 | |||
314 | /** | ||
315 | * If the given input is a ``SafeString``, returns its value; otherwise, coerces | ||
316 | * to ``String`` and escapes. | ||
317 | */ | ||
318 | function conditionalEscape(html) | ||
319 | { | ||
320 | if (html instanceof SafeString) | ||
321 | { | ||
322 | return html.value; | ||
323 | } | ||
324 | return escapeHTML(""+html); | ||
325 | } | ||
326 | |||
327 | /** | ||
328 | * ``String`` subclass which marks the given string as safe for inclusion | ||
329 | * without escaping. | ||
330 | */ | ||
331 | function SafeString(value) | ||
332 | { | ||
333 | this.value = value; | ||
334 | } | ||
335 | |||
336 | inheritFrom(SafeString, String); | ||
337 | |||
338 | SafeString.prototype.toString = SafeString.prototype.valueOf = function() | ||
339 | { | ||
340 | return this.value; | ||
341 | }; | ||
342 | |||
343 | // Mock DOM Elements ----------------------------------------------------------- | ||
344 | |||
345 | /** | ||
346 | * Partially emulates a DOM ``Node`` for HTML generation. | ||
347 | */ | ||
348 | function HTMLNode(childNodes) | ||
349 | { | ||
350 | this.childNodes = childNodes || []; | ||
351 | |||
352 | // Ensure HTMLFragment contents are inlined, as if this object's child | ||
353 | // nodes were appended one-by-one. | ||
354 | this._inlineFragments(); | ||
355 | } | ||
356 | |||
357 | inheritFrom(HTMLNode, Object); | ||
358 | |||
359 | /** | ||
360 | * Replaces any ``HTMLFragment`` objects in child nodes with their own | ||
361 | * child nodes and empties the fragment. | ||
362 | */ | ||
363 | HTMLNode.prototype._inlineFragments = function() | ||
364 | { | ||
365 | for (var i = 0, l = this.childNodes.length; i < l; i++) | ||
366 | { | ||
367 | var child = this.childNodes[i]; | ||
368 | if (child instanceof HTMLFragment) | ||
369 | { | ||
370 | this.childNodes.splice.apply(this.childNodes, | ||
371 | [i, 1].concat(child.childNodes)); | ||
372 | // Clear the fragment on append, as per DocumentFragment | ||
373 | child.childNodes = []; | ||
374 | } | ||
375 | } | ||
376 | }; | ||
377 | |||
378 | /** | ||
379 | * Emulates ``appendChild``, inserting fragment child node contents and | ||
380 | * emptying the fragment if one is given. | ||
381 | */ | ||
382 | HTMLNode.prototype.appendChild = function(node) | ||
383 | { | ||
384 | if (node instanceof HTMLFragment) | ||
385 | { | ||
386 | this.childNodes = this.childNodes.concat(node.childNodes); | ||
387 | // Clear the fragment on append, as per DocumentFragment | ||
388 | node.childNodes = []; | ||
389 | } | ||
390 | else | ||
391 | { | ||
392 | this.childNodes.push(node); | ||
393 | } | ||
394 | }; | ||
395 | |||
396 | /** | ||
397 | * Emulates ``cloneNode`` so cloning of ``HTMLFragment`` objects works | ||
398 | * as expected. | ||
399 | */ | ||
400 | HTMLNode.prototype.cloneNode = function(deep) | ||
401 | { | ||
402 | var clone = this._clone(); | ||
403 | if (deep === true) | ||
404 | { | ||
405 | for (var i = 0, l = this.childNodes.length; i < l; i++) | ||
406 | { | ||
407 | var node = this.childNodes[i]; | ||
408 | if (node instanceof HTMLElement) | ||
409 | { | ||
410 | clone.childNodes.push(node.cloneNode(deep)); | ||
411 | } | ||
412 | else | ||
413 | { | ||
414 | clone.childNodes.push(node); | ||
415 | } | ||
416 | } | ||
417 | } | ||
418 | return clone; | ||
419 | }; | ||
420 | |||
421 | /** | ||
422 | * Creates the object to be used for deep cloning. | ||
423 | */ | ||
424 | HTMLNode.prototype._clone = function() | ||
425 | { | ||
426 | return new Node(); | ||
427 | }; | ||
428 | |||
429 | /** | ||
430 | * Partially emulates a DOM ``Element ``for HTML generation. | ||
431 | */ | ||
432 | function HTMLElement(tagName, attributes, childNodes) | ||
433 | { | ||
434 | HTMLNode.call(this, childNodes); | ||
435 | |||
436 | this.tagName = this.nodeName = tagName.toLowerCase(); | ||
437 | this.attributes = attributes || {}; | ||
438 | |||
439 | // Keep a record of whether or not closing slashes are needed, as the | ||
440 | // mode could change before this object is coerced to a String. | ||
441 | this.xhtml = (DOMBuilder.mode == "XHTML"); | ||
442 | } | ||
443 | |||
444 | inheritFrom(HTMLElement, HTMLNode); | ||
445 | |||
446 | HTMLElement.eventTrackerId = 1; | ||
447 | |||
448 | HTMLElement.prototype.nodeType = 1; | ||
449 | |||
450 | HTMLElement.prototype._clone = function() | ||
451 | { | ||
452 | var clone = new HTMLElement(this.tagName, extend({}, this.attributes)); | ||
453 | clone.xhtml = this.xhtml; | ||
454 | return clone; | ||
455 | }; | ||
456 | |||
457 | /** | ||
458 | * Creates an HTML/XHTML representation of an HTMLElement. | ||
459 | * | ||
460 | * If ``true`` is passed as an argument and any event attributes are found, this | ||
461 | * method will ensure the resulting element has an id so the handlers for the | ||
462 | * event attributes can be registered after the element has been inserted into | ||
463 | * the document via ``innerHTML``. | ||
464 | * | ||
465 | * If necessary, a unique id will be generated. | ||
466 | */ | ||
467 | HTMLElement.prototype.toString = function() | ||
468 | { | ||
469 | var trackEvents = arguments[0] || false, | ||
470 | tagName = (tagNameLookup[this.tagName] | ||
471 | ? this.tagName | ||
472 | : conditionalEscape(this.tagName)); | ||
473 | |||
474 | // Opening tag | ||
475 | var parts = ["<" + tagName]; | ||
476 | for (var attr in this.attributes) | ||
477 | { | ||
478 | // innerHTML is a special case, as we can use it to (perhaps | ||
479 | // inadvisedly) to specify entire contents as a string. | ||
480 | if (attr === "innerHTML") | ||
481 | { | ||
482 | continue; | ||
483 | } | ||
484 | // Don't create attributes which wouldn't make sense in HTML mode - | ||
485 | // they can be dealt with afet insertion using addEvents(). | ||
486 | if (attr in eventAttrs) | ||
487 | { | ||
488 | if (trackEvents === true && !this.eventsFound) | ||
489 | { | ||
490 | this.eventsFound = true; | ||
491 | } | ||
492 | continue; | ||
493 | } | ||
494 | parts.push(" " + conditionalEscape(attr.toLowerCase()) + "=\"" + | ||
495 | conditionalEscape(this.attributes[attr]) + "\""); | ||
496 | } | ||
497 | if (this.eventsFound && !("id" in this.attributes)) | ||
498 | { | ||
499 | // Ensure an id is present so we can grab this element later | ||
500 | this.id = "__DB" + HTMLElement.eventTrackerId++ + "__"; | ||
501 | parts.push(' id="' + this.id + '"'); | ||
502 | } | ||
503 | parts.push(">"); | ||
504 | |||
505 | if (emptyTags[tagName]) | ||
506 | { | ||
507 | if (this.xhtml) | ||
508 | { | ||
509 | parts.splice(parts.length - 1, 1, " />"); | ||
510 | } | ||
511 | return parts.join(""); | ||
512 | } | ||
513 | |||
514 | // If innerHTML was given, use it exclusively for the contents | ||
515 | if ("innerHTML" in this.attributes) | ||
516 | { | ||
517 | parts.push(this.attributes.innerHTML); | ||
518 | } | ||
519 | else | ||
520 | { | ||
521 | for (var i = 0, l = this.childNodes.length; i < l; i++) | ||
522 | { | ||
523 | var node = this.childNodes[i]; | ||
524 | if (node instanceof HTMLElement || node instanceof SafeString) | ||
525 | { | ||
526 | parts.push(node.toString(trackEvents)); | ||
527 | } | ||
528 | else if (node === "\u00A0") | ||
529 | { | ||
530 | // Special case to convert these back to entities, | ||
531 | parts.push(" "); | ||
532 | } | ||
533 | else | ||
534 | { | ||
535 | // Coerce to string and escape | ||
536 | parts.push(escapeHTML(""+node)); | ||
537 | } | ||
538 | } | ||
539 | } | ||
540 | |||
541 | // Closing tag | ||
542 | parts.push("</" + tagName + ">"); | ||
543 | return parts.join(""); | ||
544 | }; | ||
545 | |||
546 | /** | ||
547 | * If event attributes were found when ``toString(true)`` was called, this | ||
548 | * method will retrieve the resulting DOM Element by id, attach event handlers | ||
549 | * to it and call ``addEvents`` on any HTMLElement children. | ||
550 | */ | ||
551 | HTMLElement.prototype.addEvents = function() | ||
552 | { | ||
553 | if (this.eventsFound) | ||
554 | { | ||
555 | var id = ("id" in this.attributes | ||
556 | ? conditionalEscape(this.attributes.id) | ||
557 | : this.id); | ||
558 | for (var attr in this.attributes) | ||
559 | { | ||
560 | if (attr in eventAttrs) | ||
561 | { | ||
562 | addEvent(id, attr, this.attributes[attr]); | ||
563 | } | ||
564 | } | ||
565 | |||
566 | delete this.eventsFound; | ||
567 | delete this.id; | ||
568 | } | ||
569 | |||
570 | for (var i = 0, l = this.childNodes.length; i < l; i++) | ||
571 | { | ||
572 | var node = this.childNodes[i]; | ||
573 | if (node instanceof HTMLElement) | ||
574 | { | ||
575 | node.addEvents(); | ||
576 | } | ||
577 | } | ||
578 | }; | ||
579 | |||
580 | HTMLElement.prototype.insertWithEvents = function(el) | ||
581 | { | ||
582 | setInnerHTML(el, this.toString(true)); | ||
583 | this.addEvents(); | ||
584 | }; | ||
585 | |||
586 | /** | ||
587 | * Partially emulates a DOM ``DocumentFragment`` for HTML generation. | ||
588 | */ | ||
589 | function HTMLFragment(childNodes) | ||
590 | { | ||
591 | HTMLNode.call(this, childNodes); | ||
592 | } | ||
593 | inheritFrom(HTMLFragment, HTMLNode); | ||
594 | |||
595 | HTMLFragment.prototype._clone = function() | ||
596 | { | ||
597 | return new HTMLFragment(); | ||
598 | }; | ||
599 | |||
600 | HTMLFragment.prototype.nodeType = 11; | ||
601 | HTMLFragment.prototype.nodeName = "#document-fragment"; | ||
602 | |||
603 | /** | ||
604 | * Creates an HTML/XHTML representation of an HTMLFragment. | ||
605 | * | ||
606 | * If ``true``is passed as an argument, it will be passed on to | ||
607 | * any child HTMLElements when their ``toString()`` is called. | ||
608 | */ | ||
609 | HTMLFragment.prototype.toString = function() | ||
610 | { | ||
611 | var trackEvents = arguments[0] || false, | ||
612 | parts = []; | ||
613 | |||
614 | // Contents | ||
615 | for (var i = 0, l = this.childNodes.length; i < l; i++) | ||
616 | { | ||
617 | var node = this.childNodes[i]; | ||
618 | if (node instanceof HTMLElement || node instanceof SafeString) | ||
619 | { | ||
620 | parts.push(node.toString(trackEvents)); | ||
621 | } | ||
622 | else if (node === "\u00A0") | ||
623 | { | ||
624 | // Special case to convert these back to entities, | ||
625 | parts.push(" "); | ||
626 | } | ||
627 | else | ||
628 | { | ||
629 | // Coerce to string and escape | ||
630 | parts.push(escapeHTML(""+node)); | ||
631 | } | ||
632 | } | ||
633 | |||
634 | return parts.join(""); | ||
635 | }; | ||
636 | |||
637 | /** | ||
638 | * Calls ``addEvents()`` on any HTMLElement children. | ||
639 | */ | ||
640 | HTMLFragment.prototype.addEvents = function() | ||
641 | { | ||
642 | for (var i = 0, l = this.childNodes.length; i < l; i++) | ||
643 | { | ||
644 | var node = this.childNodes[i]; | ||
645 | if (node instanceof HTMLElement) | ||
646 | { | ||
647 | node.addEvents(); | ||
648 | } | ||
649 | } | ||
650 | }; | ||
651 | |||
652 | HTMLFragment.prototype.insertWithEvents = function(el) | ||
653 | { | ||
654 | setInnerHTML(el, this.toString(true)); | ||
655 | this.addEvents(); | ||
656 | }; | ||
657 | |||
658 | /** | ||
659 | * Creates a function which, when called, uses DOMBuilder to create an element | ||
660 | * with the given ``tagName``. | ||
661 | * | ||
662 | * The resulting function will also have a ``map`` function which calls | ||
663 | * ``DOMBuilder.map`` with the given ``tagName``. | ||
664 | */ | ||
665 | function createElementFunction(tagName) | ||
666 | { | ||
667 | var elementFunction = function() | ||
668 | { | ||
669 | if (arguments.length === 0) | ||
670 | { | ||
671 | // Short circuit if there are no arguments, to avoid further | ||
672 | // argument inspection. | ||
673 | if (DOMBuilder.mode == "DOM") | ||
674 | { | ||
675 | return document.createElement(tagName); | ||
676 | } | ||
677 | else | ||
678 | { | ||
679 | return new HTMLElement(tagName); | ||
680 | } | ||
681 | } | ||
682 | else | ||
683 | { | ||
684 | return createElementFromArguments(tagName, slice.call(arguments)); | ||
685 | } | ||
686 | }; | ||
687 | |||
688 | // Add a ``map`` function which will call ``DOMBuilder.map`` with the | ||
689 | // appropriate ``tagName``. | ||
690 | elementFunction.map = function() | ||
691 | { | ||
692 | var mapArgs = slice.call(arguments); | ||
693 | mapArgs.unshift(tagName); | ||
694 | return DOMBuilder.map.apply(DOMBuilder, mapArgs); | ||
695 | }; | ||
696 | |||
697 | return elementFunction; | ||
698 | } | ||
699 | |||
700 | /** | ||
701 | * Normalises a list of arguments in order to create a new DOM element | ||
702 | * using ``DOMBuilder.createElement``. Supported argument formats are: | ||
703 | * | ||
704 | * ``(attributes, child1, ...)`` | ||
705 | * an attributes object followed by an arbitrary number of children. | ||
706 | * ``(attributes, [child1, ...])`` | ||
707 | * an attributes object and an ``Array`` of children. | ||
708 | * ``(child1, ...)`` | ||
709 | * an arbitrary number of children. | ||
710 | * ``([child1, ...])`` | ||
711 | * an ``Array`` of children. | ||
712 | * | ||
713 | * At least one argument *must* be provided. | ||
714 | */ | ||
715 | function createElementFromArguments(tagName, args) | ||
716 | { | ||
717 | var attributes, children, | ||
718 | // The short circuit in ``createElementFunction`` ensures we will | ||
719 | // always have at least one argument when called via element creation | ||
720 | // functions. | ||
721 | argsLength = args.length, firstArg = args[0]; | ||
722 | |||
723 | if (argsLength === 1 && | ||
724 | isArray(firstArg)) | ||
725 | { | ||
726 | children = firstArg; // ([child1, ...]) | ||
727 | } | ||
728 | else if (isObject(firstArg)) | ||
729 | { | ||
730 | attributes = firstArg; | ||
731 | children = (argsLength == 2 && isArray(args[1]) | ||
732 | ? args[1] // (attributes, [child1, ...]) | ||
733 | : slice.call(args, 1)); // (attributes, child1, ...) | ||
734 | } | ||
735 | else | ||
736 | { | ||
737 | children = slice.call(args); // (child1, ...) | ||
738 | } | ||
739 | |||
740 | return DOMBuilder.createElement(tagName, attributes, children); | ||
741 | } | ||
742 | |||
743 | // DOMBuilder API -------------------------------------------------------------- | ||
744 | |||
745 | var DOMBuilder = { | ||
746 | version: "1.4.3", | ||
747 | |||
748 | /** | ||
749 | * Determines which mode the ``createElement`` function will operate in. | ||
750 | * Supported values are: | ||
751 | * | ||
752 | * ``"DOM"`` | ||
753 | * create DOM Elements. | ||
754 | * ``"HTML"`` | ||
755 | * create HTML Strings. | ||
756 | * ``"XHTML"`` | ||
757 | * create XHTML Strings. | ||
758 | * | ||
759 | * The value depends on the environment we're running in - if modules are | ||
760 | * available, we default to HTML mode, otherwise we assume we'te in a | ||
761 | * browser and default to DOM mode. | ||
762 | */ | ||
763 | mode: (modules ? "HTML" : "DOM"), | ||
764 | |||
765 | /** | ||
766 | * Calls a function using DOMBuilder temporarily in the given mode and | ||
767 | * returns its output. | ||
768 | * | ||
769 | * This is primarily intended for using DOMBuilder to generate HTML | ||
770 | * strings when running in the browser without having to manage the | ||
771 | * mode flag yourself. | ||
772 | */ | ||
773 | withMode: function(mode, func) | ||
774 | { | ||
775 | var originalMode = this.mode; | ||
776 | this.mode = mode; | ||
777 | try | ||
778 | { | ||
779 | return func(); | ||
780 | } | ||
781 | finally | ||
782 | { | ||
783 | this.mode = originalMode; | ||
784 | } | ||
785 | }, | ||
786 | |||
787 | /** | ||
788 | * An ``Object`` containing element creation functions. | ||
789 | */ | ||
790 | elementFunctions: (function(obj) | ||
791 | { | ||
792 | for (var i = 0, tagName; tagName = tagNames[i]; i++) | ||
793 | { | ||
794 | obj[tagName.toUpperCase()] = createElementFunction(tagName); | ||
795 | } | ||
796 | return obj; | ||
797 | })({}), | ||
798 | |||
799 | /** | ||
800 | * Adds element creation functions to a given context ``Object``, or to | ||
801 | * a new object if none was given. Returns the object the functions were | ||
802 | * added to, either way. | ||
803 | * | ||
804 | * An ``NBSP`` property corresponding to the Unicode character for a | ||
805 | * non-breaking space is also added to the context object, for | ||
806 | * convenience. | ||
807 | */ | ||
808 | apply: function(context) | ||
809 | { | ||
810 | context = context || {}; | ||
811 | extend(context, this.elementFunctions); | ||
812 | context.NBSP = "\u00A0"; // Add NBSP for backwards-compatibility | ||
813 | return context; | ||
814 | }, | ||
815 | |||
816 | /** | ||
817 | * Creates a DOM element with the given tag name and, optionally, | ||
818 | * the given attributes and children. | ||
819 | */ | ||
820 | createElement: function(tagName, attributes, children) | ||
821 | { | ||
822 | attributes = attributes || {}; | ||
823 | children = children || []; | ||
824 | flatten(children); | ||
825 | |||
826 | if (this.mode != "DOM") | ||
827 | { | ||
828 | return new HTMLElement(tagName, attributes, children); | ||
829 | } | ||
830 | |||
831 | // Create the element and set its attributes and event listeners | ||
832 | var el = createElement(tagName, attributes); | ||
833 | |||
834 | // If content was set via innerHTML, we're done... | ||
835 | if (!("innerHTML" in attributes)) | ||
836 | { | ||
837 | // ...otherwise, append children | ||
838 | for (var i = 0, l = children.length; i < l; i++) | ||
839 | { | ||
840 | var child = children[i]; | ||
841 | if (child && child.nodeType) | ||
842 | { | ||
843 | el.appendChild(child); | ||
844 | } | ||
845 | else | ||
846 | { | ||
847 | el.appendChild(document.createTextNode(""+child)); | ||
848 | } | ||
849 | } | ||
850 | } | ||
851 | return el; | ||
852 | }, | ||
853 | |||
854 | /** | ||
855 | * Creates an element for (potentially) every item in a list. Supported | ||
856 | * argument formats are: | ||
857 | * | ||
858 | * 1. ``(tagName, defaultAttributes, [item1, ...], mappingFunction)`` | ||
859 | * 2. ``(tagName, [item1, ...], mappingFunction)`` | ||
860 | * | ||
861 | * Arguments are as follows: | ||
862 | * | ||
863 | * ``tagName`` | ||
864 | * the name of the element to create. | ||
865 | * ``defaultAttributes`` (optional) | ||
866 | * default attributes for the element. | ||
867 | * ``items`` | ||
868 | * the list of items to use as the basis for creating elements. | ||
869 | * ``mappingFunction`` (optional) | ||
870 | * a function to be called with each item in the list to provide | ||
871 | * contents for the element which will be created for that item. | ||
872 | * | ||
873 | * Contents can consist of a single value or a mixed ``Array``. | ||
874 | * | ||
875 | * If provided, the function will be called with the following | ||
876 | * arguments:: | ||
877 | * | ||
878 | * func(item, attributes, itemIndex) | ||
879 | * | ||
880 | * Attributes on the element which will be created can be altered by | ||
881 | * modifying the ``attributes argument, which will initially contain | ||
882 | * the contents of ``defaultAttributes``, if it was provided. | ||
883 | * | ||
884 | * The function can prevent an element being generated for a given | ||
885 | * item by returning ``null``. | ||
886 | * | ||
887 | * If not provided, each item will result in the creation of a new | ||
888 | * element and the item itself will be used as the only contents. | ||
889 | */ | ||
890 | map: function(tagName) | ||
891 | { | ||
892 | // Determine how the function was called | ||
893 | if (isArray(arguments[1])) | ||
894 | { | ||
895 | // (tagName, items, func) | ||
896 | var defaultAttrs = {}, | ||
897 | items = arguments[1], | ||
898 | func = (isFunction(arguments[2]) ? arguments[2] : null); | ||
899 | } | ||
900 | else | ||
901 | { | ||
902 | // (tagName, attrs, items, func) | ||
903 | var defaultAttrs = arguments[1], | ||
904 | items = arguments[2], | ||
905 | func = (isFunction(arguments[3]) ? arguments[3] : null); | ||
906 | } | ||
907 | |||
908 | var results = []; | ||
909 | for (var i = 0, l = items.length; i < l; i++) | ||
910 | { | ||
911 | var attrs = extend({}, defaultAttrs); | ||
912 | // If we were given a mapping function, call it and use the | ||
913 | // return value as the contents, unless the function specifies | ||
914 | // that the item shouldn't generate an element by explicity | ||
915 | // returning null. | ||
916 | if (func !== null) | ||
917 | { | ||
918 | var children = func(items[i], attrs, i); | ||
919 | if (children === null) | ||
920 | { | ||
921 | continue; | ||
922 | } | ||
923 | } | ||
924 | else | ||
925 | { | ||
926 | // If we weren't given a mapping function, use the item as the | ||
927 | // contents. | ||
928 | var children = items[i]; | ||
929 | } | ||
930 | |||
931 | // Ensure children are in an Array, as required by createElement | ||
932 | if (!isArray(children)) | ||
933 | { | ||
934 | children = [children]; | ||
935 | } | ||
936 | |||
937 | results.push(this.createElement(tagName, attrs, children)); | ||
938 | } | ||
939 | return results; | ||
940 | }, | ||
941 | |||
942 | /** | ||
943 | * Creates a ``DocumentFragment`` with the given children. Supported | ||
944 | * argument formats are: | ||
945 | * | ||
946 | * ``(child1, ...)`` | ||
947 | * an arbitrary number of children. | ||
948 | * ``([child1, ...])`` | ||
949 | * an ``Array`` of children. | ||
950 | * | ||
951 | * A ``DocumentFragment`` conveniently allows you to append its contents | ||
952 | * with a single call. If you're thinking of adding a wrapper ``<div>`` | ||
953 | * solely to be able to insert a number of sibling elements at the same | ||
954 | * time, a ``DocumentFragment`` will do the same job without the need for | ||
955 | * a redundant wrapper element. | ||
956 | * | ||
957 | * See http://ejohn.org/blog/dom-documentfragments/ for more information | ||
958 | * about ``DocumentFragment`` objects. | ||
959 | */ | ||
960 | fragment: function() | ||
961 | { | ||
962 | if (arguments.length === 1 && | ||
963 | isArray(arguments[0])) | ||
964 | { | ||
965 | var children = arguments[0]; // ([child1, ...]) | ||
966 | } | ||
967 | else | ||
968 | { | ||
969 | var children = slice.call(arguments) // (child1, ...) | ||
970 | } | ||
971 | |||
972 | // Inline the contents of any child Arrays | ||
973 | flatten(children); | ||
974 | |||
975 | if (this.mode != "DOM") | ||
976 | { | ||
977 | return new HTMLFragment(children); | ||
978 | } | ||
979 | |||
980 | var fragment = document.createDocumentFragment(); | ||
981 | for (var i = 0, l = children.length; i < l; i++) | ||
982 | { | ||
983 | var child = children[i]; | ||
984 | if (child.nodeType) | ||
985 | { | ||
986 | fragment.appendChild(child); | ||
987 | } | ||
988 | else | ||
989 | { | ||
990 | fragment.appendChild(document.createTextNode(""+child)); | ||
991 | } | ||
992 | } | ||
993 | |||
994 | return fragment; | ||
995 | }, | ||
996 | |||
997 | /** | ||
998 | * Marks a string as safe | ||
999 | */ | ||
1000 | markSafe: function(value) | ||
1001 | { | ||
1002 | return new SafeString(value); | ||
1003 | }, | ||
1004 | |||
1005 | /** | ||
1006 | * Determines if a string is safe. | ||
1007 | */ | ||
1008 | isSafe: function(value) | ||
1009 | { | ||
1010 | return (value instanceof SafeString); | ||
1011 | }, | ||
1012 | |||
1013 | HTMLElement: HTMLElement, | ||
1014 | HTMLFragment: HTMLFragment, | ||
1015 | HTMLNode: HTMLNode, | ||
1016 | SafeString: SafeString | ||
1017 | }; | ||
1018 | |||
1019 | /** | ||
1020 | * Creates a fragment wrapping content created for every item in a | ||
1021 | * list. | ||
1022 | * | ||
1023 | * Arguments are as follows: | ||
1024 | * | ||
1025 | * ``items`` | ||
1026 | * the list of items to use as the basis for creating fragment | ||
1027 | * contents. | ||
1028 | * ``mappingFunction`` | ||
1029 | * a function to be called with each item in the list, to provide | ||
1030 | * contents for the fragment. | ||
1031 | * | ||
1032 | * Contents can consist of a single value or a mixed ``Array``. | ||
1033 | * | ||
1034 | * The function will be called with the following arguments:: | ||
1035 | * | ||
1036 | * func(item, itemIndex) | ||
1037 | * | ||
1038 | * The function can indicate that the given item shouldn't generate | ||
1039 | * any content for the fragment by returning ``null``. | ||
1040 | */ | ||
1041 | DOMBuilder.fragment.map = function(items, func) | ||
1042 | { | ||
1043 | // If we weren't given a mapping function, the user may as well just | ||
1044 | // have created a fragment directly, as we're just wrapping content | ||
1045 | // here, not creating it. | ||
1046 | if (!isFunction(func)) | ||
1047 | { | ||
1048 | return DOMBuilder.fragment(items); | ||
1049 | } | ||
1050 | |||
1051 | var results = []; | ||
1052 | for (var i = 0, l = items.length; i < l; i++) | ||
1053 | { | ||
1054 | // Call the mapping function and add the return value to the | ||
1055 | // fragment contents, unless the function specifies that the item | ||
1056 | // shouldn't generate content by explicity returning null. | ||
1057 | var children = func(items[i], i); | ||
1058 | if (children === null) | ||
1059 | { | ||
1060 | continue; | ||
1061 | } | ||
1062 | results = results.concat(children); | ||
1063 | } | ||
1064 | return DOMBuilder.fragment(results); | ||
1065 | }; | ||
1066 | |||
1067 | // Export DOMBuilder or expose it to the global object | ||
1068 | if (modules) | ||
1069 | { | ||
1070 | module.exports = DOMBuilder; | ||
1071 | } | ||
1072 | else | ||
1073 | { | ||
1074 | __global__.DOMBuilder = DOMBuilder; | ||
1075 | } | ||
1076 | |||
1077 | })(this); | ||
1078 | |||
1079 | |||
1080 | DOM.BUILDER = DOMBuilder.apply(); | ||
1081 | |||
1082 | DOM.getIndex = function getIndex (currentNode) | ||
1083 | { | ||
1084 | var kids = currentNode.parentNode.childNodes; | ||
1085 | var j = 0; | ||
1086 | for(var i=0; i< kids.length; i++) | ||
1087 | { | ||
1088 | if (currentNode.nodeName == kids[i].nodeName) | ||
1089 | j++; | ||
1090 | if (currentNode == kids[i]) | ||
1091 | { | ||
1092 | return j; | ||
1093 | } | ||
1094 | else | ||
1095 | continue; | ||
1096 | } | ||
1097 | return -1; | ||
1098 | }; | ||
1099 | |||
1100 | DOM.getElementIdx = function getElementIdx(elt) | ||
1101 | { | ||
1102 | var count = 1; | ||
1103 | for (var sib = elt.previousSibling; sib ; sib = sib.previousSibling) | ||
1104 | { | ||
1105 | if(sib.nodeType == 1 && sib.tagName == elt.tagName)count++ | ||
1106 | } | ||
1107 | |||
1108 | return count; | ||
1109 | }; | ||
1110 | |||
1111 | DOM.makePath = function makePath(elt){ | ||
1112 | var path = ''; | ||
1113 | for (; elt && elt.nodeType == 1; elt = elt.parentNode) | ||
1114 | { | ||
1115 | if (elt.attributes['m4pageedittype'] === undefined || elt.attributes['m4pageedittype'].nodeValue != 'text') | ||
1116 | { | ||
1117 | idx = DOM.getElementIdx(elt); | ||
1118 | xname = elt.tagName; | ||
1119 | if (idx > 1) xname += "[" + idx + "]"; | ||
1120 | path = "/" + xname + path; | ||
1121 | } | ||
1122 | } | ||
1123 | return path; | ||
1124 | }; | ||
1125 | |||
1126 | DOM.evaluate = function evaluate(path,newcontent){ | ||
1127 | var nodes = document.evaluate(path, document, null, XPathResult.ANY_TYPE,null); | ||
1128 | try{ | ||
1129 | var result = nodes.iterateNext(); | ||
1130 | while (result) | ||
1131 | { | ||
1132 | if (result.tagName == "img" || result.tagName =='IMG'){ | ||
1133 | url=newcontent.split(',')[1]; | ||
1134 | size = newcontent.split(',')[0].split('x'); | ||
1135 | width = size[0]; | ||
1136 | height = size[1]; | ||
1137 | result.setAttribute('src',url) | ||
1138 | result.setAttribute('width',width); | ||
1139 | result.setAttribute('height',height); | ||
1140 | |||
1141 | } | ||
1142 | else{ | ||
1143 | result.textContent = newcontent; | ||
1144 | } | ||
1145 | result=nodes.iterateNext(); | ||
1146 | } | ||
1147 | } | ||
1148 | catch (e) | ||
1149 | { | ||
1150 | dump( 'error: Document tree modified during iteration ' + e ); | ||
1151 | } | ||
1152 | |||
1153 | } | ||
1154 | |||
1155 | DOM.getXPATH = function getXPath(element) | ||
1156 | { | ||
1157 | var doc = document; | ||
1158 | //we get the selections | ||
1159 | var selection = window.getSelection(); | ||
1160 | var str = ''; | ||
1161 | //var currentNode = selection.getRangeAt(i).commonAncestorContainer; | ||
1162 | var currentNode = element; | ||
1163 | var path = ''; | ||
1164 | var index = -1; | ||
1165 | if ( currentNode == undefined) { | ||
1166 | currentNode = document.getElementById("alipiSelectedElement"); | ||
1167 | } | ||
1168 | |||
1169 | if (currentNode.nodeName != "#text") | ||
1170 | { | ||
1171 | path = DOM.makePath(currentNode); | ||
1172 | } | ||
1173 | else | ||
1174 | { | ||
1175 | path = DOM.makePath(currentNode.parentNode); | ||
1176 | } | ||
1177 | |||
1178 | |||
1179 | return path; | ||
1180 | }; | ||
1181 | |||
1182 | DOM.findPosition = function findPosition(element) { | ||
1183 | var currentLeft = 0, currentTop = 0; | ||
1184 | |||
1185 | if (element.offsetParent) { | ||
1186 | do { | ||
1187 | currentLeft += element.offsetLeft; | ||
1188 | currentTop += element.offsetTop; | ||
1189 | } while (element = element.offsetParent); | ||
1190 | } | ||
1191 | |||
1192 | return { x : currentLeft, y : currentTop }; | ||
1193 | }; | ||
1194 | |||
1195 | DOM.findSize = function findSize(element) { | ||
1196 | return { width : element.clientWidth, height: element.clientHeight }; | ||
1197 | }; | ||
1198 | |||
1199 | DOM.clickBlocker = function clickBlocker(element) { | ||
1200 | var size = DOM.findSize(element), position; | ||
1201 | |||
1202 | if (size.width > 0 && size.height > 0) { | ||
1203 | position = DOM.findPosition(element); | ||
1204 | |||
1205 | document.body.appendChild(DOM.BUILDER.DIV( { style : 'background: transparent; z-index: 2147483644; width:' | ||
1206 | + (size.width + 'px') + '; height:' + (size.height + 'px') | ||
1207 | + '; position: absolute; left:' + (position.x + 'px') + '; top:' + (position.y + 'px') + ';' })); | ||
1208 | } | ||
1209 | }; | ||
1210 | |||
1211 | DOM.overrideStyleProperty = function overrideStyleProperty(object, property, value) { | ||
1212 | var savedName = 'm4p' + property.toUpperCase(); | ||
1213 | |||
1214 | object.style[savedName] = object.style[property]; | ||
1215 | object.style[property] = value; | ||
1216 | }; | ||
1217 | |||
1218 | DOM.restoreStyleProperty = function restoreStyleProperty(object, property, fallback) { | ||
1219 | var savedName = 'm4p' + property.toUpperCase(); | ||
1220 | |||
1221 | if (object.style[savedName] !== undefined) { | ||
1222 | object.style[property] = object.style[savedName]; | ||
1223 | } else { | ||
1224 | object.style[property] = fallback; | ||
1225 | } | ||
1226 | |||
1227 | object.style[savedName] = undefined; | ||
1228 | }; | ||
1229 | |||
1230 | DOM.deleteStyleProperty = (function() { | ||
1231 | if (typeof document.createElement('div').style.removeAttribute !== 'undefined') { | ||
1232 | // IE specific | ||
1233 | return function deleteStyleProperty(object, property) { | ||
1234 | object.style.removeAttribute(property); | ||
1235 | }; | ||
1236 | } else { | ||
1237 | // W3C standard | ||
1238 | return function deleteStyleProperty(object, property) { | ||
1239 | object.style.removeProperty(property); | ||
1240 | }; | ||
1241 | } | ||
1242 | })(); | ||
1243 | |||
1244 | // Not to be used for Style attributes. For style attributes use overrideStyleProperty instead | ||
1245 | DOM.overrideAttribute = function overrideAttribute (object, attributeName, value) { | ||
1246 | var savedName = 'm4p' + attributeName.toUpperCase(); | ||
1247 | if (object[attributeName]) { | ||
1248 | var attributeValue = object.getAttribute(attributeName); | ||
1249 | if (attributeValue) { | ||
1250 | object.setAttribute(savedName, attributeValue); | ||
1251 | } | ||
1252 | } | ||
1253 | object.setAttribute(attributeName, value); | ||
1254 | }; | ||
1255 | |||
1256 | // Not to be used for Style attributes. For style attributes use restoreStyleProperty instead | ||
1257 | DOM.restoreAttribute = function restoreAttribute (object, attributeName) { | ||
1258 | var savedName = 'm4p' + attributeName.toUpperCase(); | ||
1259 | if (object[attributeName]) { | ||
1260 | var originalValue = object.getAttribute(savedName); | ||
1261 | if (originalValue != null) { | ||
1262 | object.setAttribute(attributeName, originalValue); | ||
1263 | object.removeAttribute(savedName); | ||
1264 | } else { | ||
1265 | object.removeAttribute(attributeName); | ||
1266 | } | ||
1267 | } | ||
1268 | }; | ||
1269 | |||
1270 | DOM.addListener = (function() { | ||
1271 | if (document.attachEvent) { | ||
1272 | // Simulates W3C event model in IE | ||
1273 | return function addListener(type, callback, capture) { | ||
1274 | document.attachEvent('on' + type, function() { | ||
1275 | callback( { | ||
1276 | target : window.event.srcElement, | ||
1277 | pageX : window.event.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft), | ||
1278 | pageY : window.event.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop), | ||
1279 | clientX : window.event.clientX, | ||
1280 | clientY : window.event.clientY, | ||
1281 | keyCode : window.event.keyCode, | ||
1282 | ctrlKey : window.event.ctrlKey, | ||
1283 | preventDefault : function() { | ||
1284 | window.event.returnValue = false; | ||
1285 | }, | ||
1286 | stopPropagation : function() { | ||
1287 | window.event.cancelBubble = true; | ||
1288 | } | ||
1289 | }); | ||
1290 | }); | ||
1291 | } | ||
1292 | } else { | ||
1293 | return function addListener(type, callback, capture) { | ||
1294 | document.addEventListener(type, callback, capture); | ||
1295 | }; | ||
1296 | } | ||
1297 | })(); | ||
1298 | |||
1299 | DOM.textContent = (function() { | ||
1300 | if (document.all) { | ||
1301 | // IE specific | ||
1302 | return function textContent(element, content) { | ||
1303 | if (content) { | ||
1304 | element.innerText = content; | ||
1305 | } | ||
1306 | return element.innerText; | ||
1307 | } | ||
1308 | } else { | ||
1309 | return function textContent(element, content) { | ||
1310 | if (element == undefined) { | ||
1311 | element = document.getElementById("alipiSelectedElement"); | ||
1312 | content = document.getElementById("alipiSelectedElement").textContent; | ||
1313 | element.textContent = content; | ||
1314 | } else if (content) { | ||
1315 | element.textContent = content; | ||
1316 | } | ||
1317 | return element.textContent; | ||
1318 | } | ||
1319 | } | ||
1320 | })(); | ||
1321 | |||
1322 | DOM.viewDimension = function viewDimension() { | ||
1323 | var width, height; | ||
1324 | if (window.innerWidth) { | ||
1325 | width = window.innerWidth; | ||
1326 | } else if (document.documentElement && document.documentElement.clientWidth) { | ||
1327 | width = document.documentElement.clientWidth; | ||
1328 | } else if (document.body) { | ||
1329 | width = document.body.clientWidth; | ||
1330 | } | ||
1331 | |||
1332 | if (window.innerHeight) { | ||
1333 | height = window.innerHeight; | ||
1334 | } else if (document.documentElement && document.documentElement.clientHeight) { | ||
1335 | height = document.documentElement.clientHeight; | ||
1336 | } else if (document.body) { | ||
1337 | height = document.body.clientHeight; | ||
1338 | } | ||
1339 | |||
1340 | return [ width, height ]; | ||
1341 | }; | ||
1342 | |||
1343 | DOM.isElementOfType = function isElementOfType(element, tagName) { | ||
1344 | return (element && element.nodeName && tagName && element.tagName.toLowerCase() == tagName.toLowerCase()) ; | ||
1345 | }; | ||
1346 | |||
1347 | DOM.isQuirksMode = function isQuirksMode() { | ||
1348 | |||
1349 | return ( (document.documentMode && document.documentMode == 5) | ||
1350 | || (document.compatMode && document.compatMode == 'BackCompat')) ; | ||
1351 | } | ||
1352 | |||
1353 | /* | ||
1354 | * Use this with caution.. | ||
1355 | */ | ||
1356 | DOM.isIEBrowser = function isIEBrowser() { | ||
1357 | return (window.navigator.appName == 'Microsoft Internet Explorer'); | ||
1358 | } | ||
1359 | |||
1360 | // Immutable set of DOM Element Attributes | ||
1361 | DOM.Attributes = function(initialAttributes, additionalAttributes) { | ||
1362 | var self = this, attributes = {}, attribute; | ||
1363 | |||
1364 | var set = function(moreAttributes) { | ||
1365 | if (moreAttributes instanceof DOM.Attributes) { | ||
1366 | moreAttributes = moreAttributes.values(); | ||
1367 | } | ||
1368 | |||
1369 | for (attribute in moreAttributes) { | ||
1370 | attributes[attribute] = moreAttributes[attribute]; | ||
1371 | } | ||
1372 | }; | ||
1373 | |||
1374 | set(initialAttributes); | ||
1375 | if (additionalAttributes) { | ||
1376 | set(additionalAttributes) | ||
1377 | } | ||
1378 | |||
1379 | this.addStyle = function(value) { | ||
1380 | var style; | ||
1381 | |||
1382 | if (attributes['style']) { | ||
1383 | // later inline styles override | ||
1384 | style = attributes['style'] + ' ' + value; | ||
1385 | } else { | ||
1386 | style = value; | ||
1387 | } | ||
1388 | |||
1389 | return new DOM.Attributes(attributes, { 'style': style }); | ||
1390 | }; | ||
1391 | |||
1392 | this.put = function(moreAttributes) { | ||
1393 | return new DOM.Attributes(attributes, moreAttributes) | ||
1394 | }; | ||
1395 | |||
1396 | this.values = function() { | ||
1397 | var result = {}; | ||
1398 | for (attribute in attributes) { | ||
1399 | result[attribute] = attributes[attribute]; | ||
1400 | } | ||
1401 | return result; | ||
1402 | } | ||
1403 | }; | ||
1404 | })(DOM); | ||
1405 | // // | ||
1406 | |||
1407 | /** | ||
1408 | * AJAX utility class / functions. | ||
1409 | */ | ||
1410 | var AJAX = AJAX || {}; | ||
1411 | |||
1412 | (function(AJAX) { | ||
1413 | AJAX.createXmlHttpRequest = function createXmlHttpRequest() { | ||
1414 | if (window.ActiveXObject) { | ||
1415 | return new ActiveXObject("Microsoft.XMLHTTP"); | ||
1416 | } else { | ||
1417 | return new XMLHttpRequest(); | ||
1418 | } | ||
1419 | }; | ||
1420 | |||
1421 | AJAX.get = function get(url, callback) { | ||
1422 | return AJAX.ajax('GET', url, null, callback); | ||
1423 | }; | ||
1424 | |||
1425 | AJAX.post = function post(url, data, callback, contentType) { | ||
1426 | return AJAX.ajax('POST', url, data, callback, contentType); | ||
1427 | }; | ||
1428 | |||
1429 | // @param contentType, defaults to 'application/x-www-form-urlencoded; charset=UTF-8', optional | ||
1430 | AJAX.ajax = function ajax(method, url, data, callback, contentType) { | ||
1431 | var http = AJAX.createXmlHttpRequest(); | ||
1432 | var defaultContentType = 'application/x-www-form-urlencoded; charset=UTF-8'; | ||
1433 | if (!contentType) { | ||
1434 | contentType = defaultContentType; | ||
1435 | } | ||
1436 | if (callback) { | ||
1437 | // async | ||
1438 | http.open(method, url, true); | ||
1439 | if (method === 'POST') { | ||
1440 | // must be set after open() | ||
1441 | http.setRequestHeader('Content-type', contentType); | ||
1442 | } | ||
1443 | http.onreadystatechange = function ajaxOnReadyStateChangeHandler() { | ||
1444 | if (http.readyState === 4) { | ||
1445 | callback(http); | ||
1446 | } | ||
1447 | }; | ||
1448 | http.send(data); | ||
1449 | } else { | ||
1450 | // sync | ||
1451 | http.open(method, url, false); | ||
1452 | if (method === 'POST') { | ||
1453 | // must be set after open() | ||
1454 | http.setRequestHeader('Content-type', contentType); | ||
1455 | } | ||
1456 | http.send(data); | ||
1457 | return http; | ||
1458 | } | ||
1459 | }; | ||
1460 | })(AJAX); | ||
1461 | |||
1462 | if (typeof window.console == 'undefined') { | ||
1463 | console = { | ||
1464 | log : function() { | ||
1465 | }, | ||
1466 | error : function() { | ||
1467 | }, | ||
1468 | warn : function() { | ||
1469 | }, | ||
1470 | info : function() { | ||
1471 | }, | ||
1472 | dir : function() { | ||
1473 | } | ||
1474 | } | ||
1475 | } else { | ||
1476 | console = window.console; | ||
1477 | } | ||
1478 | |||
1479 | editAttributes = new DOM.Attributes({ 'm4pageeditcontrol': true }); | ||
1480 | elementAttributes = editAttributes.addStyle('margin:0; padding:0; border:none; text-indent: 0px; background: none;'); | ||
1481 | fontTypeAttributes = elementAttributes.addStyle("font-family: Helvetica Neue, Helvetica, Arial, Sans-serif;"); | ||
1482 | normalFontAttributes = fontTypeAttributes.addStyle("font-weight:bold; font-size:12px; line-height: 10px;"); | ||
1483 | |||
1484 | leftBorderStyle = 'border-top-left-radius:3px; border-bottom-left-radius:3px; -moz-border-radius-topleft:3px; -moz-border-radius-bottomleft:3px; -webkit-border-top-left-radius:3px; -webkit-border-bottom-left-radius:3px;'; | ||
1485 | rightBorderStyle = 'border-top-right-radius:3px; border-bottom-right-radius:3px; -moz-border-radius-topright:3px; -moz-border-radius-bottomright:3px; -webkit-border-top-right-radius:3px; -webkit-border-bottom-right-radius:3px;'; | ||
1486 | |||
1487 | editTextInputAttributes = normalFontAttributes.put({ type : 'text' }).addStyle('width: 70%; float:left; font-weight:normal;color: #747474; border:1px solid #747474; outline-style:none; outline-width:0px; margin:0; padding:2px; margin-left: 0px;').addStyle(leftBorderStyle + rightBorderStyle); | ||
1488 | editTitleAttributes = normalFontAttributes.addStyle("color:#fff; background-color:#333; float:left; padding:3px; border-top-left-radius:3px; border-bottom-left-radius:3px; -moz-border-radius-topleft:3px; -moz-border-radius-bottomleft:3px; -webkit-border-top-left-radius:3px; -webkit-border-bottom-left-radius:3px;"); | ||
1489 | |||
1490 | panelButtonAttributes = fontTypeAttributes.addStyle('height:auto; cursor:pointer; float:right; font-weight:normal; font-size:14px; background-image:none; border-radius:5px; -moz-border-radius:5px; -webkit-border-radius:5px; margin: 16px 16px 0 0; padding: 0 0 4px 0;-khtml-box-sizing: none;-webkit-box-sizing: none;-moz-box-sizing: none;box-sizing: none;text-shadow:none;'); | ||
1491 | editButtonAttributes = normalFontAttributes.addStyle(" height:45px;float:left; position:relative; cursor:pointer;border-top:1px solid #BDBDBD;border-left:1px solid #BDBDBD;border-right:1px solid #BDBDBD;border-bottom:1px solid #BDBDBD;color:#000;background-color:#FFF;margin: 0px;padding: 0px;"); | ||
1492 | |||
1493 | var closeButtonIconPath = 'http://dev.a11y.in/alipi/images/close_button.png'; | ||
1494 | closeButtonAttributes = editButtonAttributes.addStyle('top: -8px; left: -8px; position: absolute; border:none; background: url("' + closeButtonIconPath +'") no-repeat; width: 15px; height: 15px; z-index: 2;'); | ||
1495 | |||
1496 | var redArrowIconPath = './images/caret_red.png'; | ||
1497 | redArrowAttributes = elementAttributes.addStyle('width: 8px; height: 11px;position: relative;background: url(' + redArrowIconPath + ') no-repeat; float: left;margin-top: 10px;z-index:2;left: -1px;'); | ||
1498 | |||
1499 | var greyArrowIconPath = './images/caret_grey.png'; | ||
1500 | greyArrowAttributes = elementAttributes.addStyle('z-index: 2; position: relative; width:11px; height: 7px; background: url(' + greyArrowIconPath + ') no-repeat; float: left; margin-top: 3px; margin-left: 10px; display:none;'); | ||
1501 | |||
1502 | popupContainerAttributes = normalFontAttributes.addStyle('position:absolute; top:0; left:0; display:none; max-height:160px; width:auto; background:transparent; z-index:2147483645;'); | ||
1503 | |||
1504 | buttonPanelAttributes = normalFontAttributes.addStyle('width: auto; height: 53px; float: left; position: relative;'); | ||
1505 | actionPanelAttributes = normalFontAttributes.addStyle(leftBorderStyle + rightBorderStyle).addStyle('position: relative; top: -1px; float: left; display: none; max-height:140px; background:#BDBDBD; border: 1px solid #BDBDBD; width: auto; height: auto; color: #747474; background-color: #DBDBDB; background: -webkit-gradient(linear, 0% 100%, 0% 0%, from(#D9D9D9), to(#F6F6F6));background: -moz-linear-gradient(bottom, #D9D9D9, #F6F6F6); text-shadow: 0px 1px 0px #FFF; -moz-text-shadow: 0px 1px 0px #FFF; -webkit-text-shadow: 0px 1px 0px #FFF;'); | ||
1506 | |||
1507 | actionButtonAttributes = editButtonAttributes.addStyle('font-size:11px; height: 50px; margin: 0; padding-left: 5px; padding-right: 5px; left: -6px; color: #747474; background-color: #DBDBDB; background: -webkit-gradient(linear, 0% 100%, 0% 0%, from(#D9D9D9), to(#F6F6F6));background: -moz-linear-gradient(bottom, #D9D9D9, #F6F6F6); text-shadow: 0px 1px 0px #FFF; -moz-text-shadow: 0px 1px 0px #FFF; -webkit-text-shadow: 0px 1px 0px #FFF;'); | ||
1508 | |||
1509 | redButtonAttributes = editButtonAttributes.addStyle('font-size:11px; height: 50px; margin: 0; border:1px solid #777; -moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px;-moz-border-radius-topleft:3px; -moz-border-radius-bottomleft:3px;-webkit-border-top-right-radius:3px; -webkit-border-bottom-right-radius:3px;-webkit-border-top-left-radius:3px; -webkit-border-bottom-left-radius:3px;text-shadow: 2px 1px 1px #777;-moz-text-shadow: 2px 1px 0px #777;-webkit-text-shadow: 2px 1px 0px #777;background-color: #AAA;background: -webkit-gradient(linear, 0% 100%, 0% 5%, from(#777), to(#fff));background: -moz-linear-gradient(bottom, #777, #fff);'); | ||
1510 | |||
1511 | editSubmitAttributes = redButtonAttributes.put({ type: 'submit', value : 'OK' }).addStyle('height:20px; width: 32px; padding-left: 5px; padding-right: 5px; margin-left: 5px;'); | ||
1512 | |||
1513 | undoSubmitButton = redButtonAttributes.put({ type: 'submit', value : 'undo' }).addStyle('height:20px; width: 32px; padding-left: 5px; padding-right: 5px; margin-left: 5px;'); | ||
1514 | |||
1515 | titleButtonImageAttributes = elementAttributes.put({src: 'https://bo.lt/app/asset/page-edit/bo_icon_28x17.png?p=622fd096a39f5c36a6e06e41a9963dafaad61079'}).addStyle('display:block; width: 28px; height: 17px; margin-left: auto;margin-right: auto; margin-top: 2px; margin-bottom: 0px;'); | ||
1516 | titleButtonDisplayTextAttributes = fontTypeAttributes.addStyle('text-align: center; height: auto; color: #FFF; display:block; margin-left: auto;margin-right: auto; margin-top: 5px; margin-bottom: 5px; font-style: normal; font-size: 11px; text-shadow: 2px 1px 1px #777 -moz-text-shadow: 2px 1px 0px #777;-webkit-text-shadow: 2px 1px 0px #777;'); | ||
1517 | |||
1518 | actionButtonImageAttributes = elementAttributes.addStyle('width: 16px; height: 17px; margin-left: auto; margin-right: auto; margin-top: 5px; padding-top: 2px; padding-bottom: 0px; margin-bottom: 0px; display:block;'); | ||
1519 | actionButtonDisplayTextAttributes = fontTypeAttributes.addStyle('text-align: center; height: auto; color: #777; text-shadow: 0px 1px 0px #FFF; -moz-text-shadow: 0px 1px 0px #FFF; -webkit-text-shadow: 0px 1px 0px #FFF; font-size: 11px; margin-left: auto;margin-right: auto; margin-top: 5px; margin-bottom: 5px; padding-left: 10px; padding-right: 10px; width: auto; display:block;'); | ||
1520 | |||
1521 | |||
1522 | createActionButton = function createActionButton(buttonImage, displayText, buttonStyle) { | ||
1523 | var image = DOM.BUILDER.IMG(actionButtonImageAttributes.put({src: buttonImage}).values()); | ||
1524 | var text = DOM.BUILDER.SPAN(actionButtonDisplayTextAttributes.values()); | ||
1525 | text.innerHTML = displayText; | ||
1526 | var button = DOM.BUILDER.BUTTON(actionButtonAttributes.addStyle(buttonStyle).values()); | ||
1527 | button.appendChild(image); | ||
1528 | button.appendChild(text); | ||
1529 | return button; | ||
1530 | }; | ||
1531 | |||
1532 | var createTitleButton = function createTitleButton(displayText, buttonStyle) { | ||
1533 | var image = DOM.BUILDER.IMG(titleButtonImageAttributes.values()); | ||
1534 | var text = DOM.BUILDER.SPAN(titleButtonDisplayTextAttributes.values()); | ||
1535 | text.innerHTML = displayText; | ||
1536 | var button = DOM.BUILDER.BUTTON(redButtonAttributes.addStyle(buttonStyle).addStyle(leftBorderStyle + rightBorderStyle).values()); | ||
1537 | button.appendChild(image); | ||
1538 | button.appendChild(text); | ||
1539 | return button; | ||
1540 | }; | ||
1541 | |||
1542 | var displayUpArrowUnderButton = function displayUpArrowUnderButton(button, upArrow){ | ||
1543 | upArrow.style.display = 'block'; | ||
1544 | upArrow.style.marginLeft = (button.offsetLeft + button.offsetWidth/2) + 'px'; | ||
1545 | }; | ||
1546 | |||
1547 | AjaxResultProcessor = function AjaxResultProcessor() { | ||
1548 | this.processSwitchModeResponse = function processSwitchModeResponse(result) { | ||
1549 | if (result.status == 200) { | ||
1550 | window.location.href = eval("(" + result.responseText + ")").switchModeRedirectUrl; | ||
1551 | } else { | ||
1552 | pageEditor.showMessage(result.statusText); | ||
1553 | } | ||
1554 | }; | ||
1555 | |||
1556 | |||
1557 | this.processPublishedResponse = function processPublishedResponse(result) { | ||
1558 | var resultString = result.responseText; | ||
1559 | if (resultString == 'ok'){ | ||
1560 | alert("Re-narration successfuly posted"); | ||
1561 | window.location.reload(); | ||
1562 | } | ||
1563 | else{ | ||
1564 | console.warn(resultString); | ||
1565 | alert("Re-narration failed, please try later!"); | ||
1566 | } | ||
1567 | }; | ||
1568 | }; | ||
1569 | |||
1570 | |||
1571 | M4ImageElement = function M4ImageElement(element) { | ||
1572 | var self = this; | ||
1573 | |||
1574 | if (typeof element.m4boltOriginalWidth == 'undefined') { | ||
1575 | element.m4boltOriginalWidth = element.width; | ||
1576 | } | ||
1577 | if (typeof element.m4boltOriginalHeight == 'undefined') { | ||
1578 | element.m4boltOriginalHeight = element.height; | ||
1579 | } | ||
1580 | |||
1581 | this.getOriginalSize = function getOriginalSize() { | ||
1582 | return { width: element.m4boltOriginalWidth, height: element.m4boltOriginalHeight }; | ||
1583 | }; | ||
1584 | |||
1585 | this.setRawImageSize = function setRawImageSize(size) { | ||
1586 | element.m4boltRawImageWidth = size.width; | ||
1587 | element.m4boltRawImageHeight = size.height; | ||
1588 | |||
1589 | return self; | ||
1590 | }; | ||
1591 | |||
1592 | this.getRawImageSize = function getRawImageSize() { | ||
1593 | if (typeof element.m4boltRawImageWidth == 'undefined' || typeof element.m4boltRawImageHeight == 'undefined') { | ||
1594 | return { width : 0, height: 0 }; | ||
1595 | } | ||
1596 | return { width : element.m4boltRawImageWidth, height : element.m4boltRawImageHeight }; | ||
1597 | }; | ||
1598 | |||
1599 | this.getFittedSize = function getFittedSize() { | ||
1600 | var size = self.getRawImageSize(), original = self.getOriginalSize(); | ||
1601 | |||
1602 | if (size.width > original.width) { | ||
1603 | size.height = size.height * (original.width / size.width); | ||
1604 | size.width = original.width; | ||
1605 | } | ||
1606 | if (size.height > original.height) { | ||
1607 | size.width = size.width * (original.height / size.height); | ||
1608 | size.height = original.height; | ||
1609 | } | ||
1610 | size.height = Math.floor(size.height); | ||
1611 | size.width = Math.floor(size.width); | ||
1612 | |||
1613 | return size; | ||
1614 | }; | ||
1615 | |||
1616 | this.isFittable = function isFittable() { | ||
1617 | return (typeof element.m4boltRawImageWidth != 'undefined' && element.m4boltRawImageWidth > element.m4boltOriginalWidth) | ||
1618 | || (typeof element.m4boltRawImageHeight != 'undefined' && element.m4boltRawImageHeight > element.m4boltOriginalHeight); | ||
1619 | }; | ||
1620 | }; | ||
1621 | |||
1622 | SplashWindow = function SplashWindow(pageEditor ) { | ||
1623 | |||
1624 | this.createLabels = function createLabels() { | ||
1625 | |||
1626 | msg = document.createElement('div'); | ||
1627 | msg.setAttribute("id", "msgoverlay"); | ||
1628 | msg.setAttribute("title", "PAGE EDITOR"); | ||
1629 | msg.setAttribute("alipielements", "alipi"); | ||
1630 | msg.setAttribute("style", "color:#000;line-height:25px;"); | ||
1631 | document.body.appendChild(msg); | ||
1632 | |||
1633 | msgDesc = document.createElement("label"); | ||
1634 | msgDesc.setAttribute("id", "msg-desc"); | ||
1635 | msgDesc.innerHTML = 'Click on any part of the page, and you will activate buttons that allow you to modify text, replace images and add audio. Don\'t forget to hit "Publish" when you\'re finished editing so we can save your newly-crafted page... And at any moment if you need help then hit a "Help" button.<br /> Don\'t show this again '; | ||
1636 | msg.appendChild(msgDesc); | ||
1637 | |||
1638 | pubLabel = document.createElement("input"); | ||
1639 | pubLabel.setAttribute("id", "check-box"); | ||
1640 | pubLabel.setAttribute("alipielements", "alipi"); | ||
1641 | pubLabel.setAttribute("type", "checkbox"); | ||
1642 | pubLabel.setAttribute("name","msgcheckbox"); | ||
1643 | pubLabel.setAttribute("style", "margin-top:20px;"); | ||
1644 | msg.appendChild(pubLabel); | ||
1645 | }; | ||
1646 | |||
1647 | |||
1648 | function display() { | ||
1649 | $(function() { | ||
1650 | $( "#msgoverlay" ).dialog({ | ||
1651 | width:600, | ||
1652 | height:250, | ||
1653 | modal: true, | ||
1654 | close: function() { | ||
1655 | $("#msgoverlay").remove(); | ||
1656 | }, | ||
1657 | buttons: { | ||
1658 | OK: function() { hide(); | ||
1659 | $("#msgoverlay").remove(); | ||
1660 | } | ||
1661 | } | ||
1662 | |||
1663 | }); | ||
1664 | }); | ||
1665 | }; | ||
1666 | |||
1667 | this.activate = function activate() { | ||
1668 | |||
1669 | var allCookies = document.cookie; | ||
1670 | if (allCookies.indexOf('m4.show.redbar.overlay=no') == -1) { | ||
1671 | display(); | ||
1672 | } else { | ||
1673 | hide(); | ||
1674 | } | ||
1675 | |||
1676 | }; | ||
1677 | |||
1678 | function hide() { | ||
1679 | if (document.getElementById("check-box").checked) { | ||
1680 | document.cookie ='m4.show.redbar.overlay=no;' | ||
1681 | } else { | ||
1682 | // var date = new Date(); | ||
1683 | // document.cookie ='m4.show.redbar.overlay=no;expires=' + date.toUTCString() + ';'; | ||
1684 | $("#msgoverlay").hide(); | ||
1685 | } | ||
1686 | }; | ||
1687 | } ; | ||
1688 | |||
1689 | |||
1690 | //------------------------------------ Target UI -------------------------------------------- | ||
1691 | TargetWindow = function TargetWindow(pageEditor ) { | ||
1692 | |||
1693 | this.createDialogBox = function createDialogBox() { | ||
1694 | |||
1695 | target = document.createElement("div"); | ||
1696 | target.setAttribute("id", "targetoverlay"); | ||
1697 | target.setAttribute("title", "Please choose the target"); | ||
1698 | target.setAttribute("alipielements", "alipi"); | ||
1699 | target.setAttribute("class", "ui-widget-header ui-corner-all"); | ||
1700 | document.body.appendChild(target); | ||
1701 | |||
1702 | locLabel= document.createElement("label"); | ||
1703 | locLabel.innerHTML = 'Select Location'; | ||
1704 | locLabel.setAttribute("style", "position:absolute;top:5%;left:3%;color:#000;"); | ||
1705 | target.appendChild(locLabel); | ||
1706 | |||
1707 | locName= document.createElement("input"); | ||
1708 | locName.setAttribute("id","loc-select"); | ||
1709 | locName.setAttribute("type","text"); | ||
1710 | locName.setAttribute("alipielements", "alipi"); | ||
1711 | locName.setAttribute("style","position:absolute;top:5%;left:40%;width:250px;"); | ||
1712 | target.appendChild(locName); | ||
1713 | |||
1714 | langLabel= document.createElement("label"); | ||
1715 | langLabel.innerHTML = 'Select Language'; | ||
1716 | langLabel.setAttribute("style", "position:absolute;top:25%;left:3%;color:#000;"); | ||
1717 | target.appendChild(langLabel); | ||
1718 | |||
1719 | langName= document.createElement("input"); | ||
1720 | langName.setAttribute("id","lang-select"); | ||
1721 | langName.setAttribute("type","text"); | ||
1722 | langName.setAttribute("alipielements", "alipi"); | ||
1723 | langName.setAttribute("style","position:absolute;top:25%;left:40%;width:250px;"); | ||
1724 | target.appendChild(langName); | ||
1725 | |||
1726 | styleLabel= document.createElement("label"); | ||
1727 | styleLabel.innerHTML = 'Select style'; | ||
1728 | styleLabel.setAttribute("style", "position:absolute;top:45%;left:3%;color:#000;"); | ||
1729 | target.appendChild(styleLabel); | ||
1730 | |||
1731 | styleSelect = document.createElement("input"); | ||
1732 | styleSelect.setAttribute("id","styleSelect-select"); | ||
1733 | styleSelect.setAttribute("type","text"); | ||
1734 | styleSelect.setAttribute("alipielements", "alipi"); | ||
1735 | styleSelect.setAttribute("style","position:absolute;top:45%;left:40%;width:250px;"); | ||
1736 | target.appendChild(styleSelect); | ||
1737 | |||
1738 | authLabel= document.createElement("label"); | ||
1739 | authLabel.innerHTML = 'Author Name'; | ||
1740 | authLabel.setAttribute("style", "position:absolute;top:65%;left:3%;color:#000;"); | ||
1741 | target.appendChild(authLabel); | ||
1742 | |||
1743 | author= document.createElement("input"); | ||
1744 | author.setAttribute("id","auth-select"); | ||
1745 | author.setAttribute("type","text"); | ||
1746 | author.setAttribute("alipielements", "alipi"); | ||
1747 | author.setAttribute("style","position:absolute;top:65%;left:40%;width:250px;"); | ||
1748 | target.appendChild(author); | ||
1749 | |||
1750 | ourcheck = document.createElement("input"); | ||
1751 | ourcheck.setAttribute("id","our-check"); | ||
1752 | ourcheck.setAttribute("type","radio"); | ||
1753 | ourcheck.setAttribute("name", "blog"); | ||
1754 | ourcheck.setAttribute("alipielements", "alipi"); | ||
1755 | ourcheck.setAttribute("style","position:absolute;top:85%;left:40%;"); | ||
1756 | target.appendChild(ourcheck); | ||
1757 | |||
1758 | yourcheck = document.createElement("input"); | ||
1759 | yourcheck.setAttribute("id","your-check"); | ||
1760 | yourcheck.setAttribute("type","radio"); | ||
1761 | yourcheck.setAttribute("name", "blog"); | ||
1762 | yourcheck.setAttribute("alipielements", "alipi"); | ||
1763 | yourcheck.setAttribute("style","position:absolute;top:85%;left:70%;"); | ||
1764 | target.appendChild(yourcheck); | ||
1765 | |||
1766 | yourLabel = document.createElement('label'); | ||
1767 | yourLabel.textContent = "Your blog"; | ||
1768 | yourLabel.setAttribute("style","position:absolute;top:85%;left:45%;color:#000;"); | ||
1769 | target.appendChild(yourLabel); | ||
1770 | |||
1771 | ourLabel = document.createElement('label'); | ||
1772 | ourLabel.textContent = "Our blog"; | ||
1773 | ourLabel.setAttribute("style","position:absolute;top:85%;left:75%;color:#000;"); | ||
1774 | target.appendChild(ourLabel); | ||
1775 | } | ||
1776 | |||
1777 | this.activate = function activate() { | ||
1778 | $(function() { | ||
1779 | $( "#targetoverlay" ).dialog({ | ||
1780 | height:500, | ||
1781 | width:500, | ||
1782 | modal: true, | ||
1783 | buttons: { | ||
1784 | OK: function() { | ||
1785 | overlayBar = new OverlayBar(pageEditor); | ||
1786 | overlayBar.blogpost(); | ||
1787 | } | ||
1788 | }, | ||
1789 | close: function() { | ||
1790 | $( "#targetoverlay" ).hide(); | ||
1791 | } | ||
1792 | }); | ||
1793 | }); | ||
1794 | |||
1795 | |||
1796 | |||
1797 | $( "#loc-select" ).autocomplete({ | ||
1798 | source: function(req, add){ | ||
1799 | |||
1800 | //pass request to server | ||
1801 | $.getJSON("http://y.a11y.in/loc?", req, function(data) { | ||
1802 | |||
1803 | //create array for response objects | ||
1804 | var suggestions = []; | ||
1805 | |||
1806 | //process response | ||
1807 | $.each(data, function(i, val){ | ||
1808 | //suggestions.push(val.country); | ||
1809 | for(i=0;i<val.length;i++){ | ||
1810 | suggestions.push(val[i]); | ||
1811 | } | ||
1812 | }); | ||
1813 | |||
1814 | //pass array to callback | ||
1815 | add(suggestions); | ||
1816 | }); | ||
1817 | }, | ||
1818 | }); | ||
1819 | |||
1820 | $( "#lang-select" ).autocomplete({ | ||
1821 | source: function(req, add){ | ||
1822 | |||
1823 | //pass request to server | ||
1824 | $.getJSON("http://y.a11y.in/lang?", req, function(data) { | ||
1825 | |||
1826 | //create array for response objects | ||
1827 | var suggestions = []; | ||
1828 | |||
1829 | //process response | ||
1830 | $.each(data, function(i, val){ | ||
1831 | //suggestions.push(val.country); | ||
1832 | for(i=0;i<val.length;i++){ | ||
1833 | suggestions.push(val[i]); | ||
1834 | } | ||
1835 | }); | ||
1836 | |||
1837 | //pass array to callback | ||
1838 | add(suggestions); | ||
1839 | }); | ||
1840 | }, | ||
1841 | }); | ||
1842 | |||
1843 | |||
1844 | } | ||
1845 | |||
1846 | }; | ||
1847 | |||
1848 | // ------------------------------------ Target UI end --------------------------------------------- | ||
1849 | |||
1850 | // ========================================== Edit Window start ====================================================== | ||
1851 | |||
1852 | |||
1853 | EditWindow = function EditWindow(pageEditor) { | ||
1854 | |||
1855 | editor = document.createElement("div"); | ||
1856 | editor.setAttribute("id", "editoroverlay"); | ||
1857 | editor.setAttribute("title", "Edit window"); | ||
1858 | editor.setAttribute("alipielements", "alipi"); | ||
1859 | editor.setAttribute("class", "ui-widget-header ui-corner-all"); | ||
1860 | document.body.appendChild(editor); | ||
1861 | |||
1862 | refLabel= document.createElement("label"); | ||
1863 | refLabel.innerHTML = 'Reference'; | ||
1864 | refLabel.setAttribute("style", "position:absolute;top:5%;left:20%;color:#000;font-size:25px;"); | ||
1865 | editor.appendChild(refLabel); | ||
1866 | |||
1867 | refBox= document.createElement("textarea"); | ||
1868 | refBox.setAttribute("id","reference"); | ||
1869 | refBox.setAttribute("readonly", 'yes'); | ||
1870 | refBox.setAttribute("style","position:absolute;top:15%;left:4%;min-width:450px;max-width:450px;min-height:370px;max-height:370px;font-size:15;text-align:justify;"); | ||
1871 | editor.appendChild(refBox); | ||
1872 | |||
1873 | editLabel= document.createElement("label"); | ||
1874 | editLabel.innerHTML = 'Editor'; | ||
1875 | editLabel.setAttribute("style", "position:absolute;top:5%;left:70%;color:#000;font-size:25px;"); | ||
1876 | editor.appendChild(editLabel); | ||
1877 | |||
1878 | editBox= document.createElement("textarea"); | ||
1879 | editBox.setAttribute("id","editor"); | ||
1880 | editBox.setAttribute("alipielements", "alipi"); | ||
1881 | editBox.setAttribute("style","position:absolute;top:15%;left:51%;min-width:450px;max-width:450px;min-height:370px;max-height:370px;font-size:15;text-align:justify;"); | ||
1882 | editor.appendChild(editBox); | ||
1883 | |||
1884 | |||
1885 | this.activate = function activate() { | ||
1886 | $(function() { | ||
1887 | $( "#editoroverlay" ).dialog({ | ||
1888 | width:1000, | ||
1889 | height:550, | ||
1890 | modal: true, | ||
1891 | buttons: { | ||
1892 | "+": function() { | ||
1893 | if(document.getElementById('editor').style.fontSize == '30px'){ | ||
1894 | // passthrough | ||
1895 | } else { | ||
1896 | document.getElementById('editor').style.fontSize = parseFloat(document.getElementById('editor').style.fontSize) + 1 + 'px'; | ||
1897 | document.getElementById('reference').style.fontSize = parseFloat(document.getElementById('reference').style.fontSize) + 1 + 'px'; | ||
1898 | } | ||
1899 | }, | ||
1900 | "-": function() { | ||
1901 | if(document.getElementById('editor').style.fontSize == '10px'){ | ||
1902 | } else { | ||
1903 | document.getElementById('editor').style.fontSize = parseFloat(document.getElementById('editor').style.fontSize) - 1 + 'px'; | ||
1904 | document.getElementById('reference').style.fontSize = parseFloat(document.getElementById('reference').style.fontSize) - 1 + 'px'; | ||
1905 | } | ||
1906 | }, | ||
1907 | OK: function() { | ||
1908 | textElement = new TextElementPopup(pageEditor, true); | ||
1909 | textElement.textButtonOnClick(); | ||
1910 | $( "#editoroverlay" ).remove(); | ||
1911 | } | ||
1912 | }, | ||
1913 | close: function() { | ||
1914 | document.getElementById("alipiSelectedElement").removeAttribute("id", "alipiSelectedElement"); | ||
1915 | $( "#editoroverlay" ).remove(); | ||
1916 | } | ||
1917 | }); | ||
1918 | }); | ||
1919 | |||
1920 | noteLabel= document.createElement("label"); | ||
1921 | noteLabel.setAttribute("id", "note-label"); | ||
1922 | noteLabel.innerHTML = ' Magnify or Demagnify '; | ||
1923 | noteLabel.setAttribute("style", "color:#000;font-size:15px;"); | ||
1924 | $(noteLabel).insertAfter($(document.getElementsByClassName('ui-button-text')[0].parentNode)); | ||
1925 | |||
1926 | document.getElementsByClassName('ui-button-text')[1].parentNode.style.marginRight = '635px'; | ||
1927 | document.getElementsByClassName('ui-button-text')[2].parentNode.style.marginRight = '25px'; | ||
1928 | document.getElementById("ui-dialog-title-editoroverlay").setAttribute("style","font-size:25px;"); | ||
1929 | |||
1930 | } | ||
1931 | } ; | ||
1932 | |||
1933 | |||
1934 | |||
1935 | // =========================================== Edit Window end ======================================================= | ||
1936 | |||
1937 | // ========================================== Help Window Start ================================================= | ||
1938 | |||
1939 | HelpWindow = function HelpWindow(pageEditor ) { | ||
1940 | |||
1941 | this.createLabels = function createLabels() { | ||
1942 | |||
1943 | help = document.createElement('div'); | ||
1944 | help.setAttribute("id", "helpwindow"); | ||
1945 | help.setAttribute("alipielements", "alipi"); | ||
1946 | help.setAttribute("style", "color:#000;line-height:16px;top:50px;"); | ||
1947 | document.body.appendChild(help); | ||
1948 | |||
1949 | txtLabel = document.createElement("label"); | ||
1950 | txtLabel.setAttribute("id", "txtlab"); | ||
1951 | txtLabel.innerHTML = 'TEXT :-<p style="margin-left:50px";>Editor - It will popup a window and allow you to modify/replace text of select element on editor(right) box.</p><p style="margin-left:100px";>To delete - Empty the editor(right) box and press "OK".</p><p style="margin-left:50px";>See narrations - If the selected element has other narrations then it will list, on click.</p><p style="margin-left:50px";>Audio - It allows you to enter audio URL.</p>'; | ||
1952 | help.appendChild(txtLabel); | ||
1953 | |||
1954 | imgLabel = document.createElement("label"); | ||
1955 | imgLabel.setAttribute("id", "imglab"); | ||
1956 | imgLabel.innerHTML = ' IMAGE:- <p style="margin-left:50px";> Replace - It allows you to enter image URL.</p><p style="margin-left:50px";> See narrations - If the selected element has other image narration then it will show, on click.</p>'; | ||
1957 | help.appendChild(imgLabel); | ||
1958 | |||
1959 | undoLabel = document.createElement("label"); | ||
1960 | undoLabel.setAttribute("id", "undolab"); | ||
1961 | undoLabel.innerHTML = 'UNDO:- Use it when you want to revert back to previous change.<p style="margin-left:50px";> Revert deleted - Press \'Undo\' button twice. </p>'; | ||
1962 | help.appendChild(undoLabel); | ||
1963 | |||
1964 | pubLabel = document.createElement("label"); | ||
1965 | pubLabel.setAttribute("id", "publab"); | ||
1966 | pubLabel.innerHTML = 'PUBLISH:- To publish your crafted changes to database and blog (our/your).<p style="margin-left:50px";>States - To the place you are targetting.</p><p style="margin-left:50px";>Languages - In language you publishing.</p><p style="margin-left:50px";>Style - In what style you crafted?</p><p style="margin-left:50px";> Author - Who is a crafter?</p><p style="margin-left:50px";>Our blog - If you don\'t have blogspot ID then check this to post it to our blog.</p>'; | ||
1967 | help.appendChild(pubLabel); | ||
1968 | |||
1969 | |||
1970 | }; | ||
1971 | |||
1972 | this.activate = function activate() { | ||
1973 | $(function() { | ||
1974 | $( "#helpwindow" ).dialog({ | ||
1975 | width:800, | ||
1976 | height:550, | ||
1977 | modal: true, | ||
1978 | close: function() { | ||
1979 | $("#helpwindow").remove(); | ||
1980 | } | ||
1981 | }); | ||
1982 | }); | ||
1983 | }; | ||
1984 | |||
1985 | } ; | ||
1986 | |||
1987 | |||
1988 | |||
1989 | // ========================================= Help Window end =================================================== | ||
1990 | /* | ||
1991 | * Control for displaying/hiding an action panel that appears below the popup buttons. | ||
1992 | */ | ||
1993 | PopupActionControl = function PopupActionControl(actionSlot ) { | ||
1994 | |||
1995 | this.open = function open(actionPanel) { | ||
1996 | if (actionSlot.firstChild) { | ||
1997 | actionSlot.replaceChild(actionPanel, actionSlot.firstChild); | ||
1998 | } else { | ||
1999 | actionSlot.appendChild(actionPanel); | ||
2000 | } | ||
2001 | actionSlot.style.display = "block"; | ||
2002 | }; | ||
2003 | |||
2004 | this.close = function close() { | ||
2005 | actionSlot.style.display = "none"; | ||
2006 | }; | ||
2007 | } ; | ||
2008 | |||
2009 | /* | ||
2010 | * control for displaying/hiding the popup buttons. | ||
2011 | */ | ||
2012 | PopupControl = function PopupControl(pageEditor, rootElement, showAtCursor) { | ||
2013 | var self = this, selectedElement = null; | ||
2014 | var offsetX = 3, offsetY = 3; | ||
2015 | var popX = 0, popY = 0; | ||
2016 | var currentAction = null; | ||
2017 | |||
2018 | var blurListener = function blurListener(saveChanges) { | ||
2019 | self.close(saveChanges); | ||
2020 | }; | ||
2021 | |||
2022 | this.onOpen = function onOpen(selectedElement) { | ||
2023 | }; | ||
2024 | |||
2025 | this.onClose = function onClose(saveChanges) { | ||
2026 | }; | ||
2027 | |||
2028 | this.openAt = function openAt(atElement, x, y) { | ||
2029 | var dimension = DOM.viewDimension(), popupWidth, popupHeight; | ||
2030 | popX = x; | ||
2031 | selectedElement = atElement; | ||
2032 | var position = DOM.findPosition(atElement); | ||
2033 | popY = position.y + selectedElement.offsetHeight + 15; | ||
2034 | var type = selectedElement.getAttribute('m4pageedittype'); | ||
2035 | if (showAtCursor) { | ||
2036 | popY = y; | ||
2037 | } | ||
2038 | // To calculate the width, the element needs to be shown. So we move it off the screen temporarily. | ||
2039 | rootElement.style.left = '-10000px'; | ||
2040 | rootElement.style.top = '-10000px'; | ||
2041 | rootElement.style.width = 'auto'; | ||
2042 | rootElement.style.display = 'block'; | ||
2043 | var popupSize = DOM.findSize(rootElement); | ||
2044 | popupWidth = DOM.findSize(rootElement).width; | ||
2045 | // FF sometimes needs 1 pixel buffer. IE doesn't like it. | ||
2046 | if (!rootElement.currentStyle) { | ||
2047 | popupWidth = popupWidth + 1; | ||
2048 | } | ||
2049 | |||
2050 | rootElement.style.width = popupWidth + 'px'; | ||
2051 | // If not enough space exist on the right on cursor, launch on the left side instead. | ||
2052 | if ((popX + popupWidth) > dimension[0]) { | ||
2053 | popX = dimension[0] - popupWidth - 3; | ||
2054 | if (popX < 0) { | ||
2055 | popX = 0; | ||
2056 | } | ||
2057 | } | ||
2058 | |||
2059 | rootElement.style.left = popX + 'px'; | ||
2060 | rootElement.style.top = popY + 'px'; | ||
2061 | pageEditor.loseFocus(); | ||
2062 | pageEditor.addFocusListener(blurListener); | ||
2063 | self.onOpen(selectedElement); | ||
2064 | }; | ||
2065 | |||
2066 | // @param saveChanges, save the current changes, default false, optional | ||
2067 | this.close = function close(saveChanges) { | ||
2068 | self.onClose(saveChanges); | ||
2069 | self.hideAction(); | ||
2070 | rootElement.style.left = '0px'; | ||
2071 | rootElement.style.top = '0px'; | ||
2072 | rootElement.style.display = 'none'; | ||
2073 | pageEditor.removeFocusListener(blurListener); | ||
2074 | if (saveChanges) { | ||
2075 | pageEditor.saveAndClose(); | ||
2076 | } else { | ||
2077 | pageEditor.close(); | ||
2078 | } | ||
2079 | selectedElement = null; | ||
2080 | }; | ||
2081 | |||
2082 | this.showAction = function showAction(popupAction) { | ||
2083 | self.hideAction(); | ||
2084 | if (popupAction) { | ||
2085 | currentAction = popupAction; | ||
2086 | currentAction.open(selectedElement); | ||
2087 | } | ||
2088 | }; | ||
2089 | |||
2090 | this.hideAction = function hideAction() { | ||
2091 | if (currentAction) { | ||
2092 | currentAction.close(); | ||
2093 | } | ||
2094 | } | ||
2095 | }; | ||
2096 | |||
2097 | /* | ||
2098 | * Action for editing a hyperlink. | ||
2099 | */ | ||
2100 | |||
2101 | function renAction(pageEditor, actionSlot) { | ||
2102 | var self = this, renInput,renDiv,selectedElement,renActionControl,optionInput,v,x,i,undoButton,element,vxpath,vdata, varray=[],previousData,xpath; | ||
2103 | |||
2104 | renActionControl = new PopupActionControl(actionSlot); | ||
2105 | |||
2106 | this.open = function open(element) { | ||
2107 | |||
2108 | renInput = DOM.BUILDER.SELECT(editTextInputAttributes.addStyle('margin-left: 5px; background: #FFFFFF;').addStyle(leftBorderStyle + rightBorderStyle).values()); | ||
2109 | |||
2110 | undoButton=DOM.BUILDER.INPUT(undoSubmitButton.addStyle('vertical-align: middle; float:left; margin-left: 5px; margin-right: auto;').values()); | ||
2111 | |||
2112 | renDiv = DOM.BUILDER.DIV(popupContainerAttributes.addStyle('overflow: hidden !important; display: none;position: relative; margin-left: auto; margin-right: auto; margin-top: 5px; margin-bottom: 5px; height: auto !important; height: 60px;').values(), renInput,undoButton); | ||
2113 | |||
2114 | |||
2115 | |||
2116 | xpath = DOM.getXPATH(element); | ||
2117 | previousData = element.textContent; | ||
2118 | |||
2119 | var xmlhttp = new XMLHttpRequest(); | ||
2120 | d = window.location.search.split('?')[1]; | ||
2121 | var a =[]; | ||
2122 | for (var i = 0;i<d.split('&').length;i++){ | ||
2123 | a[d.split('&')[i].split('=')[0]] = d.split('&')[i].split('=')[1]; | ||
2124 | } | ||
2125 | var url = a['foruri']; | ||
2126 | var data="url="+encodeURIComponent(url)+"&xpath="+encodeURIComponent(xpath); | ||
2127 | xmlhttp.onreadystatechange = function() | ||
2128 | { | ||
2129 | if(xmlhttp.readyState == 4 && xmlhttp.status== 200) | ||
2130 | { | ||
2131 | if(xmlhttp.responseText=='') | ||
2132 | { | ||
2133 | renDiv.style.display = 'none'; | ||
2134 | alert("Renarrations not available"); | ||
2135 | } | ||
2136 | else { | ||
2137 | for (i=0;i<= varray.length;i++) varray.pop(i); | ||
2138 | for (i=0; i<=renInput.length;i++) renInput.remove(i,null); | ||
2139 | |||
2140 | x=DOM.BUILDER.OPTION("please choose a Re-narration"); | ||
2141 | renInput.add(x,null); | ||
2142 | |||
2143 | renActionControl.open(renDiv); | ||
2144 | renDiv.style.display = 'block'; | ||
2145 | var response=xmlhttp.responseText.substring(3).split('###'); | ||
2146 | for (var j= 0; j< response.length ; j++){ | ||
2147 | d ={} | ||
2148 | chunk = response[j].substring(1).split('&'); | ||
2149 | for (var i= 0; i< chunk.length ; i++){ | ||
2150 | pair =chunk[i].split("::"); | ||
2151 | key = pair[0]; | ||
2152 | value = pair[1]; | ||
2153 | d[key] = value; | ||
2154 | } | ||
2155 | varray.push(d); | ||
2156 | } | ||
2157 | for(i=0;i<varray.length;i++) { | ||
2158 | lang_ = varray[i]['lang']; | ||
2159 | location_ = varray[i]['location']; | ||
2160 | style_ = varray[i]['style']; | ||
2161 | x=DOM.BUILDER.OPTION(lang_+', '+location_+', '+style_); | ||
2162 | renInput.add(x,null); | ||
2163 | } | ||
2164 | renInput.onchange=function(){ | ||
2165 | |||
2166 | if (renInput.selectedIndex -1 < 0) alert("please choose a Re-narration "); | ||
2167 | else { | ||
2168 | DOM.evaluate(varray[renInput.selectedIndex - 1]['xpath'],varray[renInput.selectedIndex - 1]['data']);}; | ||
2169 | renInput.selectedIndex = 0; | ||
2170 | } | ||
2171 | |||
2172 | undoButton.onclick =function(){ | ||
2173 | DOM.evaluate(xpath,previousData); | ||
2174 | }; | ||
2175 | |||
2176 | } | ||
2177 | } | ||
2178 | } | ||
2179 | xmlhttp.open("POST","http://dev.a11y.in/narration",true); | ||
2180 | xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); | ||
2181 | xmlhttp.send(data); | ||
2182 | |||
2183 | |||
2184 | }; | ||
2185 | |||
2186 | |||
2187 | this.close = function close() { | ||
2188 | selectedElement = null; | ||
2189 | }; | ||
2190 | } | ||
2191 | |||
2192 | |||
2193 | //******************************** Shalini - Changed AudioupdatePopupAction from ImageUpdatePopupAction ***************** | ||
2194 | |||
2195 | AudioUpdateByUrl = function AudioUpdateByUrl(pageEditor) { | ||
2196 | // var self = this, popupDiv, audioUrlInput, randomInput, audioUrlForm, selectedElement, targetName,audioElement; | ||
2197 | // var addUrlLabel = DOM.BUILDER.SPAN(normalFontAttributes.addStyle('width: 100%; display: block; float: left; font-size: 10px;position:relative; margin-top: 5px;margin-left: 0px; margin-right: 5px; margin-bottom: 5px; background: transparent; color: #747474; text-shadow: 0 1px 0 #FFFFFF; text-align: left;').values()); | ||
2198 | // addUrlLabel.innerHTML = 'Add URL'; | ||
2199 | |||
2200 | // audioUrlInput = DOM.BUILDER.INPUT(editTextInputAttributes.addStyle('display:block; background: #FFFFFF;').values()); | ||
2201 | // randomInput = DOM.BUILDER.INPUT(editAttributes.put({ name : 'random', type : 'hidden', value : '1' }).values()); | ||
2202 | // audioUrlForm = DOM.BUILDER.FORM(elementAttributes.values(), | ||
2203 | // audioUrlInput, | ||
2204 | // DOM.BUILDER.INPUT(editSubmitAttributes.values())); | ||
2205 | this.display = function display() { | ||
2206 | audioDiv = document.createElement("div"); | ||
2207 | audioDiv.setAttribute("id", "audiodiv"); | ||
2208 | audioDiv.setAttribute("alipielements", "alipi"); | ||
2209 | audioDiv.setAttribute("title", "Enter ogg file link"); | ||
2210 | document.body.appendChild(audioDiv); | ||
2211 | |||
2212 | urlInput = document.createElement("input"); | ||
2213 | urlInput.setAttribute("id", "audiourl"); | ||
2214 | urlInput.setAttribute("alipielements", "alipi"); | ||
2215 | urlInput.setAttribute("type", "text"); | ||
2216 | urlInput.setAttribute("style", "width:300px;"); | ||
2217 | audioDiv.appendChild(urlInput); | ||
2218 | |||
2219 | $(function() { | ||
2220 | $( "#audiodiv" ).dialog({ | ||
2221 | width:350, | ||
2222 | height:150, | ||
2223 | modal: true, | ||
2224 | close: function() { | ||
2225 | $("#audiodiv").remove(); | ||
2226 | }, | ||
2227 | buttons: { | ||
2228 | OK: function() { | ||
2229 | var url = urlInput.value; | ||
2230 | updateAudio(url); | ||
2231 | document.getElementById('alipiSelectedElement').removeAttribute('id', 'alipiSelectedElement'); | ||
2232 | $("#audiodiv").remove(); | ||
2233 | } | ||
2234 | } | ||
2235 | |||
2236 | }); | ||
2237 | }); | ||
2238 | }; | ||
2239 | |||
2240 | |||
2241 | // function updateFormOnSubmit() { | ||
2242 | // var url = urlInput.value; | ||
2243 | // updateAudio(url); | ||
2244 | // return false; | ||
2245 | // }; | ||
2246 | |||
2247 | // audioDiv = DOM.BUILDER.DIV(popupContainerAttributes.addStyle('width: 100%; float:left; position: relative; margin: 0px auto auto 10px; display: block;').values(), addUrlLabel, audioUrlForm); | ||
2248 | |||
2249 | // audioActionControl = new PopupActionControl(actionControl); | ||
2250 | |||
2251 | // this.getActionDiv = function getActionDiv() { | ||
2252 | // return audioDiv; | ||
2253 | // }; | ||
2254 | |||
2255 | // this.open = function open(element) { | ||
2256 | // audioActionControl.open(audioDiv); | ||
2257 | // audioUrlInput.value = ''; | ||
2258 | // selectedElement = element; | ||
2259 | // audioDiv.style.display = 'block'; | ||
2260 | // }; | ||
2261 | |||
2262 | // this.close = function close() { | ||
2263 | // selectedElement = null; | ||
2264 | // audioDiv.style.display = 'none'; | ||
2265 | // }; | ||
2266 | |||
2267 | updateAudio = function updateAudio(src) { | ||
2268 | var command; | ||
2269 | selectedElement = document.getElementById("alipiSelectedElement"); | ||
2270 | // audioElement = urlInput; | ||
2271 | // if (audioElement) { | ||
2272 | // command = { | ||
2273 | // command : 'AUDIO_UPDATE', | ||
2274 | // element : audioElement, | ||
2275 | // elementId : audioElement.getAttribute('m4pageeditid'), | ||
2276 | // data : src, | ||
2277 | // // previousData : originalHref | ||
2278 | // }; | ||
2279 | // } else { | ||
2280 | command = { | ||
2281 | command : 'AUDIO_CREATE', | ||
2282 | element : selectedElement, | ||
2283 | elementType : 'audio/ogg', | ||
2284 | xpath : DOM.getXPATH(selectedElement), | ||
2285 | url : window.location.href, | ||
2286 | elementId : selectedElement.getAttribute('m4pageeditid'), | ||
2287 | data : src, | ||
2288 | previousData : '' | ||
2289 | }; | ||
2290 | // } | ||
2291 | pageEditor.commandApply(command); | ||
2292 | }; | ||
2293 | |||
2294 | }; | ||
2295 | |||
2296 | |||
2297 | //******************************************************************* | ||
2298 | |||
2299 | /** | ||
2300 | * Action for updating an image. | ||
2301 | */ | ||
2302 | function ImageUpdatePopupAction(pageEditor, actionSlot, updateType) { | ||
2303 | var self = this, selectedElement, imagePopupDiv, backgroundUploadPopup, uploadPopupDiv, imageUrlPopup, imageUrlDiv, | ||
2304 | imageSizeSpan, imageFitCheckbox, headerDiv, updateSize, fitElement, imageActionControl; | ||
2305 | |||
2306 | imagePopupDiv = DOM.BUILDER.DIV(popupContainerAttributes.addStyle('position: relative; overflow: hidden !important; display: block; margin-top:3px; height: auto !important; height: 120px; margin-bottom: 10px;').values()); | ||
2307 | headerDiv = DOM.BUILDER.DIV(normalFontAttributes.addStyle('position: relative;').values()); | ||
2308 | |||
2309 | imageActionControl = new PopupActionControl(actionSlot); | ||
2310 | |||
2311 | imageSizeSpan = DOM.BUILDER.SPAN(normalFontAttributes.addStyle('font-size: 10px; position: relative; float: left; margin-top: 2px; margin-left: 10px; background: transparent; color: #747474; text-shadow: 0 1px 0 #FFFFFF;').values()); | ||
2312 | imageSizeSpan.innerHTML = 'Image Size:'; | ||
2313 | imageFitCheckbox = DOM.BUILDER.INPUT(editAttributes.put({ name : 'Fit Image', type : 'checkbox', checked : 'yes' }).addStyle('position:relative; margin-top: 2px; padding: 1px; background: transparent; float:right; vertical-align: bottom; display:block;').values()); | ||
2314 | |||
2315 | var imageLabel = DOM.BUILDER.LABEL(normalFontAttributes.addStyle('font-size: 10px; float:right;position:relative; margin-top:2px; margin-left: 5px; margin-right: 5px;background: transparent; color: #747474; text-shadow: 0 1px 0 #FFFFFF;').values()); | ||
2316 | imageLabel.innerHTML = 'Fit Image'; | ||
2317 | headerDiv.appendChild(imageSizeSpan); | ||
2318 | headerDiv.appendChild(imageLabel); | ||
2319 | headerDiv.appendChild(imageFitCheckbox); | ||
2320 | |||
2321 | var backgroundImageOnLoad = function backgroundImageOnLoad(selectedElement, url, size) { | ||
2322 | var command = { | ||
2323 | command : 'BACKGROUND_IMAGE_UPDATE', | ||
2324 | element : selectedElement, | ||
2325 | elementId : selectedElement.getAttribute('m4pageeditid'), | ||
2326 | data : url, | ||
2327 | previousData : selectedElement.style.backgroundImage | ||
2328 | }; | ||
2329 | pageEditor.commandApply(command); | ||
2330 | }; | ||
2331 | |||
2332 | var sourceImageUpdateOnLoad = function sourceImageUpdateOnLoad(selectedElement, url, size) { | ||
2333 | var image = new M4ImageElement(selectedElement).setRawImageSize(size), command, fittedSize = size; | ||
2334 | if (imageFitCheckbox.checked) { | ||
2335 | fittedSize = image.getFittedSize(); | ||
2336 | } | ||
2337 | command = { | ||
2338 | command : 'IMAGE_SRC_UPDATE', | ||
2339 | element : selectedElement, | ||
2340 | elementType : 'image', | ||
2341 | xpath : DOM.getXPATH(selectedElement), | ||
2342 | url : window.location.href, | ||
2343 | data : new UTIL.StringBuffer().append(fittedSize.width).append('x').append(fittedSize.height).append(',').append(url).toString(), | ||
2344 | previousData : { | ||
2345 | 'src' : selectedElement.src, | ||
2346 | 'size' : { width: selectedElement.width, height: selectedElement.height }, | ||
2347 | 'rawImageSize' : image.getRawImageSize() | ||
2348 | } | ||
2349 | }; | ||
2350 | |||
2351 | updateSize(); | ||
2352 | pageEditor.commandApply(command); | ||
2353 | }; | ||
2354 | var imageOnLoad = backgroundImageOnLoad; | ||
2355 | var uploadButtonText = 'Upload BG Image'; | ||
2356 | |||
2357 | if (updateType == 'IMAGE_SRC_UPDATE') { | ||
2358 | imageOnLoad = sourceImageUpdateOnLoad; | ||
2359 | uploadButtonText = 'Upload Image'; | ||
2360 | imagePopupDiv.appendChild(headerDiv); | ||
2361 | } | ||
2362 | |||
2363 | backgroundUploadPopup = new ImageUpdateByUpload(self, uploadButtonText); | ||
2364 | backgroundUploadPopup.onImageLoad = imageOnLoad; | ||
2365 | uploadPopupDiv = backgroundUploadPopup.getActionDiv(); | ||
2366 | |||
2367 | imageUrlPopup = new ImageUpdateByUrl(pageEditor, self); | ||
2368 | imageUrlPopup.onImageLoad = imageOnLoad; | ||
2369 | imageUrlDiv = imageUrlPopup.getActionDiv(); | ||
2370 | |||
2371 | |||
2372 | imagePopupDiv.appendChild(uploadPopupDiv); | ||
2373 | imagePopupDiv.appendChild(imageUrlDiv); | ||
2374 | |||
2375 | this.open = function open(element) { | ||
2376 | imageActionControl.open(imagePopupDiv); | ||
2377 | selectedElement = element; | ||
2378 | headerDiv.style.width = imagePopupDiv.offsetWidth; | ||
2379 | backgroundUploadPopup.open(selectedElement); | ||
2380 | imageUrlPopup.open(selectedElement); | ||
2381 | updateSize(); | ||
2382 | }; | ||
2383 | |||
2384 | this.close = function close() { | ||
2385 | imageActionControl.close(); | ||
2386 | backgroundUploadPopup.close(); | ||
2387 | imageUrlPopup.close(); | ||
2388 | selectedElement = null; | ||
2389 | }; | ||
2390 | |||
2391 | this.onComplete = function onComplete() { | ||
2392 | }; | ||
2393 | |||
2394 | this.onError = function onError() { | ||
2395 | }; | ||
2396 | |||
2397 | this.actionComplete = function actionComplete() { | ||
2398 | self.onComplete(); | ||
2399 | }; | ||
2400 | |||
2401 | this.handleError = function handleError() { | ||
2402 | self.onError(); | ||
2403 | }; | ||
2404 | |||
2405 | updateSize = function updateSize() { | ||
2406 | if (selectedElement) { | ||
2407 | var size = DOM.findSize(selectedElement); | ||
2408 | imageSizeSpan.innerHTML = new UTIL.StringBuffer().append('Image Size ').append(size.width).append('x').append(size.height).append(' pixels').toString(); | ||
2409 | } | ||
2410 | }; | ||
2411 | |||
2412 | function ImageUpdateByUpload(actionControl, uploadButtonText) { | ||
2413 | var self = this, uploadForm, uploadingMessage, uploadIframe, fileInput, pageSlugInput, | ||
2414 | uploadSlugInput, targetName, randomInput, selectedElement = null, sizingImage, showLoading, uploadButton, | ||
2415 | uploadPopupDiv; | ||
2416 | |||
2417 | uploadPopupDiv = DOM.BUILDER.DIV(popupContainerAttributes.addStyle('width: 110px; overflow: none; display: block; position: relative; margin: 10px auto auto 10px; float:left;').values()); | ||
2418 | uploadingMessage = DOM.BUILDER.SPAN(editTitleAttributes.addStyle("display:none").values(), "Loading..."); | ||
2419 | fileInput = DOM.BUILDER.INPUT(editTextInputAttributes.put({ name : 'file', type : 'file', size : '20' }).addStyle('width: 110px; cursor: pointer; height: 30px;opacity: 0; -ms-filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0); filter:alpha(opacity=0); position: relative; float: none;').values()); | ||
2420 | |||
2421 | pageSlugInput = DOM.BUILDER.INPUT(editAttributes.put({ name : 'pageSlug', type : 'hidden', value : pageSlug }).values()); | ||
2422 | uploadSlugInput = DOM.BUILDER.INPUT(editAttributes.put({ name : 'uploadSlug', type : 'hidden', value : uploadSlug }).values()); | ||
2423 | randomInput = DOM.BUILDER.INPUT(editAttributes.put({ name : 'random', type : 'hidden', value : '1' }).values()); | ||
2424 | |||
2425 | targetName = 'm4-bolt-upload-target-' + Math.round(Math.random() * 10000000); | ||
2426 | |||
2427 | uploadButton = DOM.BUILDER.BUTTON(redButtonAttributes.addStyle('cursor: pointer;width: 110px; height: 25px; position: absolute; float:left; text-align: center;').addStyle(leftBorderStyle + rightBorderStyle).values(), uploadButtonText); | ||
2428 | |||
2429 | uploadButton.onclick = function uploadButtonOnClick(){ | ||
2430 | return false; | ||
2431 | }; | ||
2432 | |||
2433 | uploadForm = DOM.BUILDER.FORM(elementAttributes.put({ target : targetName, encType : 'multipart/form-data', method : 'post', action : '/app/page-edit/upload' }).addStyle('display:block; margin: auto;').values()); | ||
2434 | |||
2435 | showLoading = function showLoading() { | ||
2436 | uploadForm.style.display = "none"; | ||
2437 | uploadingMessage.style.width = '110 px'; | ||
2438 | uploadingMessage.style.display = "block"; | ||
2439 | }; | ||
2440 | |||
2441 | uploadForm.onsubmit = function uploadFormOnSubmit() { | ||
2442 | showLoading(); | ||
2443 | }; | ||
2444 | |||
2445 | fileInput.onchange = function fileInputOnChange() { | ||
2446 | showLoading(); | ||
2447 | uploadForm.submit(); | ||
2448 | }; | ||
2449 | |||
2450 | uploadIframe = DOM.BUILDER.IFRAME( { name : targetName, src : 'https://bo.lt/app/asset/empty.html?p=622fd096a39f5c36a6e06e41a9963dafaad61079', style : 'display: none' }); | ||
2451 | UTIL.addEvent(uploadIframe, 'load', function uploadIframeOnLoad() { | ||
2452 | var iframeBody; | ||
2453 | if (uploadIframe.contentDocument) { | ||
2454 | iframeBody = uploadIframe.contentDocument.body; | ||
2455 | } else if (uploadIframe.contentWindow) { | ||
2456 | iframeBody = uploadIframe.contentWindow.document.body; | ||
2457 | } | ||
2458 | var upload, resultText = DOM.textContent(iframeBody); | ||
2459 | |||
2460 | if (!/^\s*\{.*\}\s*/.test(resultText) || selectedElement == null) { | ||
2461 | return; | ||
2462 | } | ||
2463 | |||
2464 | try { | ||
2465 | upload = eval("(" + resultText + ")"); | ||
2466 | } catch (error) { | ||
2467 | console.error("Unable to interpret the upload image response", error); | ||
2468 | actionControl.handleError(); | ||
2469 | return; | ||
2470 | } | ||
2471 | |||
2472 | if (!upload.success) { | ||
2473 | console.error("Unable to upload the specified file:", upload.error); | ||
2474 | actionControl.handleError(); | ||
2475 | return; | ||
2476 | } | ||
2477 | |||
2478 | sizingImage = new Image(); | ||
2479 | sizingImage.onload = function sizingImageOnLoad() { | ||
2480 | self.onImageLoad(selectedElement, upload.url, { width: sizingImage.width, height: sizingImage.height }); | ||
2481 | actionControl.actionComplete(); | ||
2482 | }; | ||
2483 | sizingImage.src = upload.url; | ||
2484 | randomInput.value = randomInput.value + 1; | ||
2485 | }); | ||
2486 | |||
2487 | uploadPopupDiv.appendChild(uploadForm); | ||
2488 | uploadPopupDiv.appendChild(uploadingMessage); | ||
2489 | uploadPopupDiv.appendChild(uploadIframe); | ||
2490 | |||
2491 | this.onImageLoad = function onImageLoad(selectedElement, url, size) { | ||
2492 | }; | ||
2493 | |||
2494 | this.getActionDiv = function getActionDiv() { | ||
2495 | return uploadPopupDiv; | ||
2496 | }; | ||
2497 | |||
2498 | this.open = function open(element) { | ||
2499 | selectedElement = element; | ||
2500 | uploadForm.style.display = "block"; | ||
2501 | uploadingMessage.style.display = "none"; | ||
2502 | fileInput.value = ''; | ||
2503 | fileInput.select(); | ||
2504 | }; | ||
2505 | |||
2506 | this.close = function close() { | ||
2507 | selectedElement = null; | ||
2508 | uploadingMessage.style.display = "none"; | ||
2509 | uploadForm.style.display = "block"; | ||
2510 | }; | ||
2511 | } | ||
2512 | |||
2513 | function ImageUpdateByUrl(pageEditor, actionControl) { | ||
2514 | var self = this, popupDiv, imageUrlInput, randomInput, imageUrlForm, selectedElement, targetName; | ||
2515 | |||
2516 | var addUrlLabel = DOM.BUILDER.SPAN(normalFontAttributes.addStyle('width: 100%; display: block; float: left; font-size: 10px;position:relative; margin-top: 5px;margin-left: 0px; margin-right: 5px; margin-bottom: 5px; background: transparent; color: #747474; text-shadow: 0 1px 0 #FFFFFF; text-align: left;').values()); | ||
2517 | addUrlLabel.innerHTML = 'Add URL'; | ||
2518 | |||
2519 | imageUrlInput = DOM.BUILDER.INPUT(editTextInputAttributes.addStyle('display:block; background: #FFFFFF;').values()); | ||
2520 | randomInput = DOM.BUILDER.INPUT(editAttributes.put({ name : 'random', type : 'hidden', value : '1' }).values()); | ||
2521 | |||
2522 | imageUrlForm = DOM.BUILDER.FORM(elementAttributes.put({ target : targetName, enctype : 'multipart/form-data', method : 'post', action : '/app/page-edit/upload' }).values(), | ||
2523 | imageUrlInput, | ||
2524 | DOM.BUILDER.INPUT(editAttributes.put({ name : 'pageSlug', type : 'hidden', value : pageSlug }).values()), | ||
2525 | randomInput, | ||
2526 | DOM.BUILDER.INPUT(editSubmitAttributes.values())); | ||
2527 | |||
2528 | imageUrlForm.onsubmit = function updateFormOnSubmit() { | ||
2529 | var url = imageUrlInput.value; | ||
2530 | if (url != '') { | ||
2531 | randomInput.value = randomInput.value + 1; | ||
2532 | var sizingImage = new Image(); | ||
2533 | sizingImage.onload = function sizingImageOnLoad() { | ||
2534 | self.onImageLoad(selectedElement, url, { width: sizingImage.width, height: sizingImage.height }); | ||
2535 | actionControl.actionComplete(); | ||
2536 | }; | ||
2537 | sizingImage.src = url; | ||
2538 | } | ||
2539 | return false; | ||
2540 | }; | ||
2541 | |||
2542 | popupDiv = DOM.BUILDER.DIV(popupContainerAttributes.addStyle('width: 100%; float:left; position: relative; margin: 0px auto auto 10px; display: block;').values(), | ||
2543 | addUrlLabel, imageUrlForm); | ||
2544 | |||
2545 | this.getActionDiv = function getActionDiv() { | ||
2546 | return popupDiv; | ||
2547 | }; | ||
2548 | |||
2549 | this.open = function open(element) { | ||
2550 | imageUrlInput.value = ''; | ||
2551 | selectedElement = element; | ||
2552 | popupDiv.style.display = 'block'; | ||
2553 | }; | ||
2554 | |||
2555 | this.close = function close() { | ||
2556 | selectedElement = null; | ||
2557 | popupDiv.style.display = 'none'; | ||
2558 | }; | ||
2559 | |||
2560 | this.onImageLoad = function onImageLoad(element, url, size) { | ||
2561 | }; | ||
2562 | } | ||
2563 | |||
2564 | } | ||
2565 | |||
2566 | |||
2567 | |||
2568 | /** | ||
2569 | * Popup for all editable elements except text. | ||
2570 | */ | ||
2571 | function EditableElementPopup(pageEditor, imageElement) { | ||
2572 | var self = this, popupControl, deleteElement, imagePopupDiv, deleteButton,renButton,selectedElement, | ||
2573 | linkUpdateAction, linkButton, closeButton, imageButton, backgroundButton, redArrow,imageUpdateAction, | ||
2574 | imageUpdateDiv, uploadMode, backgroundButtonText, imageButtonText, buttonPanel, upArrow, actionSlot,subMenuAction,renUpdateAction; | ||
2575 | |||
2576 | this.popupAt = function popupAt(element, popX, popY) { | ||
2577 | popupControl.openAt(element, popX, popY); | ||
2578 | }; | ||
2579 | |||
2580 | this.popdown = function popdown() { | ||
2581 | popupControl.close(); | ||
2582 | }; | ||
2583 | |||
2584 | if (imageElement) { | ||
2585 | uploadMode = 'IMAGE_SRC_UPDATE'; | ||
2586 | backgroundButtonText = "Replace"; | ||
2587 | imageButtonText = 'Image'; | ||
2588 | } | ||
2589 | |||
2590 | buttonPanel = DOM.BUILDER.DIV(buttonPanelAttributes.values()); | ||
2591 | upArrow = DOM.BUILDER.SPAN(greyArrowAttributes.values()); | ||
2592 | actionSlot = DOM.BUILDER.DIV(actionPanelAttributes.values()); | ||
2593 | |||
2594 | imagePopupDiv = DOM.BUILDER.DIV(popupContainerAttributes.addStyle('margin-bottom: 10px;').values()); | ||
2595 | |||
2596 | popupControl = new PopupControl(pageEditor, imagePopupDiv, true); | ||
2597 | popupControl.onOpen = function onOpen(element) { | ||
2598 | selectedElement = element; | ||
2599 | var actionSlotWidth = DOM.findSize(imagePopupDiv).width - DOM.findSize(redArrow).width; | ||
2600 | var spanElement = imageButton.getElementsByTagName('span')[0]; | ||
2601 | if (DOM.isElementOfType(selectedElement, 'body')) { | ||
2602 | actionSlotWidth = actionSlotWidth - DOM.findSize(deleteButton).width; | ||
2603 | deleteButton.style.display = 'none'; | ||
2604 | spanElement.innerHTML = 'Body'; | ||
2605 | } else { | ||
2606 | spanElement.innerHTML = imageButtonText; | ||
2607 | deleteButton.style.display = 'block'; | ||
2608 | } | ||
2609 | actionSlot.style.width = actionSlotWidth + 'px'; | ||
2610 | }; | ||
2611 | |||
2612 | popupControl.onClose = function onClose() { | ||
2613 | upArrow.style.display = 'none'; | ||
2614 | selectedElement = null; | ||
2615 | }; | ||
2616 | |||
2617 | closeButton = DOM.BUILDER.BUTTON(closeButtonAttributes.values()); | ||
2618 | closeButton.onclick = function closeButtonOnClick() { | ||
2619 | popupControl.close(); | ||
2620 | upArrow.style.display = 'none'; | ||
2621 | return false; | ||
2622 | }; | ||
2623 | |||
2624 | |||
2625 | imageUpdateAction = new ImageUpdatePopupAction(pageEditor, actionSlot, uploadMode); | ||
2626 | imageUpdateAction.onComplete = function imageUpdateActionOnComplete() { | ||
2627 | self.popdown(); | ||
2628 | }; | ||
2629 | |||
2630 | var backgroundImage = 'http://dev.a11y.in/alipi/images/replace_image.png'; | ||
2631 | backgroundButton = createActionButton(backgroundImage, backgroundButtonText, 'border-right: none;' + leftBorderStyle); | ||
2632 | backgroundButton.onclick = function backgroundButtonOnClick() { | ||
2633 | popupControl.showAction(imageUpdateAction); | ||
2634 | displayUpArrowUnderButton(backgroundButton, upArrow); | ||
2635 | return false; | ||
2636 | }; | ||
2637 | |||
2638 | renUpdateAction = new renAction(pageEditor, actionSlot); | ||
2639 | renUpdateAction.onComplete = function renUpdateActionOnComplete() { | ||
2640 | self.popdown(true); | ||
2641 | }; | ||
2642 | |||
2643 | |||
2644 | var renImage = 'http://dev.a11y.in/alipi/images/renarration.png'; | ||
2645 | renButton = createActionButton(renImage, 'See (other) narrations', 'border-right: none;'); | ||
2646 | renButton.onclick = function renButtonOnClick() { | ||
2647 | popupControl.showAction(renUpdateAction); | ||
2648 | return false; | ||
2649 | }; | ||
2650 | |||
2651 | buttonPanel.appendChild(backgroundButton); | ||
2652 | buttonPanel.appendChild(renButton); | ||
2653 | imagePopupDiv.appendChild(closeButton); | ||
2654 | imagePopupDiv.appendChild(buttonPanel); | ||
2655 | imagePopupDiv.appendChild(actionSlot); | ||
2656 | |||
2657 | document.body.appendChild(imagePopupDiv); | ||
2658 | |||
2659 | deleteElement = function deleteElement() { | ||
2660 | var command = { | ||
2661 | command : 'DELETE', | ||
2662 | element : selectedElement, | ||
2663 | url : '', | ||
2664 | xpath : '', | ||
2665 | elementType : 'text', | ||
2666 | data : '', | ||
2667 | previousData : '' | ||
2668 | }; | ||
2669 | pageEditor.commandApply(command); | ||
2670 | popupControl.close(); | ||
2671 | }; | ||
2672 | } | ||
2673 | |||
2674 | /** | ||
2675 | * Popup for text edit. | ||
2676 | */ | ||
2677 | function TextElementPopup(pageEditor) { | ||
2678 | var self = this, updateText, deleteElement, textPopupDiv, selectedElement, originalTextContent, deleteButton, | ||
2679 | imageUpdateAction, popupControl, linkUpdateAction, linkButton, closeButton, textButton, doneButton, | ||
2680 | imageUpdateDiv, backgroundButton, redArrow, buttonPanel, upArrow, actionSlot,renButton, variablePassing; | ||
2681 | |||
2682 | this.popupAt = function popupAt(element, popX, popY) { | ||
2683 | popupControl.openAt(element, popX, popY); | ||
2684 | }; | ||
2685 | |||
2686 | this.popdown = function popdown(saveChanges) { | ||
2687 | popupControl.close(saveChanges); | ||
2688 | }; | ||
2689 | |||
2690 | buttonPanel = DOM.BUILDER.DIV(buttonPanelAttributes.values()); | ||
2691 | upArrow = DOM.BUILDER.SPAN(greyArrowAttributes.values()); | ||
2692 | actionSlot = DOM.BUILDER.DIV(actionPanelAttributes.values()); | ||
2693 | redArrow = DOM.BUILDER.SPAN(redArrowAttributes.values()); | ||
2694 | textPopupDiv = DOM.BUILDER.DIV(popupContainerAttributes.values()); | ||
2695 | |||
2696 | var eatKeyboardEvents = function eatKeyboardEvents(event) { | ||
2697 | event.stopPropagation(); | ||
2698 | }; | ||
2699 | var handleKeyDown = function handleKeyDown(event) { | ||
2700 | switch (event.keyCode) { | ||
2701 | case 13: | ||
2702 | // Enter key | ||
2703 | self.popdown(true); | ||
2704 | event.stopPropagation(); | ||
2705 | event.preventDefault(); | ||
2706 | |||
2707 | return false; | ||
2708 | default: | ||
2709 | eatKeyboardEvents(event); | ||
2710 | } | ||
2711 | }; | ||
2712 | |||
2713 | popupControl = new PopupControl(pageEditor, textPopupDiv, false); | ||
2714 | popupControl.onOpen = function onOpen(element) { | ||
2715 | selectedElement = element; | ||
2716 | originalTextContent = DOM.textContent(selectedElement); | ||
2717 | // actionSlot.style.marginLeft = (textButton.offsetWidth) + 'px'; | ||
2718 | UTIL.addEvent(selectedElement, 'keydown', handleKeyDown); | ||
2719 | UTIL.addEvent(selectedElement, 'keyup', eatKeyboardEvents); | ||
2720 | UTIL.addEvent(selectedElement, 'keypress', eatKeyboardEvents); | ||
2721 | if (DOM.isIEBrowser() && DOM.isQuirksMode()) { | ||
2722 | actionSlot.style.marginTop = '-8px'; | ||
2723 | actionSlot.style.paddingTop = '0px'; | ||
2724 | } | ||
2725 | selectedElement.setAttribute('contentEditable', false); | ||
2726 | }; | ||
2727 | |||
2728 | popupControl.onClose = function onClose(saveChanges) { | ||
2729 | upArrow.style.display = 'none'; | ||
2730 | if (saveChanges && (DOM.textContent(selectedElement) != originalTextContent)) // || (saveChanges && hasAudio==true) | ||
2731 | { | ||
2732 | updateText(); | ||
2733 | } else { | ||
2734 | DOM.textContent(selectedElement, originalTextContent); | ||
2735 | } | ||
2736 | selectedElement = null; | ||
2737 | originalTextContent = null; | ||
2738 | }; | ||
2739 | |||
2740 | closeButton = DOM.BUILDER.BUTTON(closeButtonAttributes.values()); | ||
2741 | closeButton.onclick = function closeButtonOnClick() { | ||
2742 | DOM.textContent(selectedElement, originalTextContent); | ||
2743 | self.popdown(false); | ||
2744 | upArrow.style.display = 'none'; | ||
2745 | return false; | ||
2746 | }; | ||
2747 | |||
2748 | |||
2749 | |||
2750 | var doneImage = 'http://y.a11y.in/alipi/images/done.png'; | ||
2751 | doneButton = createActionButton(doneImage, 'Edit ', 'border-right: none;' + leftBorderStyle); | ||
2752 | doneButton.onclick = function doneButtonOnClick(elements) { | ||
2753 | editWindow = new EditWindow(pageEditor); | ||
2754 | document.getElementById('reference').value = selectedElement.textContent; | ||
2755 | document.getElementById('editor').value = selectedElement.textContent; | ||
2756 | selectedElement.setAttribute('id', 'alipiSelectedElement'); | ||
2757 | document.getElementById("editor").removeAttribute("readonly"); | ||
2758 | // DOM.textContent(selectedElement, originalTextContent); | ||
2759 | editWindow.activate(); | ||
2760 | self.popdown(false); | ||
2761 | // upArrow.style.display = 'none'; | ||
2762 | return false; | ||
2763 | |||
2764 | }; | ||
2765 | |||
2766 | |||
2767 | this.textButtonOnClick = function textButtonOnClick() { | ||
2768 | self.popdown(true); | ||
2769 | document.getElementById('alipiSelectedElement').textContent = document.getElementById('editor').value; | ||
2770 | document.getElementById('alipiSelectedElement').removeAttribute('id', 'alipiSelectedElement'); | ||
2771 | return false; | ||
2772 | }; | ||
2773 | |||
2774 | |||
2775 | var renImage = 'http://dev.a11y.in/alipi/images/renarration.png'; | ||
2776 | renButton = createActionButton(renImage, 'See (other) narrations', 'border-right: none;'); | ||
2777 | renButton.onclick = function renButtonOnClick() { | ||
2778 | popupControl.showAction(renUpdateAction); | ||
2779 | return false; | ||
2780 | }; | ||
2781 | |||
2782 | renUpdateAction = new renAction(pageEditor, actionSlot); | ||
2783 | renUpdateAction.onComplete = function renUpdateActionOnComplete() { | ||
2784 | self.popdown(true); | ||
2785 | }; | ||
2786 | |||
2787 | audioUpdateAction = new AudioUpdateByUrl(pageEditor, actionSlot); | ||
2788 | audioUpdateAction.onComplete = function audioUpdateActionOnComplete() { | ||
2789 | self.popdown(false); | ||
2790 | }; | ||
2791 | |||
2792 | var audioImage = 'http://dev.a11y.in/alipi/images/audio.png'; | ||
2793 | audioButton = createActionButton(audioImage,'Audio','border-right:none;'); | ||
2794 | audioButton.onclick = function audioButtonOnClick() { | ||
2795 | selectedElement.setAttribute('id', 'alipiSelectedElement'); | ||
2796 | audioUpdateAction = new AudioUpdateByUrl(pageEditor); | ||
2797 | audioUpdateAction.display(); | ||
2798 | self.popdown(true); | ||
2799 | return false; | ||
2800 | }; | ||
2801 | |||
2802 | |||
2803 | imageUpdateAction = new ImageUpdatePopupAction(pageEditor, actionSlot, 'BACKGROUND_IMAGE_UPDATE'); | ||
2804 | imageUpdateAction.onComplete = function imageUpdateActionOnComplete() { | ||
2805 | self.popdown(true); | ||
2806 | }; | ||
2807 | |||
2808 | var backgroundImage = 'http://dev.a11y.in/alipi/images/replace_image.png'; | ||
2809 | backgroundButton = createActionButton(backgroundImage, 'BG Image', 'border-right: none;'); | ||
2810 | backgroundButton.onclick = function backgroundButtonOnClick() { | ||
2811 | popupControl.showAction(imageUpdateAction); | ||
2812 | imageUpdateAction.open(selectedElement.parentNode); | ||
2813 | displayUpArrowUnderButton(backgroundButton, upArrow); | ||
2814 | return false; | ||
2815 | }; | ||
2816 | |||
2817 | buttonPanel.appendChild(doneButton); | ||
2818 | buttonPanel.appendChild(renButton); | ||
2819 | buttonPanel.appendChild(audioButton); | ||
2820 | textPopupDiv.appendChild(closeButton); | ||
2821 | textPopupDiv.appendChild(buttonPanel); | ||
2822 | textPopupDiv.appendChild(actionSlot); | ||
2823 | document.body.appendChild(textPopupDiv); | ||
2824 | |||
2825 | updateText = function updateText() { | ||
2826 | var command = { | ||
2827 | command : 'TEXT_UPDATE', | ||
2828 | element : selectedElement, | ||
2829 | url : window.location.href, | ||
2830 | xpath : DOM.getXPATH(selectedElement), | ||
2831 | elementType : 'text', | ||
2832 | data : DOM.textContent(selectedElement), | ||
2833 | previousData : originalTextContent | ||
2834 | }; | ||
2835 | pageEditor.commandApply(command); | ||
2836 | if (DOM.textContent(selectedElement).length == 0) { | ||
2837 | deleteElement(); | ||
2838 | } | ||
2839 | }; | ||
2840 | |||
2841 | deleteElement = function deleteElement() { | ||
2842 | var command = { | ||
2843 | command : 'DELETE', | ||
2844 | element : selectedElement, | ||
2845 | url : '', | ||
2846 | elementType : 'text', | ||
2847 | data : '', | ||
2848 | xpath : '', | ||
2849 | data : '', | ||
2850 | previousData : '' | ||
2851 | }; | ||
2852 | pageEditor.commandApply(command); | ||
2853 | }; | ||
2854 | } | ||
2855 | |||
2856 | |||
2857 | |||
2858 | /** | ||
2859 | * Overlay bar which can function in either visual editor or html editor mode. | ||
2860 | */ | ||
2861 | function OverlayBar(pageEditor, isVisualEditor) { | ||
2862 | var self = this, overlayDiv, firstRowDiv, firstRowStyleAttributes, messageDiv, publishButton, undoButton,fillUpButton; | ||
2863 | var moveDiv, editModeChangeOverlayDiv, buttonDiv, editModeChangeButtonDiv, editModeChangeSaveButton, editModeChangeDiscardButton; | ||
2864 | var redButtonStyleAttributes, fillUpButtonStyleAttributes, firstRowDivOffset, calculateScrollPositionY, wrapperDiv,showKeepOriginalOverlay, publishOptions = new PublishOptions(); | ||
2865 | |||
2866 | |||
2867 | overlayDiv = document.createElement("div"); | ||
2868 | overlayDiv.setAttribute("id", "overlay-div"); | ||
2869 | overlayDiv.setAttribute("alipielements", "alipi"); | ||
2870 | overlayDiv.setAttribute("style", "overflow-x:visible; position:fixed; z-index:2147483645; left:0; top:0; width:100%; height:30px; background-color:rgba(0, 0, 0, 0.5);"); | ||
2871 | document.body.appendChild(overlayDiv); | ||
2872 | |||
2873 | |||
2874 | image = document.createElement("img"); | ||
2875 | image.setAttribute("id", "close-image"); | ||
2876 | image.setAttribute("alipielements", "alipi"); | ||
2877 | image.setAttribute("src", "http://dev.a11y.in/alipi/images/close_button.png"); | ||
2878 | image.setAttribute("style", "position:relative;width:25px;height:28px;"); | ||
2879 | overlayDiv.appendChild(image); | ||
2880 | image.onclick=function(){ | ||
2881 | answer = confirm("Do you really want to exit the editor?") | ||
2882 | if (answer !=0) | ||
2883 | { | ||
2884 | window.location.reload(); | ||
2885 | } | ||
2886 | } | ||
2887 | |||
2888 | |||
2889 | messageDiv = document.createElement("div"); | ||
2890 | messageDiv.setAttribute("id", "message-div"); | ||
2891 | messageDiv.setAttribute("alipielements", "alipi"); | ||
2892 | messageDiv.setAttribute("style", "position:relative;left:150px;bottom:26px;font-size:23px;font-weight:bold;color:#ffe;"); | ||
2893 | overlayDiv.appendChild(messageDiv); | ||
2894 | |||
2895 | helpLink = document.createElement("input"); | ||
2896 | helpLink.setAttribute("id", "help"); | ||
2897 | helpLink.setAttribute("alipielements", "alipi"); | ||
2898 | helpLink.setAttribute("type", "submit"); | ||
2899 | helpLink.setAttribute("Value", "Help"); | ||
2900 | helpLink.setAttribute("style", "position:relative;top:-55px;left:750px;font-size:18px;font-weight:bold;width:100px;height:30px;"); | ||
2901 | overlayDiv.appendChild(helpLink); | ||
2902 | helpLink.onclick = function helpLinkOnClick() { | ||
2903 | helpWindow = new HelpWindow(pageEditor); | ||
2904 | helpWindow.createLabels(); | ||
2905 | helpWindow.activate(); | ||
2906 | |||
2907 | }; | ||
2908 | |||
2909 | |||
2910 | undoButton = document.createElement("input"); | ||
2911 | undoButton.setAttribute("id", "undo"); | ||
2912 | undoButton.setAttribute("alipielements", "alipi"); | ||
2913 | undoButton.setAttribute("type", "submit"); | ||
2914 | undoButton.setAttribute("Value", "Undo"); | ||
2915 | undoButton.setAttribute("style", "position:relative;top:-55px;left:825px;font-size:18px;font-weight:bold;width:100px;height:30px;"); | ||
2916 | overlayDiv.appendChild(undoButton); | ||
2917 | undoButton.onclick = function undoButtonOnClick() { | ||
2918 | pageEditor.commandUndo(); | ||
2919 | return false; | ||
2920 | }; | ||
2921 | |||
2922 | |||
2923 | publishButton = document.createElement("input"); | ||
2924 | publishButton.setAttribute("id", "publish"); | ||
2925 | publishButton.setAttribute("alipielements", "alipi"); | ||
2926 | publishButton.setAttribute("type", "submit"); | ||
2927 | publishButton.setAttribute("Value", "Publish"); | ||
2928 | publishButton.setAttribute("style", "position:relative;top:-55px;left:900px;font-size:18px;font-weight:bold;width:100px;height:30px;"); | ||
2929 | overlayDiv.appendChild(publishButton); | ||
2930 | var dialog = 0; | ||
2931 | publishButton.onclick = function publishButtonOnClick() { | ||
2932 | if (pageEditor.hasChangesPending() /* && (pageEditor.formUncomplete() ==false) */ ) { | ||
2933 | targetWindow = new TargetWindow(pageEditor); | ||
2934 | if (dialog == 0) { | ||
2935 | targetWindow.createDialogBox(); | ||
2936 | dialog = 1; | ||
2937 | } | ||
2938 | targetWindow.activate(); | ||
2939 | } else { | ||
2940 | pageEditor.showMessage("Nothing to post"); | ||
2941 | } | ||
2942 | }; | ||
2943 | |||
2944 | |||
2945 | this.blogpost = function blogpost() { | ||
2946 | if (locName.value == "" || langName.value == "" || styleSelect.value == "" || author.value == "" || (ourcheck.checked == false && yourcheck.checked == false)) { | ||
2947 | alert("Please give all the details, it will be used further"); | ||
2948 | } else { | ||
2949 | pageEditor.commandPublish(); | ||
2950 | pageEditor.showMessage("... Please wait, your blog is being posted"); | ||
2951 | $('#targetoverlay').remove(); | ||
2952 | } | ||
2953 | }; | ||
2954 | // End of okButton function | ||
2955 | |||
2956 | this.show = function show(activate) { | ||
2957 | // overlayDiv.style.display = 'block'; | ||
2958 | var disabled = true; | ||
2959 | var opacity = '0.4'; | ||
2960 | if (activate) { | ||
2961 | disabled = false; | ||
2962 | opacity = '1.0'; | ||
2963 | } | ||
2964 | |||
2965 | undoButton.disabled = false; | ||
2966 | publishButton.disabled = false; | ||
2967 | |||
2968 | undoButton.style.opacity = "1"; | ||
2969 | publishButton.style.opacity = "1"; | ||
2970 | publishOptions.hide(); | ||
2971 | }; | ||
2972 | |||
2973 | this.message = function message(value) { | ||
2974 | messageDiv.innerHTML = value; | ||
2975 | }; | ||
2976 | |||
2977 | |||
2978 | function PublishOptions() { | ||
2979 | var self = this, wrapperDiv, keepOriginalCheckbox, activateOptionsTimerId, cancelTimer, activatePublishOptions; | ||
2980 | var checkboxId = 'm4PublishOptionsCheckbox-' + new Date().getTime(); | ||
2981 | keepOriginalCheckbox = DOM.BUILDER.INPUT( | ||
2982 | editAttributes.put({ | ||
2983 | name : 'Publish Options', | ||
2984 | type : 'checkbox', id: checkboxId}).addStyle( | ||
2985 | 'font-family: Helvetica Neue, Helvetica, Ariel, Sans-serif; font-size: 10px; width: 14px; height: 14px; margin: 0; padding: 0; position: relative; background: transparent;').values() | ||
2986 | ); | ||
2987 | keepOriginalCheckbox.onclick = function() { | ||
2988 | keepOriginal = keepOriginalCheckbox.checked; | ||
2989 | }; | ||
2990 | var backgroundImage = 'url(http://dev.a11y.in/alipi/images/container_save_new_page.png) no-repeat scroll 0 0 transparent'; | ||
2991 | var position = 'fixed'; | ||
2992 | |||
2993 | wrapperDiv = DOM.BUILDER.DIV(editAttributes.addStyle('font-family: Helvetica Neue, Helvetica, Ariel, Sans-serif; font-size: 10px; display: table; vertical-align: middle; z-index: 2147483647; margin: 0; width: 134px; height: 33px; line-height: 33px; position: '+ position+ '; right: 10px; background:'+ backgroundImage + ' ; display:none;').values(), DOM.BUILDER.SPAN(editAttributes.addStyle(('font-family: Helvetica Neue, Helvetica, Ariel, Sans-serif; font-size: 10px; display: table-cell; vertical-align: middle; height: 14px; hasLayout=true;')).values(), DOM.BUILDER.SPAN(editAttributes.addStyle('font-family: Helvetica Neue, Helvetica, Ariel, Sans-serif; font-size: 10px; display: inline; vertical-align: middle; height: 10px; width: 14px; padding: 0; margin: 1px 0 0 13px;').values(), keepOriginalCheckbox), DOM.BUILDER.LABEL(normalFontAttributes.put({'for' : checkboxId}).addStyle(('font-family: Helvetica Neue, Helvetica, Ariel, Sans-serif; display: inline; font-size: 10px; background: transparent; color: #E9E9E9; padding: 0 0 0 5px;')).values(),'Save as new page.'))); | ||
2994 | |||
2995 | UTIL.addEvent(wrapperDiv, 'mouseout', function publishButtonMouseOut(event) { | ||
2996 | self.hide(); | ||
2997 | }); | ||
2998 | |||
2999 | UTIL.addEvent(wrapperDiv, 'mouseover', function publishButtonMouseOver(event) { | ||
3000 | cancelTimer(); | ||
3001 | activatePublishOptions(true); | ||
3002 | }); | ||
3003 | |||
3004 | document.body.appendChild(wrapperDiv); | ||
3005 | |||
3006 | this.show = function show(onTop, margin) { | ||
3007 | if (onTop) { | ||
3008 | wrapperDiv.style.top = '0px'; | ||
3009 | wrapperDiv.style.marginTop = margin + 'px'; | ||
3010 | DOM.deleteStyleProperty(wrapperDiv, 'bottom'); | ||
3011 | } else { | ||
3012 | wrapperDiv.style.bottom = '0px'; | ||
3013 | wrapperDiv.style.marginBottom = margin + 'px';; | ||
3014 | DOM.deleteStyleProperty(wrapperDiv, 'top'); | ||
3015 | } | ||
3016 | activatePublishOptions(true); | ||
3017 | cancelTimer(); | ||
3018 | activateOptionsTimerId = setTimeout(function() { | ||
3019 | activatePublishOptions(false); | ||
3020 | }, 5000); | ||
3021 | }; | ||
3022 | |||
3023 | this.hide = function hide() { | ||
3024 | activatePublishOptions(false); | ||
3025 | }; | ||
3026 | |||
3027 | this.scrollToPosition = function scrollToPosition(onTop, position) { | ||
3028 | if (onTop) { | ||
3029 | wrapperDiv.style.top = position; | ||
3030 | } else { | ||
3031 | wrapperDiv.style.bottom = position; | ||
3032 | } | ||
3033 | }; | ||
3034 | |||
3035 | cancelTimer = function cancelTimer() { | ||
3036 | if (activateOptionsTimerId) { | ||
3037 | clearTimeout(activateOptionsTimerId); | ||
3038 | } | ||
3039 | }; | ||
3040 | |||
3041 | activatePublishOptions = function activatePublishOptions(activate) { | ||
3042 | if (hasEditPermission == 'true' && activate) { | ||
3043 | wrapperDiv.style.display = 'table'; | ||
3044 | } else { | ||
3045 | wrapperDiv.style.display = 'none'; | ||
3046 | } | ||
3047 | }; | ||
3048 | } | ||
3049 | } | ||
3050 | |||
3051 | |||
3052 | /** | ||
3053 | * Manages page level keyboard shortcuts. | ||
3054 | */ | ||
3055 | function PageShortcuts(pageEditor) { | ||
3056 | this.enable = function enable() { | ||
3057 | DOM.addListener('keydown', function keydownHandler(event) { | ||
3058 | switch (event.keyCode) { | ||
3059 | case 27: | ||
3060 | // ESC | ||
3061 | // event.preventDefault(); | ||
3062 | // event.stopPropagation(); | ||
3063 | // pageEditor.close(); | ||
3064 | // return false; | ||
3065 | // case 77: | ||
3066 | // // "m" | ||
3067 | // if (pageEditor.hasFocus()) { | ||
3068 | // event.preventDefault(); | ||
3069 | // event.stopPropagation(); | ||
3070 | // pageEditor.moveOverlayBar(); | ||
3071 | // } | ||
3072 | // return false; | ||
3073 | |||
3074 | // case 85: | ||
3075 | // // "u" | ||
3076 | // if (pageEditor.hasFocus()) { | ||
3077 | // event.preventDefault(); | ||
3078 | // event.stopPropagation(); | ||
3079 | // pageEditor.commandUndo(); | ||
3080 | // } | ||
3081 | return false; | ||
3082 | } | ||
3083 | }, true); | ||
3084 | } | ||
3085 | } | ||
3086 | |||
3087 | /** | ||
3088 | * Maintains command history and related features like undo and publish. | ||
3089 | */ | ||
3090 | function EditCommandHistory(pageEditor) { | ||
3091 | var self = this, history = [], imageSrc, imageMatcher, imageHeight, imageWidth, buildDataString, anchorElement, anchorElementId, ajaxResultProcessor = new AjaxResultProcessor(); | ||
3092 | |||
3093 | this.hasChangesPending = function hasChangesPending() { | ||
3094 | return history.length > 0; | ||
3095 | }; | ||
3096 | this.formUncomplete = function formUnomplete(){ | ||
3097 | return (locName == '' && langName=='' && styleName == '' ); | ||
3098 | }; | ||
3099 | |||
3100 | this.apply = function apply(command) { | ||
3101 | var poofPosition, poofDiv; | ||
3102 | |||
3103 | switch (command.command) { | ||
3104 | case 'TEXT_UPDATE': | ||
3105 | command.element = document.getElementById("alipiSelectedElement"); | ||
3106 | command.previousData = document.getElementById("alipiSelectedElement").textContent; | ||
3107 | command.data = document.getElementById("editor").value; | ||
3108 | DOM.textContent(command.element, command.data); | ||
3109 | pageEditor.showMessage('Text changed'); | ||
3110 | break; | ||
3111 | case 'AUDIO_SRC_UPDATE': | ||
3112 | textElementPopup.hasAudio = true; | ||
3113 | command.previousData = ""; | ||
3114 | pageEditor.showMessage('Audio updated'); | ||
3115 | break; | ||
3116 | |||
3117 | case 'DELETE': | ||
3118 | poofPosition = DOM.findPosition(command.element); | ||
3119 | |||
3120 | poofDiv = DOM.BUILDER.DIV({'style' : 'width:32px;height:32px;background: transparent url(http://y.a11y.in/alipi/images/poof.png) no-repeat;position:absolute;top:' + poofPosition.y + 'px;left:' + poofPosition.x + 'px;'}); | ||
3121 | document.body.appendChild(poofDiv); | ||
3122 | |||
3123 | UTIL.animate(function(index, last) { | ||
3124 | if (last) { | ||
3125 | document.body.removeChild(poofDiv); | ||
3126 | } else { | ||
3127 | poofDiv.style.backgroundPosition = '0 -' + (index * 32) + 'px'; | ||
3128 | } | ||
3129 | }, 5, 100); | ||
3130 | |||
3131 | DOM.overrideStyleProperty(command.element, 'display', 'none'); | ||
3132 | pageEditor.showMessage('Section deleted'); | ||
3133 | break; | ||
3134 | |||
3135 | case 'IMAGE_SRC_UPDATE': | ||
3136 | imageMatcher = new RegExp("(\\d+)x(\\d+),(.+)").exec(command.data); | ||
3137 | imageWidth = imageMatcher[1]; | ||
3138 | imageHeight = imageMatcher[2]; | ||
3139 | imageSrc = imageMatcher[3]; | ||
3140 | |||
3141 | if (imageSrc && command.element.src != imageSrc) { | ||
3142 | command.element.src = imageSrc; | ||
3143 | pageEditor.showMessage('Image changed'); | ||
3144 | } | ||
3145 | if (imageWidth == 0) { | ||
3146 | command.element.removeAttribute('width'); | ||
3147 | } else { | ||
3148 | command.element.width = imageWidth; | ||
3149 | } | ||
3150 | |||
3151 | if (imageHeight == 0) { | ||
3152 | command.element.removeAttribute('height'); | ||
3153 | } else { | ||
3154 | command.element.height = imageHeight; | ||
3155 | } | ||
3156 | break; | ||
3157 | |||
3158 | case 'ANCHOR_UPDATE': | ||
3159 | command.element.setAttribute('href', command.data); | ||
3160 | pageEditor.showMessage('Link changed'); | ||
3161 | break; | ||
3162 | |||
3163 | case 'ANCHOR_CREATE': | ||
3164 | anchorElement = DOM.BUILDER.A({ 'href' : command.data }); | ||
3165 | command.element.parentNode.replaceChild(anchorElement, command.element); | ||
3166 | anchorElement.appendChild(command.element); | ||
3167 | command.previousData = anchorElement; | ||
3168 | pageEditor.showMessage('Link added'); | ||
3169 | break; | ||
3170 | |||
3171 | case 'AUDIO_UPDATE': | ||
3172 | command.element.setAttribute('src', command.data); | ||
3173 | pageEditor.showMessage('Audio changed'); | ||
3174 | break; | ||
3175 | |||
3176 | case 'AUDIO_CREATE': | ||
3177 | audioElement = document.createElement('audio'); | ||
3178 | audioElement.setAttribute("id", "audiotag"); | ||
3179 | audioElement.setAttribute('src',command.data); | ||
3180 | audioElement.setAttribute('controls','controls'); | ||
3181 | audioElement.setAttribute('style', 'display:table;'); | ||
3182 | $(audioElement).insertBefore($(selectedElement)); | ||
3183 | pageEditor.showMessage('Audio added'); | ||
3184 | break; | ||
3185 | |||
3186 | default: | ||
3187 | console.error('Unknown command:', command); | ||
3188 | } | ||
3189 | |||
3190 | history.push(command); | ||
3191 | }; | ||
3192 | |||
3193 | this.undo = function undo() { | ||
3194 | var imageElement, command; | ||
3195 | |||
3196 | if (self.hasChangesPending()) { | ||
3197 | command = history.pop(); | ||
3198 | switch (command.command) { | ||
3199 | case 'TEXT_UPDATE': | ||
3200 | command.element.innerHTML = command.previousData; | ||
3201 | pageEditor.showMessage('Text change undone'); | ||
3202 | break; | ||
3203 | |||
3204 | case 'DELETE': | ||
3205 | DOM.restoreStyleProperty(command.element, 'display', ''); | ||
3206 | pageEditor.showMessage('Delete undone'); | ||
3207 | break; | ||
3208 | |||
3209 | case 'IMAGE_SRC_UPDATE': | ||
3210 | imageElement = new M4ImageElement(command.element); | ||
3211 | |||
3212 | command.element.src = command.previousData.src; | ||
3213 | if (command.previousData.size.width) { | ||
3214 | command.element.width = command.previousData.size.width; | ||
3215 | } else { | ||
3216 | command.element.removeAttribute('width'); | ||
3217 | } | ||
3218 | if (command.previousData.size.height) { | ||
3219 | command.element.height = command.previousData.size.height; | ||
3220 | } else { | ||
3221 | command.element.removeAttribute('height'); | ||
3222 | } | ||
3223 | imageElement.setRawImageSize(command.previousData.rawImageSize) | ||
3224 | |||
3225 | pageEditor.showMessage('Image change undone'); | ||
3226 | break; | ||
3227 | |||
3228 | case 'AUDIO_SRC_UPDATE': | ||
3229 | command.element.remove(); | ||
3230 | pageEditor.showMessage('Link removed'); | ||
3231 | break; | ||
3232 | case 'ANCHOR_UPDATE': | ||
3233 | command.element.setAttribute('href', command.previousData); | ||
3234 | pageEditor.showMessage('Link change undone'); | ||
3235 | break; | ||
3236 | |||
3237 | case 'ANCHOR_CREATE': | ||
3238 | command.previousData.parentNode.replaceChild(command.element, command.previousData); | ||
3239 | pageEditor.showMessage('Link removed'); | ||
3240 | break; | ||
3241 | |||
3242 | default: | ||
3243 | console.error('Unknown command:', command); | ||
3244 | } | ||
3245 | } else { | ||
3246 | pageEditor.showMessage('Nothing to undo'); | ||
3247 | } | ||
3248 | }; | ||
3249 | |||
3250 | this.publish = function publish() { | ||
3251 | var result; | ||
3252 | if(document.getElementById('our-check').checked) | ||
3253 | { | ||
3254 | localStorage.myContent = buildDataString(); | ||
3255 | window.location.href = "http://dev.a11y.in/test.html"; | ||
3256 | window.reload(); | ||
3257 | } | ||
3258 | else{ | ||
3259 | |||
3260 | AJAX.post('http://dev.a11y.in/test', buildDataString(), function(result) { | ||
3261 | ajaxResultProcessor.processPublishedResponse(result); | ||
3262 | }); | ||
3263 | } | ||
3264 | }; | ||
3265 | |||
3266 | // this.switchMode = function switchMode(saveChanges) { | ||
3267 | // var result, requestParameters; | ||
3268 | |||
3269 | // requestParameters = '?slug=' + pageSlug + '&uploadSlug=' + uploadSlug; | ||
3270 | // if (successUrl) { | ||
3271 | // requestParameters = requestParameters + '&successUrl=' + encodeURIComponent(successUrl); | ||
3272 | // } | ||
3273 | |||
3274 | // if (saveChanges) { | ||
3275 | // result = AJAX.post('/app/page-edit/switch-edit-mode' + requestParameters, | ||
3276 | // buildDataString()); | ||
3277 | // ajaxResultProcessor.processSwitchModeResponse(result); | ||
3278 | // } else { | ||
3279 | // window.location.href = 'https://bo.lt/app/page-edit/html' + requestParameters; | ||
3280 | // } | ||
3281 | // }; | ||
3282 | |||
3283 | buildDataString = function buildDataString() { | ||
3284 | var check_xpath = [], temp_history = [], index = []; | ||
3285 | for(x=0; x<history.length; x++) { | ||
3286 | check_xpath.push(history[x].xpath); | ||
3287 | } | ||
3288 | for(i=0; i<check_xpath.length-1; i++) { | ||
3289 | for(j=i+1; j<check_xpath.length; j++) { | ||
3290 | if ((check_xpath[i] == check_xpath[j]) && (history[i].elementType == history[j].elementType)) { | ||
3291 | index.push(i); | ||
3292 | } | ||
3293 | } | ||
3294 | } | ||
3295 | if (index.length > 0) { | ||
3296 | for (var z=0; z<index.length; z++) { | ||
3297 | delete history[index[z]]; | ||
3298 | } | ||
3299 | } | ||
3300 | |||
3301 | for (var x=0; x<history.length; x++) { | ||
3302 | if (history[x] != undefined) { | ||
3303 | temp_history.push(history[x]); | ||
3304 | } | ||
3305 | } | ||
3306 | |||
3307 | history = temp_history; | ||
3308 | |||
3309 | var command, buffer; | ||
3310 | buffer = new UTIL.StringBuffer(); | ||
3311 | UTIL.forEach(history, function(index, command) { | ||
3312 | buffer.append('###'); //separates the commands | ||
3313 | buffer.append('about='); //url=about //removed '&' on purpose | ||
3314 | buffer.append(window.location.search.split('=')[1]); | ||
3315 | buffer.append('&lang=');//lang | ||
3316 | buffer.append(encodeURIComponent(langName.value)); | ||
3317 | buffer.append('&location=');//location | ||
3318 | buffer.append(encodeURIComponent(locName.value)); | ||
3319 | buffer.append('&style=');//style | ||
3320 | buffer.append(encodeURIComponent(styleSelect.value)); | ||
3321 | buffer.append('&blog='); //blog where to post | ||
3322 | buffer.append(encodeURIComponent("blog")); | ||
3323 | buffer.append('&elementtype='); // text, audio, img | ||
3324 | buffer.append(encodeURIComponent(command.elementType)); | ||
3325 | buffer.append('&xpath=');//xpath | ||
3326 | buffer.append(encodeURIComponent(command.xpath)); | ||
3327 | buffer.append('&data='); //data | ||
3328 | buffer.append(encodeURIComponent(command.data)); | ||
3329 | buffer.append('&author='); //author | ||
3330 | if (author.value == '') { | ||
3331 | buffer.append(encodeURIComponent('Anonymous')); | ||
3332 | } else { | ||
3333 | buffer.append(encodeURIComponent(author.value)); | ||
3334 | } | ||
3335 | }); console.log(buffer.toString()); | ||
3336 | return buffer.toString().substring(3); | ||
3337 | }; | ||
3338 | } | ||
3339 | |||
3340 | /** | ||
3341 | * Main coordinator for the visual editor's overlay, shortcuts, edits and primary popups. | ||
3342 | */ | ||
3343 | function VisualPageEditor() { | ||
3344 | var self = this, overlayBar, pageShortcuts, editCommandHistory, editorHasFocus = true, listeners = new Array(), | ||
3345 | textElementSelector, imageElementSelector, editableElementSelector, preProcessors = new Array(), | ||
3346 | currentSelector = null, updateSelection, getSelectorForType, focus, closePopup; | ||
3347 | var ACTION = { | ||
3348 | MOUSE_OVER : 0, MOUSE_OUT: 1, MOUSE_CLICK: 2 | ||
3349 | }; | ||
3350 | |||
3351 | overlayBar = new OverlayBar(this, true); | ||
3352 | pageShortcuts = new PageShortcuts(this); | ||
3353 | editCommandHistory = new EditCommandHistory(this); | ||
3354 | |||
3355 | preProcessors.push(new FlashPreProcessor()); | ||
3356 | preProcessors.push(new IframePreProcessor()); | ||
3357 | preProcessors.push(new FormPreProcessor()); | ||
3358 | |||
3359 | textElementSelector = new TextElementSelector(self); | ||
3360 | imageElementSelector = new ImageElementSelector(self); | ||
3361 | editableElementSelector = new EditableElementSelector(self); | ||
3362 | |||
3363 | this.hasChangesPending = function hasChangesPending() { | ||
3364 | return editCommandHistory.hasChangesPending(); | ||
3365 | }; | ||
3366 | |||
3367 | |||
3368 | this.formUncomplete = function fromUncomplete() { | ||
3369 | return editCommandHistory.formUncomplete(); | ||
3370 | }; | ||
3371 | |||
3372 | this.show = function show() { | ||
3373 | |||
3374 | DOM.addListener('mouseover', function globalMouseOverListener(event) { | ||
3375 | if(event.target.id != 'ok-button'){ | ||
3376 | var type = event.target.getAttribute('m4pageedittype'); | ||
3377 | if (type) { | ||
3378 | event.preventDefault(); | ||
3379 | event.stopPropagation(); | ||
3380 | updateSelection(ACTION.MOUSE_OVER, event); | ||
3381 | }} | ||
3382 | }, true); | ||
3383 | |||
3384 | DOM.addListener('mouseout', function globalMouseOutListener(event) { | ||
3385 | var type = event.target.getAttribute('m4pageedittype'); | ||
3386 | if (type) { | ||
3387 | event.preventDefault(); | ||
3388 | event.stopPropagation(); | ||
3389 | updateSelection(ACTION.MOUSE_OUT, event); | ||
3390 | } | ||
3391 | }, true); | ||
3392 | |||
3393 | DOM.addListener('click', function globalClickListener(event) { | ||
3394 | var type = event.target.getAttribute('m4pageedittype'); | ||
3395 | var alipiElements = event.target.getAttribute('alipiElements'); | ||
3396 | if (event.target.getAttribute('m4pageeditcontrol')) { | ||
3397 | // click is passthrough for our controls | ||
3398 | } else if (type) { | ||
3399 | event.preventDefault(); | ||
3400 | event.stopPropagation(); | ||
3401 | updateSelection(ACTION.MOUSE_CLICK, event); | ||
3402 | } else if (event.target.id == "" || alipiElements || event.target.parentNode.attributes['class'].value == "ui-menu-item") { // click is passthrough for our controls | ||
3403 | } else { | ||
3404 | // normal page elements | ||
3405 | event.preventDefault(); | ||
3406 | event.stopPropagation(); | ||
3407 | self.saveAndClose(); | ||
3408 | } | ||
3409 | }, true); | ||
3410 | |||
3411 | // We intercept mousedown so things like drop down box won't work during edit mode. | ||
3412 | DOM.addListener('mousedown', function globalMouseDownListener(event) { | ||
3413 | |||
3414 | var alipiElements = event.target.getAttribute('alipiElements'); | ||
3415 | if (event.target.getAttribute('m4pageeditcontrol')) { | ||
3416 | // passthrough | ||
3417 | } else if (event.target.getAttribute('m4pageedittype')) { | ||
3418 | // passthrough | ||
3419 | } else if (event.target.id == "lang-select" || event.target.id == "loc-select" || alipiElements) { | ||
3420 | // passthrough | ||
3421 | } else if (event.clientX > document.body.clientWidth || event.clientY > document.body.clientHeight) { | ||
3422 | // passthrough if this click was outside of the html page, meaning on a scrollbar | ||
3423 | } else { | ||
3424 | // normal page elements | ||
3425 | event.preventDefault(); | ||
3426 | event.stopPropagation(); | ||
3427 | } | ||
3428 | }, true); | ||
3429 | pageShortcuts.enable(); | ||
3430 | overlayBar.show(false); | ||
3431 | overlayBar.message("Ready to Narrate"); | ||
3432 | }; | ||
3433 | |||
3434 | |||
3435 | updateSelection = function updateSelection(action, event) { | ||
3436 | var type, selector, element = event.target; | ||
3437 | selector = getSelectorForType(element.getAttribute('m4pageedittype')); | ||
3438 | if (selector) { | ||
3439 | switch (action) { | ||
3440 | case ACTION.MOUSE_OVER: | ||
3441 | if (currentSelector == null) { | ||
3442 | selector.highlight(element); | ||
3443 | } | ||
3444 | break; | ||
3445 | case ACTION.MOUSE_OUT: | ||
3446 | if (currentSelector == null) { | ||
3447 | selector.unhighlight(element); | ||
3448 | } | ||
3449 | break; | ||
3450 | case ACTION.MOUSE_CLICK: | ||
3451 | if (currentSelector == null) { | ||
3452 | currentSelector = selector; | ||
3453 | currentSelector.select(element, event); | ||
3454 | } else if (currentSelector.isCurrentSelection(element)) { | ||
3455 | currentSelector.select(element, event); | ||
3456 | } else { | ||
3457 | self.saveAndClose(); | ||
3458 | selector.focus(); | ||
3459 | selector.highlight(element); | ||
3460 | } | ||
3461 | break; | ||
3462 | } | ||
3463 | } | ||
3464 | }; | ||
3465 | |||
3466 | getSelectorForType = function getSelectorForType(type) { | ||
3467 | |||
3468 | switch (type) { | ||
3469 | case 'text': | ||
3470 | return textElementSelector; | ||
3471 | case 'image': | ||
3472 | return imageElementSelector; | ||
3473 | case 'edit': | ||
3474 | return editableElementSelector; | ||
3475 | } | ||
3476 | return null; | ||
3477 | }; | ||
3478 | |||
3479 | focus = function focus(saveChanges) { | ||
3480 | editorHasFocus = true; | ||
3481 | for (var i = 0; i < listeners.length; i++) { | ||
3482 | listeners[i](saveChanges) | ||
3483 | } | ||
3484 | }; | ||
3485 | |||
3486 | closePopup = function closePopup(saveChanges) { | ||
3487 | if (currentSelector != null) { | ||
3488 | currentSelector.unselect(); | ||
3489 | currentSelector = null; | ||
3490 | } | ||
3491 | focus(saveChanges); | ||
3492 | }; | ||
3493 | |||
3494 | this.loseFocus = function loseFocus() { | ||
3495 | editorHasFocus = false; | ||
3496 | }; | ||
3497 | |||
3498 | this.hasFocus = function hasFocus() { | ||
3499 | return editorHasFocus; | ||
3500 | }; | ||
3501 | |||
3502 | this.addFocusListener = function addFocusListener(listener) { | ||
3503 | listeners.push(listener) | ||
3504 | }; | ||
3505 | |||
3506 | this.removeFocusListener = function(listener) { | ||
3507 | for (var i = 0; i < listeners.length; i++) { | ||
3508 | if (listeners[i] == listener) { | ||
3509 | listeners.splice(i, 1); | ||
3510 | } | ||
3511 | } | ||
3512 | }; | ||
3513 | |||
3514 | this.close = function close() { | ||
3515 | closePopup(false); | ||
3516 | }; | ||
3517 | |||
3518 | this.saveAndClose = function saveAndClose() { | ||
3519 | closePopup(true); | ||
3520 | }; | ||
3521 | |||
3522 | // this composition is necessary to avoid circular dependencies | ||
3523 | // this.moveOverlayBar = function moveOverlayBar() { | ||
3524 | // overlayBar.move(); | ||
3525 | // }; | ||
3526 | |||
3527 | this.showMessage = function showMessage(message) { | ||
3528 | overlayBar.message(message); | ||
3529 | }; | ||
3530 | |||
3531 | this.commandApply = function commandApply(command) { | ||
3532 | editCommandHistory.apply(command); | ||
3533 | }; | ||
3534 | |||
3535 | this.commandUndo = function commandUndo() { | ||
3536 | editCommandHistory.undo(); | ||
3537 | }; | ||
3538 | |||
3539 | this.commandPublish = function commandPublish() { | ||
3540 | |||
3541 | overlayBar.show(false); | ||
3542 | self.saveAndClose(); | ||
3543 | for (var i = 0; i < preProcessors.length; i++) { | ||
3544 | preProcessors[i].restore(); | ||
3545 | } | ||
3546 | editCommandHistory.publish(); | ||
3547 | overlayBar.show(true); | ||
3548 | }; | ||
3549 | |||
3550 | this.activateEditor = function activateEditor() { | ||
3551 | overlayBar.show(true); | ||
3552 | for (var i = 0; i < preProcessors.length; i++) { | ||
3553 | preProcessors[i].process(); | ||
3554 | } | ||
3555 | }; | ||
3556 | |||
3557 | function IframePreProcessor () { | ||
3558 | this.process = function process() { | ||
3559 | // make iframes unclickable by overlaying transparent div over it. | ||
3560 | UTIL.forEach(document.getElementsByTagName('iframe'), function(index, iframe) { | ||
3561 | var displayStyle = null; | ||
3562 | if (document.defaultView && document.defaultView.getComputedStyle) { | ||
3563 | displayStyle = document.defaultView.getComputedStyle(iframe, null).getPropertyValue('display'); | ||
3564 | } else if (iframe.currentStyle) { | ||
3565 | displayStyle = iframe.currentStyle['display']; | ||
3566 | } | ||
3567 | if(displayStyle != 'none') { | ||
3568 | DOM.clickBlocker(iframe); | ||
3569 | } | ||
3570 | var iframeSourceUrl = iframe.src; | ||
3571 | var isYouTubeIFrame = iframeSourceUrl.toLowerCase().indexOf('youtube') != -1; | ||
3572 | if (isYouTubeIFrame) { | ||
3573 | // If the flash object is visible when the wmode property is set, then the state doesn't get updated. | ||
3574 | // So first set the parent node's display property to 'none, then add the wmode property and finally | ||
3575 | // restore the original display proeprty back on the parent. | ||
3576 | DOM.overrideStylePropert(iframe.parentNode, 'display', 'none'); | ||
3577 | if(iframeSourceUrl.indexOf('?') != -1) { | ||
3578 | iframe.src = iframeSourceUrl + '&wmode=opaque'; | ||
3579 | } else { | ||
3580 | iframe.src = iframeSourceUrl + '?wmode=opaque'; | ||
3581 | } | ||
3582 | DOM.restoreStyleProperty(iframe.parentNode, 'display'); | ||
3583 | } | ||
3584 | }); | ||
3585 | }; | ||
3586 | |||
3587 | this.restore = function restore() { | ||
3588 | }; | ||
3589 | }; | ||
3590 | |||
3591 | function FlashPreProcessor() { | ||
3592 | this.process = function process() { | ||
3593 | // make flash objects unclickable by overlaying transparent div over it. | ||
3594 | // If the flash object is visible when the wmode property is set, then the state doesn't get updated. | ||
3595 | // So first set the parent node's display property to 'none, then add the wmode property and finally | ||
3596 | // restore the original display proeprty back on the parent. | ||
3597 | UTIL.forEach(document.getElementsByTagName('object'), function(index, value) { | ||
3598 | DOM.overrideStyleProperty(value.parentNode, 'display', 'none'); | ||
3599 | DOM.clickBlocker(value); | ||
3600 | var param = document.createElement('param'); | ||
3601 | param.setAttribute('name', 'wmode'); | ||
3602 | param.setAttribute('value', 'opaque'); | ||
3603 | value.appendChild(param); | ||
3604 | DOM.restoreStyleProperty(value.parentNode, 'display'); | ||
3605 | }); | ||
3606 | |||
3607 | UTIL.forEach(document.getElementsByTagName('embed'), function(index, value) { | ||
3608 | DOM.overrideStyleProperty(value.parentNode, 'display', 'none'); | ||
3609 | DOM.clickBlocker(value); | ||
3610 | value.setAttribute('wmode', 'opaque'); | ||
3611 | DOM.restoreStyleProperty(value.parentNode, 'display'); | ||
3612 | }); | ||
3613 | }; | ||
3614 | |||
3615 | this.restore = function restore() { | ||
3616 | }; | ||
3617 | }; | ||
3618 | |||
3619 | function FormPreProcessor () { | ||
3620 | var overrideElementAttribute = function overrideElementAttribute(nodeName, attributeName, attributeValue) { | ||
3621 | UTIL.forEach(document.getElementsByTagName(nodeName), function(index, inputElement) { | ||
3622 | var type = inputElement.getAttribute('m4pageeditcontrol'); | ||
3623 | if (!type) { | ||
3624 | DOM.overrideAttribute(inputElement, attributeName, attributeValue); | ||
3625 | } | ||
3626 | }); | ||
3627 | }; | ||
3628 | |||
3629 | var restoreElementAttribute = function restoreElementAttribute(nodeName, attributeName) { | ||
3630 | UTIL.forEach(document.getElementsByTagName(nodeName), function(index, inputElement) { | ||
3631 | var type = inputElement.getAttribute('m4pageeditcontrol'); | ||
3632 | if (!type) { | ||
3633 | DOM.restoreAttribute(inputElement, attributeName); | ||
3634 | } | ||
3635 | }); | ||
3636 | }; | ||
3637 | |||
3638 | this.process = function process() { | ||
3639 | overrideElementAttribute('input', 'readonly', 'true'); | ||
3640 | overrideElementAttribute('textarea', 'readonly', 'true'); | ||
3641 | }; | ||
3642 | |||
3643 | this.restore = function restore() { | ||
3644 | restoreElementAttribute('input', 'readonly'); | ||
3645 | restoreElementAttribute('textarea', 'readonly'); | ||
3646 | }; | ||
3647 | }; | ||
3648 | |||
3649 | function ImageElementSelector(pageEditor) { | ||
3650 | var self = this, imageElementPopup = new EditableElementPopup(pageEditor, true), lastSelection = null; | ||
3651 | this.highlight = function highlight(element) { | ||
3652 | DOM.overrideStyleProperty(element, 'outline', '#777 solid 2px'); | ||
3653 | DOM.overrideStyleProperty(element, 'cursor', 'pointer'); | ||
3654 | }; | ||
3655 | |||
3656 | this.unhighlight = function unhighlight(element) { | ||
3657 | DOM.restoreStyleProperty(element, 'cursor', ''); | ||
3658 | DOM.restoreStyleProperty(element, 'outline', ''); | ||
3659 | }; | ||
3660 | |||
3661 | this.select = function select(element, event) { | ||
3662 | if (lastSelection == null) { | ||
3663 | lastSelection = element; | ||
3664 | self.unhighlight(lastSelection); | ||
3665 | self.highlight(lastSelection); | ||
3666 | imageElementPopup.popupAt(lastSelection, event.pageX, event.pageY); | ||
3667 | } | ||
3668 | }; | ||
3669 | |||
3670 | this.unselect = function unselect() { | ||
3671 | if (lastSelection) { | ||
3672 | self.unhighlight(lastSelection); | ||
3673 | } | ||
3674 | lastSelection = null; | ||
3675 | }; | ||
3676 | |||
3677 | this.isCurrentSelection = function isCurrentSelection(element) { | ||
3678 | return lastSelection == element; | ||
3679 | }; | ||
3680 | |||
3681 | this.focus = function focus(element) { | ||
3682 | // NO OP | ||
3683 | }; | ||
3684 | }; | ||
3685 | |||
3686 | function EditableElementSelector(pageEditor) { | ||
3687 | var self = this, editableElementPopup = new EditableElementPopup(pageEditor, false), lastSelection = null; | ||
3688 | |||
3689 | this.highlight = function highlight(element) { | ||
3690 | DOM.overrideStyleProperty(element, 'outline', ''); | ||
3691 | DOM.overrideStyleProperty(element, 'cursor', 'pointer'); | ||
3692 | }; | ||
3693 | |||
3694 | this.unhighlight = function unhighlight(element) { | ||
3695 | DOM.restoreStyleProperty(element, 'cursor', ''); | ||
3696 | DOM.restoreStyleProperty(element, 'outline', ''); | ||
3697 | }; | ||
3698 | |||
3699 | this.select = function select(element, event) { | ||
3700 | if (lastSelection == null) { | ||
3701 | lastSelection = element; | ||
3702 | self.unhighlight(lastSelection); | ||
3703 | self.highlight(lastSelection); | ||
3704 | editableElementPopup.popupAt(lastSelection, event.pageX, event.pageY); | ||
3705 | } | ||
3706 | }; | ||
3707 | |||
3708 | this.unselect = function unselect() { | ||
3709 | if (lastSelection) { | ||
3710 | self.unhighlight(lastSelection); | ||
3711 | } | ||
3712 | lastSelection = null; | ||
3713 | }; | ||
3714 | |||
3715 | this.isCurrentSelection = function isCurrentSelection(element) { | ||
3716 | return lastSelection == element; | ||
3717 | } | ||
3718 | |||
3719 | this.focus = function focus(element) { | ||
3720 | // NO OP | ||
3721 | }; | ||
3722 | }; | ||
3723 | |||
3724 | function TextElementSelector(pageEditor) { | ||
3725 | var self = this, lastSelection = null, textElementPopup = new TextElementPopup(pageEditor), editor, | ||
3726 | findAnchorAncestor, internalHighlight; | ||
3727 | |||
3728 | if(DOM.isIEBrowser()) { | ||
3729 | editor = new InternetExplorerInlineEditor(); | ||
3730 | } else { | ||
3731 | editor = new DefaultInlineEditor(); | ||
3732 | } | ||
3733 | |||
3734 | this.highlight = function highlight(element) { | ||
3735 | |||
3736 | internalHighlight(element, '#fff', '#bbb', 'pointer'); | ||
3737 | editor.activate(element); | ||
3738 | }; | ||
3739 | |||
3740 | this.unhighlight = function unhighlight(element) { | ||
3741 | DOM.restoreStyleProperty(element, 'borderLeft', ''); | ||
3742 | DOM.restoreStyleProperty(element, 'borderRight', ''); | ||
3743 | DOM.restoreStyleProperty(element, 'cursor', ''); | ||
3744 | DOM.restoreStyleProperty(element, 'backgroundColor', ''); | ||
3745 | DOM.restoreStyleProperty(element, 'color', ''); | ||
3746 | editor.deactivate(element); | ||
3747 | }; | ||
3748 | |||
3749 | this.select = function select(element, event) { | ||
3750 | if (lastSelection == null) { | ||
3751 | lastSelection = element; | ||
3752 | self.unhighlight(lastSelection); | ||
3753 | editor.activate(element); | ||
3754 | internalHighlight(lastSelection, '#333', '#fff', 'text'); | ||
3755 | textElementPopup.popupAt(lastSelection, event.pageX, event.pageY); | ||
3756 | } | ||
3757 | editor.startEditing(event); | ||
3758 | }; | ||
3759 | |||
3760 | |||
3761 | this.unselect = function unselect() { | ||
3762 | if (lastSelection) { | ||
3763 | self.unhighlight(lastSelection); | ||
3764 | editor.stopEditing(); | ||
3765 | } | ||
3766 | lastSelection = null; | ||
3767 | }; | ||
3768 | |||
3769 | this.isCurrentSelection = function isCurrentSelection(element) { | ||
3770 | return lastSelection == element; | ||
3771 | }; | ||
3772 | |||
3773 | this.focus = function focus(element) { | ||
3774 | editor.focus(); | ||
3775 | }; | ||
3776 | internalHighlight = function internalHighlight(element, highlightColor, highlightBackground, cursorType) { | ||
3777 | // because element containing text often have a calculated height of | ||
3778 | // 0, even when text is showing, we need to highlight using background | ||
3779 | // color. | ||
3780 | DOM.overrideStyleProperty(element, 'cursor', cursorType); | ||
3781 | DOM.overrideStyleProperty(element, 'borderLeft', '#FFF solid 2px'); // Ajay -changed color but can't notice where | ||
3782 | DOM.overrideStyleProperty(element, 'borderRight', '#000 solid 2px'); // Ajay- Same here | ||
3783 | DOM.overrideStyleProperty(element, 'color', highlightColor); | ||
3784 | DOM.overrideStyleProperty(element, 'backgroundColor', highlightBackground); | ||
3785 | }; | ||
3786 | |||
3787 | function DefaultInlineEditor () { | ||
3788 | var self = this, currentEditableElement = null, activateAncestorNodes, ancestorsEditable = false, makeAncestorsEditable, updateCursorPosition; | ||
3789 | |||
3790 | // FF doesn't let you delete the text inside the span if the ancestor is another inline element and that is uneditable | ||
3791 | // http://htmlhelp.com/reference/html40/inline.html | ||
3792 | var ELEMENTS_TO_OVERRIDE = {'a': 'a', 'abbr': 'abbr', 'acronym': 'acronym', 'b': 'b', 'basefont' : 'basefont', | ||
3793 | 'bdo': 'bdo', 'big' : 'big', 'br': 'br', 'cite': 'cite', 'dfn': 'dfn', 'em': 'em', 'font': 'font', 'i': 'i', | ||
3794 | 'img': 'img', 'input': 'input', 'kbd': 'kbd', 'label': 'label', 'q': 'q', 's': 's', 'samp': 'samp', | ||
3795 | 'select': 'select','small': 'small', 'span': 'span', 'strike': 'strike', 'strong': 'strong', 'sub': 'sub', | ||
3796 | 'sup': 'sup', 'textarea': 'textarea', 'tt': 'tt', 'u': 'u', 'var': 'var'}; | ||
3797 | |||
3798 | this.activate = function activate(element) { | ||
3799 | currentEditableElement = element; | ||
3800 | DOM.overrideAttribute(currentEditableElement, 'contentEditable', 'true'); | ||
3801 | }; | ||
3802 | |||
3803 | this.deactivate = function deactivate() { | ||
3804 | if (currentEditableElement) { | ||
3805 | DOM.restoreAttribute(currentEditableElement,'contentEditable'); | ||
3806 | } | ||
3807 | }; | ||
3808 | |||
3809 | this.startEditing = function startEditing(event) { | ||
3810 | if (currentEditableElement && event.rangeOffset) { | ||
3811 | // FF specific | ||
3812 | ancestorsEditable = true; | ||
3813 | makeAncestorsEditable(currentEditableElement.parentNode, true); | ||
3814 | updateCursorPosition(event); | ||
3815 | } | ||
3816 | }; | ||
3817 | |||
3818 | this.stopEditing = function stopEditing() { | ||
3819 | if (currentEditableElement && ancestorsEditable) { | ||
3820 | ancestorsEditable = false; | ||
3821 | makeAncestorsEditable(currentEditableElement.parentNode, false); | ||
3822 | } | ||
3823 | self.deactivate(); | ||
3824 | currentEditableElement = null; | ||
3825 | }; | ||
3826 | |||
3827 | this.focus = function focus() { | ||
3828 | window.getSelection().removeAllRanges(); | ||
3829 | }; | ||
3830 | |||
3831 | updateCursorPosition = function updateCursorPosition(event) { | ||
3832 | var selection = window.getSelection(); | ||
3833 | var range = selection.getRangeAt(0); | ||
3834 | |||
3835 | if (selection.anchorOffset == selection.focusOffset) { | ||
3836 | selection.collapse(currentEditableElement.firstChild, event.rangeOffset); | ||
3837 | } else { | ||
3838 | range.setStart(currentEditableElement.firstChild, selection.anchorOffset); | ||
3839 | range.setEnd(currentEditableElement.firstChild, selection.focusOffset); | ||
3840 | } | ||
3841 | }; | ||
3842 | |||
3843 | makeAncestorsEditable = function makeAncestorsEditable(element, editable) { | ||
3844 | if (ELEMENTS_TO_OVERRIDE[element.nodeName.toLowerCase()]) { | ||
3845 | if (editable) { | ||
3846 | DOM.overrideAttribute(element, 'contentEditable', 'true'); | ||
3847 | } else { | ||
3848 | DOM.restoreAttribute(element, 'contentEditable'); | ||
3849 | } | ||
3850 | } | ||
3851 | if (element.parentNode) { | ||
3852 | makeAncestorsEditable(element.parentNode, editable); | ||
3853 | } else { | ||
3854 | return; | ||
3855 | } | ||
3856 | } | ||
3857 | }; | ||
3858 | }; | ||
3859 | } | ||
3860 | |||
3861 | /** | ||
3862 | * Main coordinator for the html editor's overlay and other functionality. | ||
3863 | */ | ||
3864 | function HtmlPageEditor(editor) { | ||
3865 | var self = this, overlayBar, buildDataString, ajaxResultProcessor = new AjaxResultProcessor(); | ||
3866 | |||
3867 | overlayBar = new OverlayBar(this, false); | ||
3868 | |||
3869 | this.hasChangesPending = function hasChangesPending() { | ||
3870 | return editor.getSession().getUndoManager().$undoStack.length > 0; | ||
3871 | }; | ||
3872 | |||
3873 | this.show = function show() { | ||
3874 | overlayBar.show(false); | ||
3875 | overlayBar.message('New page created for editing'); | ||
3876 | }; | ||
3877 | |||
3878 | // this composition is necessary to avoid circular dependencies | ||
3879 | this.showMessage = function showMessage(message) { | ||
3880 | overlayBar.message(message); | ||
3881 | }; | ||
3882 | |||
3883 | this.commandUndo = function commandUndo() { | ||
3884 | if (self.hasChangesPending()) { | ||
3885 | editor.undo(); | ||
3886 | self.showMessage('Change undone'); | ||
3887 | } else { | ||
3888 | self.showMessage('Nothing to undo'); | ||
3889 | } | ||
3890 | }; | ||
3891 | |||
3892 | this.commandPublish = function commandPublish() { | ||
3893 | var result; | ||
3894 | splashWindow.show('Saving...'); | ||
3895 | overlayBar.show(false); | ||
3896 | result = AJAX.post('/app/page-edit/publish?slug=' + pageSlug + '&uploadSlug=' + uploadSlug + '&keepOriginal=' + keepOriginal, | ||
3897 | buildDataString(), function(result) { | ||
3898 | ajaxResultProcessor.processPublishedResponse(result); | ||
3899 | }); | ||
3900 | |||
3901 | overlayBar.show(true); | ||
3902 | }; | ||
3903 | |||
3904 | this.commandSwitchMode = function commandSwitchMode(saveChanges) { | ||
3905 | var result; | ||
3906 | |||
3907 | overlayBar.enableSwitchSave(false); | ||
3908 | var successUrlParam = ''; | ||
3909 | if (successUrl) { | ||
3910 | successUrlParam = '&successUrl=' + encodeURIComponent(successUrl); | ||
3911 | } | ||
3912 | if (saveChanges) { | ||
3913 | result = AJAX.post('/app/page-edit/switch-edit-mode?slug=' + pageSlug + '&uploadSlug=' + uploadSlug + successUrlParam, buildDataString()); | ||
3914 | } else { | ||
3915 | window.location.href = 'https://bo.lt/app/page-edit/?slug=' + pageSlug + '&uploadSlug=' + uploadSlug + successUrlParam; | ||
3916 | return; | ||
3917 | } | ||
3918 | ajaxResultProcessor.processSwitchModeResponse(result); | ||
3919 | |||
3920 | overlayBar.enableSwitchSave(true); | ||
3921 | }; | ||
3922 | |||
3923 | buildDataString = function buildDataString() { | ||
3924 | return 'htmlContent=' + encodeURIComponent(editor.getSession().getValue()); | ||
3925 | }; | ||
3926 | |||
3927 | this.activateditor = function activateEditor() { | ||
3928 | overlayBar.show(true); | ||
3929 | }; | ||
3930 | |||
3931 | this.close = function close() { | ||
3932 | //no op for html editor. added to keep the editor interface consistent | ||
3933 | }; | ||
3934 | |||
3935 | this.saveAndClose = function saveAndClose() { | ||
3936 | //no op for html editor. added to keep the editor interface consistent | ||
3937 | }; | ||
3938 | |||
3939 | } | ||
3940 | splashWindow = new SplashWindow(pageEditor); | ||
3941 | splashWindow.createLabels(); | ||
3942 | splashWindow.activate(); | ||
3943 | if (editMode != 'HTML') { | ||
3944 | pageEditor = new VisualPageEditor(); | ||
3945 | pageEditor.show(); | ||
3946 | } | ||
3947 | |||
3948 | var activateEditor = function activateEditor() { | ||
3949 | if (editMode == 'HTML') { | ||
3950 | var editor, htmlMode; | ||
3951 | editor = ace.edit("editor"); | ||
3952 | htmlMode = require("ace/mode/html").Mode; | ||
3953 | editor.setTheme("ace/theme/eclipse"); | ||
3954 | editor.setShowPrintMargin(false); | ||
3955 | editor.getSession().setMode(new htmlMode()); | ||
3956 | editor.getSession().setUseWrapMode(true); | ||
3957 | pageEditor = new HtmlPageEditor(editor); | ||
3958 | } | ||
3959 | pageEditor.activateEditor(); | ||
3960 | if (splashWindow) { | ||
3961 | splashWindow.activate(); | ||
3962 | } | ||
3963 | } | ||
3964 | loadingTimerId = setTimeout(activateEditor, 000); | ||
3965 | UTIL.addEvent(window, 'load', function() { | ||
3966 | clearTimeout(loadingTimerId); | ||
3967 | activateEditor(); | ||
3968 | }); | ||
3969 | |||
3970 | } |