theme asset picker in progress
@ -7,6 +7,10 @@ module Admin
|
||||
assets = current_site.theme_assets.all
|
||||
@non_image_assets = assets.find_all { |a| a.stylesheet? || a.javascript? }
|
||||
@image_assets = assets.find_all { |a| a.image? }
|
||||
|
||||
if request.xhr?
|
||||
render :action => 'images', :layout => false
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@ -18,7 +22,17 @@ module Admin
|
||||
end
|
||||
|
||||
def create
|
||||
@asset = current_site.theme_assets.build(params[:theme_asset])
|
||||
# logger.debug "request = #{request.inspect}"
|
||||
# logger.debug "file size = #{request.env['rack.input'].inspect}"
|
||||
|
||||
# File.cp(request.env['rack.input'], '/Users/didier/Desktop/FOO')
|
||||
|
||||
if params[:file]
|
||||
# params[:theme_asset][:source] = request.env['rack.input']
|
||||
@asset = current_site.theme_assets.build(:source => params[:file])
|
||||
else
|
||||
@asset = current_site.theme_assets.build(params[:theme_asset])
|
||||
end
|
||||
|
||||
if @asset.save
|
||||
flash_success!
|
||||
|
@ -64,6 +64,7 @@ class ThemeAsset
|
||||
|
||||
def filename
|
||||
if not self.image?
|
||||
# TODO: fix that for handling not image / stylesheets / javascripts assets
|
||||
"#{self.slug}.#{self.stylesheet? ? 'css' : 'js'}"
|
||||
else
|
||||
"#{self.slug}#{File.extname(self.source.file.original_filename)}"
|
||||
|
@ -30,6 +30,8 @@ class AssetUploader < CarrierWave::Uploader::Base
|
||||
def set_content_type
|
||||
value = :other
|
||||
|
||||
content_type = File.mime_type?(original_filename) if file.content_type == 'application/octet-stream'
|
||||
|
||||
self.class.content_types.each_pair do |type, rules|
|
||||
rules.each do |rule|
|
||||
case rule
|
||||
|
@ -36,11 +36,13 @@ class ThemeAssetUploader < CarrierWave::Uploader::Base
|
||||
def set_content_type
|
||||
value = :other
|
||||
|
||||
content_type = File.mime_type?(original_filename) if file.content_type == 'application/octet-stream'
|
||||
|
||||
self.class.content_types.each_pair do |type, rules|
|
||||
rules.each do |rule|
|
||||
case rule
|
||||
when String then value = type if file.content_type == rule
|
||||
when Regexp then value = type if (file.content_type =~ rule) == 0
|
||||
when String then value = type if content_type == rule
|
||||
when Regexp then value = type if (content_type =~ rule) == 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
= stylesheet_link_tag 'blueprint/screen', :media => 'screen'
|
||||
/ [if IE]
|
||||
= stylesheet_link_tag('blueprint/ie', :media => 'screen')
|
||||
= stylesheet_link_tag 'blueprint/ie', :media => 'screen'
|
||||
|
||||
= stylesheet_link_tag 'admin/layout', 'admin/plugins/toggle', 'admin/menu', 'admin/buttons', 'admin/formtastic', 'admin/formtastic_changes', 'admin/application', :media => 'screen', :cache => Rails.env.production?
|
||||
|
||||
|
@ -1,7 +1,11 @@
|
||||
%li{ :class => "asset #{'last' if (asset_counter + 1) % 6 == 0}"}
|
||||
%h4= link_to truncate(asset.slug, :length => 22), edit_admin_theme_asset_path(asset)
|
||||
- per_row ||= 6
|
||||
- edit_mode = defined?(edit).nil? ? true: edit
|
||||
|
||||
%li{ :class => "asset #{'last' if (asset_counter + 1) % per_row == 0}"}
|
||||
%h4= link_to truncate(asset.slug, :length => 22), edit_mode ? edit_admin_theme_asset_path(asset) : asset.source.url
|
||||
.image
|
||||
.inside
|
||||
= vignette_tag(asset)
|
||||
.actions
|
||||
= link_to image_tag('admin/list/icons/cross.png'), admin_theme_asset_path(asset), :class => 'remove', :confirm => t('admin.messages.confirm'), :method => :delete
|
||||
- if edit_mode
|
||||
.actions
|
||||
= link_to image_tag('admin/list/icons/cross.png'), admin_theme_asset_path(asset), :class => 'remove', :confirm => t('admin.messages.confirm'), :method => :delete
|
@ -1,5 +1,6 @@
|
||||
- content_for :head do
|
||||
= javascript_include_tag 'admin/plugins/codemirror/codemirror', 'admin/theme_assets.js'
|
||||
= javascript_include_tag 'admin/plugins/codemirror/codemirror', 'admin/plugins/fancybox', 'admin/plugins/plupload/plupload.full.js', 'admin/theme_assets.js'
|
||||
= stylesheet_link_tag 'admin/plugins/fancybox', 'admin/box'
|
||||
|
||||
= f.hidden_field :performing_plain_text
|
||||
|
||||
@ -22,12 +23,14 @@
|
||||
= f.select :content_type, ["stylesheet", "javascript"]
|
||||
|
||||
= f.custom_input :plain_text, :css => 'full', :with_label => false do
|
||||
%code{ :class => (@asset.new_record? || (@asset.size && @asset.size > 40000) ? 'nude' : @asset.content_type) }
|
||||
%code{ :class => (@asset.size && @asset.size > 40000 ? 'nude' : (@asset.content_type || 'stylesheet')) }
|
||||
= f.text_area :plain_text
|
||||
%li.more
|
||||
= link_to t('.picker_link'), admin_theme_assets_path, :id => 'asset-picker-link'
|
||||
|
||||
%span.alt
|
||||
= t('admin.theme_assets.form.choose_file')
|
||||
|
||||
|
||||
- if @asset.image?
|
||||
= f.foldable_inputs :name => "#{t('formtastic.titles.preview')} #{image_dimensions_and_size(@asset)}", :class => 'preview' do
|
||||
%li
|
||||
|
12
app/views/admin/theme_assets/images.html.haml
Normal file
@ -0,0 +1,12 @@
|
||||
#theme-images.asset-picker
|
||||
%h2= t('.title')
|
||||
|
||||
.actions
|
||||
= admin_button_tag t('admin.theme_assets.index.new'), admin_theme_assets_url(:json), :class => 'button small add', :id => 'upload-link'
|
||||
|
||||
- if @image_assets.empty?
|
||||
%p.no-items= t('.no_items')
|
||||
- else
|
||||
%ul.assets
|
||||
= render :partial => 'asset', :collection => @image_assets, :locals => { :per_row => 3, :edit => false }
|
||||
%li.clear
|
@ -29,7 +29,7 @@ module Mongoid #:nodoc:
|
||||
end
|
||||
end
|
||||
|
||||
Rails.logger.debug "conditions = #{conditions.inspect} / #{options[:scope].inspect}"
|
||||
# Rails.logger.debug "conditions = #{conditions.inspect} / #{options[:scope].inspect}"
|
||||
|
||||
return if document.class.where(conditions).empty?
|
||||
|
||||
|
18
doc/TODO
@ -1,16 +1,21 @@
|
||||
BOARD:
|
||||
- theme assets
|
||||
- theme assets picker (???)
|
||||
|
||||
- assets uploader: remove old files if new one
|
||||
x lightbox (http://fancybox.net/api)
|
||||
x select it
|
||||
- flash upload (http://www.plupload.com/example_custom.php)
|
||||
- theme assets: disable version if not image
|
||||
- refactor theme assets / assets uploaders
|
||||
|
||||
BACKLOG:
|
||||
|
||||
- devise messages in French
|
||||
- localize devise emails
|
||||
|
||||
- cucumber features for admin pages
|
||||
- refactoring admin crud (pages + layouts + snippets)
|
||||
|
||||
- icons for mime type
|
||||
|
||||
- new types for custom field
|
||||
- file
|
||||
- boolean
|
||||
@ -18,11 +23,14 @@ BACKLOG:
|
||||
- refactoring: CustomFields::CustomField => CustomFields::Field
|
||||
- optimization custom_fields: use dynamic class for a collection instead of modifying the metaclass each time we build an item
|
||||
|
||||
- deploy on Heroku
|
||||
|
||||
BUGS:
|
||||
- when assigning new layout, disabled parts show up :-( (js problem)
|
||||
|
||||
NICE TO HAVE:
|
||||
- asset collections: custom resizing if image
|
||||
- super_finder
|
||||
|
||||
DONE:
|
||||
x admin layout
|
||||
@ -91,4 +99,6 @@ x liquid rendering engine
|
||||
x contents pagination
|
||||
x how to disable a page part in layout ? (BUG)
|
||||
x non published page (redirect to 404 ?)
|
||||
x refactoring page.rb => create module pagetree
|
||||
x refactoring page.rb => create module pagetree
|
||||
! assets uploader: remove old files if new one (BUG non )
|
||||
x CodeMirror: switch js -> css -> js .... (http://marijn.haverbeke.nl/codemirror/manual.html)
|
@ -3,6 +3,7 @@ require 'locomotive/configuration'
|
||||
require 'locomotive/liquid'
|
||||
require 'locomotive/mongoid'
|
||||
|
||||
|
||||
module Locomotive
|
||||
|
||||
class << self
|
||||
|
@ -1 +1,2 @@
|
||||
require 'locomotive/mongoid/document'
|
||||
require 'locomotive/mongoid/document'
|
||||
require 'locomotive/mongoid/model_extensions'
|
BIN
public/images/admin/plugins/fancybox/blank.gif
Executable file
After Width: | Height: | Size: 43 B |
BIN
public/images/admin/plugins/fancybox/fancy_close.png
Executable file
After Width: | Height: | Size: 1.5 KiB |
BIN
public/images/admin/plugins/fancybox/fancy_loading.png
Executable file
After Width: | Height: | Size: 10 KiB |
BIN
public/images/admin/plugins/fancybox/fancy_nav_left.png
Executable file
After Width: | Height: | Size: 1.4 KiB |
BIN
public/images/admin/plugins/fancybox/fancy_nav_right.png
Executable file
After Width: | Height: | Size: 1.4 KiB |
BIN
public/images/admin/plugins/fancybox/fancy_shadow_e.png
Executable file
After Width: | Height: | Size: 107 B |
BIN
public/images/admin/plugins/fancybox/fancy_shadow_n.png
Executable file
After Width: | Height: | Size: 106 B |
BIN
public/images/admin/plugins/fancybox/fancy_shadow_ne.png
Executable file
After Width: | Height: | Size: 347 B |
BIN
public/images/admin/plugins/fancybox/fancy_shadow_nw.png
Executable file
After Width: | Height: | Size: 324 B |
BIN
public/images/admin/plugins/fancybox/fancy_shadow_s.png
Executable file
After Width: | Height: | Size: 111 B |
BIN
public/images/admin/plugins/fancybox/fancy_shadow_se.png
Executable file
After Width: | Height: | Size: 352 B |
BIN
public/images/admin/plugins/fancybox/fancy_shadow_sw.png
Executable file
After Width: | Height: | Size: 340 B |
BIN
public/images/admin/plugins/fancybox/fancy_shadow_w.png
Executable file
After Width: | Height: | Size: 103 B |
BIN
public/images/admin/plugins/fancybox/fancy_title_left.png
Executable file
After Width: | Height: | Size: 503 B |
BIN
public/images/admin/plugins/fancybox/fancy_title_main.png
Executable file
After Width: | Height: | Size: 96 B |
BIN
public/images/admin/plugins/fancybox/fancy_title_over.png
Executable file
After Width: | Height: | Size: 70 B |
BIN
public/images/admin/plugins/fancybox/fancy_title_right.png
Executable file
After Width: | Height: | Size: 506 B |
BIN
public/images/admin/plugins/fancybox/fancybox-x.png
Executable file
After Width: | Height: | Size: 203 B |
BIN
public/images/admin/plugins/fancybox/fancybox-y.png
Executable file
After Width: | Height: | Size: 176 B |
BIN
public/images/admin/plugins/fancybox/fancybox.png
Executable file
After Width: | Height: | Size: 15 KiB |
@ -21,12 +21,15 @@ $.growl.settings.dockCss = {
|
||||
var addCodeMirrorEditor = function(type, el, parser) {
|
||||
var parserfile = "parse" + type + ".js";
|
||||
if (parser != undefined) parserfile = parser;
|
||||
if (type == 'liquid') type = 'xml';
|
||||
// if (type == 'liquid') type = 'xml';
|
||||
|
||||
var editor = CodeMirror.fromTextArea(el.attr('id'), {
|
||||
height: "400px",
|
||||
parserfile: parserfile,
|
||||
stylesheet: ["/stylesheets/admin/plugins/codemirror/" + type + "colors.css", "/stylesheets/admin/plugins/codemirror/liquidcolors.css"],
|
||||
stylesheet: [
|
||||
"/stylesheets/admin/plugins/codemirror/csscolors.css",
|
||||
"/stylesheets/admin/plugins/codemirror/javascriptcolors.css",
|
||||
"/stylesheets/admin/plugins/codemirror/liquidcolors.css"],
|
||||
path: "/javascripts/admin/plugins/codemirror/",
|
||||
continuousScanning: 500,
|
||||
reindentOnLoad: true,
|
||||
|
@ -33,6 +33,8 @@ var CodeMirror = (function(){
|
||||
iframeClass: null,
|
||||
passDelay: 200,
|
||||
passTime: 50,
|
||||
lineNumberDelay: 200,
|
||||
lineNumberTime: 50,
|
||||
continuousScanning: false,
|
||||
saveFunction: null,
|
||||
onChange: null,
|
||||
@ -41,7 +43,7 @@ var CodeMirror = (function(){
|
||||
disableSpellcheck: true,
|
||||
textWrapping: true,
|
||||
readOnly: false,
|
||||
width: "100%",
|
||||
width: "",
|
||||
height: "300px",
|
||||
autoMatchParens: false,
|
||||
parserConfig: null,
|
||||
@ -50,67 +52,49 @@ var CodeMirror = (function(){
|
||||
activeTokens: null,
|
||||
cursorActivity: null,
|
||||
lineNumbers: false,
|
||||
indentUnit: 2
|
||||
indentUnit: 2,
|
||||
domain: null
|
||||
});
|
||||
|
||||
function wrapLineNumberDiv(place) {
|
||||
return function(node) {
|
||||
var container = document.createElement("DIV"),
|
||||
nums = document.createElement("DIV"),
|
||||
scroller = document.createElement("DIV");
|
||||
container.style.position = "relative";
|
||||
nums.style.position = "absolute";
|
||||
nums.style.height = "100%";
|
||||
if (nums.style.setExpression) {
|
||||
try {nums.style.setExpression("height", "this.previousSibling.offsetHeight + 'px'");}
|
||||
catch(e) {} // Seems to throw 'Not Implemented' on some IE8 versions
|
||||
}
|
||||
nums.style.top = "0px";
|
||||
nums.style.overflow = "hidden";
|
||||
place(container);
|
||||
container.appendChild(node);
|
||||
container.appendChild(nums);
|
||||
scroller.className = "CodeMirror-line-numbers";
|
||||
nums.appendChild(scroller);
|
||||
function addLineNumberDiv(container) {
|
||||
var nums = document.createElement("DIV"),
|
||||
scroller = document.createElement("DIV");
|
||||
nums.style.position = "absolute";
|
||||
nums.style.height = "100%";
|
||||
if (nums.style.setExpression) {
|
||||
try {nums.style.setExpression("height", "this.previousSibling.offsetHeight + 'px'");}
|
||||
catch(e) {} // Seems to throw 'Not Implemented' on some IE8 versions
|
||||
}
|
||||
nums.style.top = "0px";
|
||||
nums.style.overflow = "hidden";
|
||||
container.appendChild(nums);
|
||||
scroller.className = "CodeMirror-line-numbers";
|
||||
nums.appendChild(scroller);
|
||||
return nums;
|
||||
}
|
||||
|
||||
function applyLineNumbers(frame) {
|
||||
var win = frame.contentWindow, doc = win.document,
|
||||
nums = frame.nextSibling, scroller = nums.firstChild;
|
||||
function frameHTML(options) {
|
||||
if (typeof options.parserfile == "string")
|
||||
options.parserfile = [options.parserfile];
|
||||
if (typeof options.stylesheet == "string")
|
||||
options.stylesheet = [options.stylesheet];
|
||||
|
||||
var nextNum = 1, barWidth = null;
|
||||
function sizeBar() {
|
||||
if (!frame.offsetWidth || !win.Editor) {
|
||||
for (var cur = frame; cur.parentNode; cur = cur.parentNode) {
|
||||
if (cur != document) {
|
||||
clearInterval(sizeInterval);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nums.offsetWidth != barWidth) {
|
||||
barWidth = nums.offsetWidth;
|
||||
nums.style.left = "-" + (frame.parentNode.style.marginLeft = barWidth + "px");
|
||||
}
|
||||
}
|
||||
function update() {
|
||||
var diff = 20 + Math.max(doc.body.offsetHeight, frame.offsetHeight) - scroller.offsetHeight;
|
||||
for (var n = Math.ceil(diff / 10); n > 0; n--) {
|
||||
var div = document.createElement("DIV");
|
||||
div.appendChild(document.createTextNode(nextNum++));
|
||||
scroller.appendChild(div);
|
||||
}
|
||||
nums.scrollTop = doc.body.scrollTop || doc.documentElement.scrollTop || 0;
|
||||
}
|
||||
sizeBar();
|
||||
update();
|
||||
win.addEventHandler(win, "scroll", update);
|
||||
win.addEventHandler(win, "resize", update);
|
||||
var sizeInterval = setInterval(sizeBar, 500);
|
||||
var html = ["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\"><html><head>"];
|
||||
// Hack to work around a bunch of IE8-specific problems.
|
||||
html.push("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=EmulateIE7\"/>");
|
||||
forEach(options.stylesheet, function(file) {
|
||||
html.push("<link rel=\"stylesheet\" type=\"text/css\" href=\"" + file + "\"/>");
|
||||
});
|
||||
forEach(options.basefiles.concat(options.parserfile), function(file) {
|
||||
html.push("<script type=\"text/javascript\" src=\"" + options.path + file + "\"><" + "/script>");
|
||||
});
|
||||
html.push("</head><body style=\"border-width: 0;\" class=\"editbox\" spellcheck=\"" +
|
||||
(options.disableSpellcheck ? "false" : "true") + "\"></body></html>");
|
||||
return html.join("");
|
||||
}
|
||||
|
||||
var internetExplorer = document.selection && window.ActiveXObject && /MSIE/.test(navigator.userAgent);
|
||||
|
||||
function CodeMirror(place, options) {
|
||||
// Backward compatibility for deprecated options.
|
||||
if (options.dumbTabs) options.tabMode = "spaces";
|
||||
@ -123,66 +107,72 @@ var CodeMirror = (function(){
|
||||
var frame = this.frame = document.createElement("IFRAME");
|
||||
if (options.iframeClass) frame.className = options.iframeClass;
|
||||
frame.frameBorder = 0;
|
||||
frame.src = "javascript:false;";
|
||||
frame.style.border = "0";
|
||||
frame.style.width = options.width;
|
||||
frame.style.height = options.height;
|
||||
frame.style.width = '100%';
|
||||
frame.style.height = '100%';
|
||||
// display: block occasionally suppresses some Firefox bugs, so we
|
||||
// always add it, redundant as it sounds.
|
||||
frame.style.display = "block";
|
||||
|
||||
if (place.appendChild) {
|
||||
var node = place;
|
||||
place = function(n){node.appendChild(n);};
|
||||
}
|
||||
if (options.lineNumbers) place = wrapLineNumberDiv(place);
|
||||
place(frame);
|
||||
var div = this.wrapping = document.createElement("DIV");
|
||||
div.style.position = "relative";
|
||||
div.className = "CodeMirror-wrapping";
|
||||
div.style.width = options.width;
|
||||
div.style.height = options.height;
|
||||
// This is used by Editor.reroutePasteEvent
|
||||
var teHack = this.textareaHack = document.createElement("TEXTAREA");
|
||||
div.appendChild(teHack);
|
||||
teHack.style.position = "absolute";
|
||||
teHack.style.left = "-10000px";
|
||||
teHack.style.width = "10px";
|
||||
|
||||
// Link back to this object, so that the editor can fetch options
|
||||
// and add a reference to itself.
|
||||
frame.CodeMirror = this;
|
||||
if (options.domain && internetExplorer) {
|
||||
this.html = frameHTML(options);
|
||||
frame.src = "javascript:(function(){document.open();" +
|
||||
(options.domain ? "document.domain=\"" + options.domain + "\";" : "") +
|
||||
"document.write(window.frameElement.CodeMirror.html);document.close();})()";
|
||||
}
|
||||
else {
|
||||
frame.src = "javascript:false";
|
||||
}
|
||||
|
||||
if (place.appendChild) place.appendChild(div);
|
||||
else place(div);
|
||||
div.appendChild(frame);
|
||||
if (options.lineNumbers) this.lineNumbers = addLineNumberDiv(div);
|
||||
|
||||
this.win = frame.contentWindow;
|
||||
|
||||
if (typeof options.parserfile == "string")
|
||||
options.parserfile = [options.parserfile];
|
||||
if (typeof options.stylesheet == "string")
|
||||
options.stylesheet = [options.stylesheet];
|
||||
|
||||
var html = ["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\"><html><head>"];
|
||||
// Hack to work around a bunch of IE8-specific problems.
|
||||
html.push("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=EmulateIE7\"/>");
|
||||
forEach(options.stylesheet, function(file) {
|
||||
html.push("<link rel=\"stylesheet\" type=\"text/css\" href=\"" + file + "\"/>");
|
||||
});
|
||||
forEach(options.basefiles.concat(options.parserfile), function(file) {
|
||||
html.push("<script type=\"text/javascript\" src=\"" + options.path + file + "\"></script>");
|
||||
});
|
||||
html.push("</head><body style=\"border-width: 0;\" class=\"editbox\" spellcheck=\"" +
|
||||
(options.disableSpellcheck ? "false" : "true") + "\"></body></html>");
|
||||
|
||||
var doc = this.win.document;
|
||||
doc.open();
|
||||
doc.write(html.join(""));
|
||||
doc.close();
|
||||
if (!options.domain || !internetExplorer) {
|
||||
this.win.document.open();
|
||||
this.win.document.write(frameHTML(options));
|
||||
this.win.document.close();
|
||||
}
|
||||
}
|
||||
|
||||
CodeMirror.prototype = {
|
||||
init: function() {
|
||||
if (this.options.initCallback) this.options.initCallback(this);
|
||||
if (this.options.lineNumbers) applyLineNumbers(this.frame);
|
||||
if (this.options.lineNumbers) this.activateLineNumbers();
|
||||
if (this.options.reindentOnLoad) this.reindent();
|
||||
},
|
||||
|
||||
getCode: function() {return this.editor.getCode();},
|
||||
setCode: function(code) {this.editor.importCode(code);},
|
||||
selection: function() {return this.editor.selectedText();},
|
||||
selection: function() {this.focusIfIE(); return this.editor.selectedText();},
|
||||
reindent: function() {this.editor.reindent();},
|
||||
reindentSelection: function() {this.editor.reindentSelection(null);},
|
||||
reindentSelection: function() {this.focusIfIE(); this.editor.reindentSelection(null);},
|
||||
|
||||
focusIfIE: function() {
|
||||
// in IE, a lot of selection-related functionality only works when the frame is focused
|
||||
if (this.win.select.ie_selection) this.focus();
|
||||
},
|
||||
focus: function() {
|
||||
this.win.focus();
|
||||
if (this.editor.selectionSnapshot) // IE hack
|
||||
this.win.select.selectCoords(this.win, this.editor.selectionSnapshot);
|
||||
this.win.select.setBookmark(this.win.document.body, this.editor.selectionSnapshot);
|
||||
},
|
||||
replaceSelection: function(text) {
|
||||
this.focus();
|
||||
@ -192,8 +182,8 @@ var CodeMirror = (function(){
|
||||
replaceChars: function(text, start, end) {
|
||||
this.editor.replaceChars(text, start, end);
|
||||
},
|
||||
getSearchCursor: function(string, fromCursor) {
|
||||
return this.editor.getSearchCursor(string, fromCursor);
|
||||
getSearchCursor: function(string, fromCursor, caseFold) {
|
||||
return this.editor.getSearchCursor(string, fromCursor, caseFold);
|
||||
},
|
||||
|
||||
undo: function() {this.editor.history.undo();},
|
||||
@ -204,18 +194,76 @@ var CodeMirror = (function(){
|
||||
grabKeys: function(callback, filter) {this.editor.grabKeys(callback, filter);},
|
||||
ungrabKeys: function() {this.editor.ungrabKeys();},
|
||||
|
||||
setParser: function(name) {this.editor.setParser(name);},
|
||||
|
||||
cursorPosition: function(start) {
|
||||
if (this.win.select.ie_selection) this.focus();
|
||||
return this.editor.cursorPosition(start);
|
||||
setParser: function(name) { this.editor.setParser(name); },
|
||||
setSpellcheck: function(on) {this.win.document.body.spellcheck = on;},
|
||||
setStylesheet: function(names) {
|
||||
if (typeof names === "string") names = [names];
|
||||
var activeStylesheets = {};
|
||||
var matchedNames = {};
|
||||
var links = this.win.document.getElementsByTagName("link");
|
||||
// Create hashes of active stylesheets and matched names.
|
||||
// This is O(n^2) but n is expected to be very small.
|
||||
for (var x = 0, link; link = links[x]; x++) {
|
||||
if (link.rel.indexOf("stylesheet") !== -1) {
|
||||
for (var y = 0; y < names.length; y++) {
|
||||
var name = names[y];
|
||||
if (link.href.substring(link.href.length - name.length) === name) {
|
||||
activeStylesheets[link.href] = true;
|
||||
matchedNames[name] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Activate the selected stylesheets and disable the rest.
|
||||
for (var x = 0, link; link = links[x]; x++) {
|
||||
if (link.rel.indexOf("stylesheet") !== -1) {
|
||||
link.disabled = !(link.href in activeStylesheets);
|
||||
}
|
||||
}
|
||||
// Create any new stylesheets.
|
||||
for (var y = 0; y < names.length; y++) {
|
||||
var name = names[y];
|
||||
if (!(name in matchedNames)) {
|
||||
var link = this.win.document.createElement("link");
|
||||
link.rel = "stylesheet";
|
||||
link.type = "text/css";
|
||||
link.href = name;
|
||||
this.win.document.getElementsByTagName('head')[0].appendChild(link);
|
||||
}
|
||||
}
|
||||
},
|
||||
setTextWrapping: function(on) {
|
||||
if (on == this.options.textWrapping) return;
|
||||
this.win.document.body.style.whiteSpace = on ? "" : "nowrap";
|
||||
this.options.textWrapping = on;
|
||||
if (this.lineNumbers) {
|
||||
this.setLineNumbers(false);
|
||||
this.setLineNumbers(true);
|
||||
}
|
||||
},
|
||||
setIndentUnit: function(unit) {this.win.indentUnit = unit;},
|
||||
setUndoDepth: function(depth) {this.editor.history.maxDepth = depth;},
|
||||
setTabMode: function(mode) {this.options.tabMode = mode;},
|
||||
setLineNumbers: function(on) {
|
||||
if (on && !this.lineNumbers) {
|
||||
this.lineNumbers = addLineNumberDiv(this.wrapping);
|
||||
this.activateLineNumbers();
|
||||
}
|
||||
else if (!on && this.lineNumbers) {
|
||||
this.wrapping.removeChild(this.lineNumbers);
|
||||
this.wrapping.style.marginLeft = "";
|
||||
this.lineNumbers = null;
|
||||
}
|
||||
},
|
||||
|
||||
cursorPosition: function(start) {this.focusIfIE(); return this.editor.cursorPosition(start);},
|
||||
firstLine: function() {return this.editor.firstLine();},
|
||||
lastLine: function() {return this.editor.lastLine();},
|
||||
nextLine: function(line) {return this.editor.nextLine(line);},
|
||||
prevLine: function(line) {return this.editor.prevLine(line);},
|
||||
lineContent: function(line) {return this.editor.lineContent(line);},
|
||||
setLineContent: function(line, content) {this.editor.setLineContent(line, content);},
|
||||
removeLine: function(line){this.editor.removeLine(line);},
|
||||
insertIntoLine: function(line, position, content) {this.editor.insertIntoLine(line, position, content);},
|
||||
selectLines: function(startLine, startOffset, endLine, endOffset) {
|
||||
this.win.focus();
|
||||
@ -235,14 +283,125 @@ var CodeMirror = (function(){
|
||||
}
|
||||
return num;
|
||||
},
|
||||
|
||||
// Old number-based line interface
|
||||
jumpToLine: function(n) {
|
||||
this.selectLines(this.nthLine(n), 0);
|
||||
jumpToLine: function(line) {
|
||||
if (typeof line == "number") line = this.nthLine(line);
|
||||
this.selectLines(line, 0);
|
||||
this.win.focus();
|
||||
},
|
||||
currentLine: function() {
|
||||
return this.lineNumber(this.cursorPosition().line);
|
||||
currentLine: function() { // Deprecated, but still there for backward compatibility
|
||||
return this.lineNumber(this.cursorLine());
|
||||
},
|
||||
cursorLine: function() {
|
||||
return this.cursorPosition().line;
|
||||
},
|
||||
|
||||
activateLineNumbers: function() {
|
||||
var frame = this.frame, win = frame.contentWindow, doc = win.document, body = doc.body,
|
||||
nums = this.lineNumbers, scroller = nums.firstChild, self = this;
|
||||
var barWidth = null;
|
||||
|
||||
function sizeBar() {
|
||||
if (frame.offsetWidth == 0) return;
|
||||
for (var root = frame; root.parentNode; root = root.parentNode);
|
||||
if (!nums.parentNode || root != document || !win.Editor) {
|
||||
// Clear event handlers (their nodes might already be collected, so try/catch)
|
||||
try{clear();}catch(e){}
|
||||
clearInterval(sizeInterval);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nums.offsetWidth != barWidth) {
|
||||
barWidth = nums.offsetWidth;
|
||||
nums.style.left = "-" + (frame.parentNode.style.marginLeft = barWidth + "px");
|
||||
}
|
||||
}
|
||||
function doScroll() {
|
||||
nums.scrollTop = body.scrollTop || doc.documentElement.scrollTop || 0;
|
||||
}
|
||||
// Cleanup function, registered by nonWrapping and wrapping.
|
||||
var clear = function(){};
|
||||
sizeBar();
|
||||
var sizeInterval = setInterval(sizeBar, 500);
|
||||
|
||||
function nonWrapping() {
|
||||
var nextNum = 1, pending;
|
||||
function update() {
|
||||
var target = 50 + Math.max(body.offsetHeight, Math.max(frame.offsetHeight, body.scrollHeight || 0));
|
||||
var endTime = new Date().getTime() + self.options.lineNumberTime;
|
||||
while (scroller.offsetHeight < target && (!scroller.firstChild || scroller.offsetHeight)) {
|
||||
scroller.appendChild(document.createElement("DIV"));
|
||||
scroller.lastChild.innerHTML = nextNum++;
|
||||
if (new Date().getTime() > endTime) {
|
||||
if (pending) clearTimeout(pending);
|
||||
pending = setTimeout(update, self.options.lineNumberDelay);
|
||||
break;
|
||||
}
|
||||
}
|
||||
doScroll();
|
||||
}
|
||||
var onScroll = win.addEventHandler(win, "scroll", update, true),
|
||||
onResize = win.addEventHandler(win, "resize", update, true);
|
||||
clear = function(){onScroll(); onResize(); if (pending) clearTimeout(pending);};
|
||||
update();
|
||||
}
|
||||
function wrapping() {
|
||||
var node, lineNum, next, pos;
|
||||
|
||||
function addNum(n) {
|
||||
if (!lineNum) lineNum = scroller.appendChild(document.createElement("DIV"));
|
||||
lineNum.innerHTML = n;
|
||||
pos = lineNum.offsetHeight + lineNum.offsetTop;
|
||||
lineNum = lineNum.nextSibling;
|
||||
}
|
||||
function work() {
|
||||
if (!scroller.parentNode || scroller.parentNode != self.lineNumbers) return;
|
||||
|
||||
var endTime = new Date().getTime() + self.options.lineNumberTime;
|
||||
while (node) {
|
||||
addNum(next++);
|
||||
for (; node && !win.isBR(node); node = node.nextSibling) {
|
||||
var bott = node.offsetTop + node.offsetHeight;
|
||||
while (scroller.offsetHeight && bott - 3 > pos) addNum(" ");
|
||||
}
|
||||
if (node) node = node.nextSibling;
|
||||
if (new Date().getTime() > endTime) {
|
||||
pending = setTimeout(work, self.options.lineNumberDelay);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// While there are un-processed number DIVs, or the scroller is smaller than the frame...
|
||||
var target = 50 + Math.max(body.offsetHeight, Math.max(frame.offsetHeight, body.scrollHeight || 0));
|
||||
while (lineNum || (scroller.offsetHeight < target && (!scroller.firstChild || scroller.offsetHeight)))
|
||||
addNum(next++);
|
||||
doScroll();
|
||||
}
|
||||
function start() {
|
||||
doScroll();
|
||||
node = body.firstChild;
|
||||
lineNum = scroller.firstChild;
|
||||
pos = 0;
|
||||
next = 1;
|
||||
work();
|
||||
}
|
||||
|
||||
start();
|
||||
var pending = null;
|
||||
function update() {
|
||||
if (pending) clearTimeout(pending);
|
||||
if (self.editor.allClean()) start();
|
||||
else pending = setTimeout(update, 200);
|
||||
}
|
||||
self.updateNumbers = update;
|
||||
var onScroll = win.addEventHandler(win, "scroll", doScroll, true),
|
||||
onResize = win.addEventHandler(win, "resize", update, true);
|
||||
clear = function(){
|
||||
if (pending) clearTimeout(pending);
|
||||
if (self.updateNumbers == update) self.updateNumbers = null;
|
||||
onScroll();
|
||||
onResize();
|
||||
};
|
||||
}
|
||||
(this.options.textWrapping ? wrapping : nonWrapping)();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -4,6 +4,11 @@
|
||||
* plain sequences of <span> and <br> elements
|
||||
*/
|
||||
|
||||
var internetExplorer = document.selection && window.ActiveXObject && /MSIE/.test(navigator.userAgent);
|
||||
var webkit = /AppleWebKit/.test(navigator.userAgent);
|
||||
var safari = /Apple Computers, Inc/.test(navigator.vendor);
|
||||
var gecko = /gecko\/(\d{8})/i.test(navigator.userAgent);
|
||||
|
||||
// Make sure a string does not contain two consecutive 'collapseable'
|
||||
// whitespace characters.
|
||||
function makeWhiteSpace(n) {
|
||||
@ -80,13 +85,13 @@ var Editor = (function(){
|
||||
if (text.length) leaving = false;
|
||||
result.push(node);
|
||||
}
|
||||
else if (node.nodeName == "BR" && node.childNodes.length == 0) {
|
||||
else if (isBR(node) && node.childNodes.length == 0) {
|
||||
leaving = true;
|
||||
result.push(node);
|
||||
}
|
||||
else {
|
||||
forEach(node.childNodes, simplifyNode);
|
||||
if (!leaving && newlineElements.hasOwnProperty(node.nodeName)) {
|
||||
if (!leaving && newlineElements.hasOwnProperty(node.nodeName.toUpperCase())) {
|
||||
leaving = true;
|
||||
if (!atEnd || !top)
|
||||
result.push(doc.createElement("BR"));
|
||||
@ -106,7 +111,7 @@ var Editor = (function(){
|
||||
// See the story.html file for some short remarks about the use of
|
||||
// continuation-passing style in this iterator.
|
||||
function traverseDOM(start){
|
||||
function yield(value, c){cc = c; return value;}
|
||||
function _yield(value, c){cc = c; return value;}
|
||||
function push(fun, arg, c){return function(){return fun(arg, c);};}
|
||||
function stop(){cc = stop; throw StopIteration;};
|
||||
var cc = push(scanNode, start, stop);
|
||||
@ -124,6 +129,11 @@ var Editor = (function(){
|
||||
}
|
||||
var point = null;
|
||||
|
||||
// This an Opera-specific hack -- always insert an empty span
|
||||
// between two BRs, because Opera's cursor code gets terribly
|
||||
// confused when the cursor is between two BRs.
|
||||
var afterBR = true;
|
||||
|
||||
// Insert a normalized node at the current point. If it is a text
|
||||
// node, wrap it in a <span>, and give that span a currentText
|
||||
// property -- this is used to cache the nodeValue, because
|
||||
@ -136,6 +146,12 @@ var Editor = (function(){
|
||||
select.snapshotChanged();
|
||||
part = makePartSpan(part, owner);
|
||||
text = part.currentText;
|
||||
afterBR = false;
|
||||
}
|
||||
else {
|
||||
if (afterBR && window.opera)
|
||||
point(makePartSpan("", owner));
|
||||
afterBR = true;
|
||||
}
|
||||
part.dirty = true;
|
||||
nodeQueue.push(part);
|
||||
@ -151,7 +167,7 @@ var Editor = (function(){
|
||||
forEach(simplifyDOM(node, end), function(part) {
|
||||
toYield.push(insertPart(part));
|
||||
});
|
||||
return yield(toYield.join(""), c);
|
||||
return _yield(toYield.join(""), c);
|
||||
}
|
||||
|
||||
// Check whether a node is a normalized <span> element.
|
||||
@ -173,11 +189,15 @@ var Editor = (function(){
|
||||
|
||||
if (partNode(node)){
|
||||
nodeQueue.push(node);
|
||||
return yield(node.currentText, c);
|
||||
afterBR = false;
|
||||
return _yield(node.currentText, c);
|
||||
}
|
||||
else if (node.nodeName == "BR") {
|
||||
else if (isBR(node)) {
|
||||
if (afterBR && window.opera)
|
||||
node.parentNode.insertBefore(makePartSpan("", owner), node);
|
||||
nodeQueue.push(node);
|
||||
return yield("\n", c);
|
||||
afterBR = true;
|
||||
return _yield("\n", c);
|
||||
}
|
||||
else {
|
||||
var end = !node.nextSibling;
|
||||
@ -195,23 +215,20 @@ var Editor = (function(){
|
||||
|
||||
// Determine the text size of a processed node.
|
||||
function nodeSize(node) {
|
||||
if (node.nodeName == "BR")
|
||||
return 1;
|
||||
else
|
||||
return node.currentText.length;
|
||||
return isBR(node) ? 1 : node.currentText.length;
|
||||
}
|
||||
|
||||
// Search backwards through the top-level nodes until the next BR or
|
||||
// the start of the frame.
|
||||
function startOfLine(node) {
|
||||
while (node && node.nodeName != "BR") node = node.previousSibling;
|
||||
while (node && !isBR(node)) node = node.previousSibling;
|
||||
return node;
|
||||
}
|
||||
function endOfLine(node, container) {
|
||||
if (!node) node = container.firstChild;
|
||||
else if (node.nodeName == "BR") node = node.nextSibling;
|
||||
else if (isBR(node)) node = node.nextSibling;
|
||||
|
||||
while (node && node.nodeName != "BR") node = node.nextSibling;
|
||||
while (node && !isBR(node)) node = node.nextSibling;
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -223,8 +240,10 @@ var Editor = (function(){
|
||||
// indicating whether anything was found, and can be called again to
|
||||
// skip to the next find. Use the select and replace methods to
|
||||
// actually do something with the found locations.
|
||||
function SearchCursor(editor, string, fromCursor) {
|
||||
function SearchCursor(editor, string, fromCursor, caseFold) {
|
||||
this.editor = editor;
|
||||
this.caseFold = caseFold;
|
||||
if (caseFold) string = string.toLowerCase();
|
||||
this.history = editor.history;
|
||||
this.history.commit();
|
||||
|
||||
@ -252,7 +271,8 @@ var Editor = (function(){
|
||||
// For one-line strings, searching can be done simply by calling
|
||||
// indexOf on the current line.
|
||||
function() {
|
||||
var match = cleanText(self.history.textAfter(self.line).slice(self.offset)).indexOf(string);
|
||||
var line = cleanText(self.history.textAfter(self.line).slice(self.offset));
|
||||
var match = (self.caseFold ? line.toLowerCase() : line).indexOf(string);
|
||||
if (match > -1)
|
||||
return {from: {node: self.line, offset: self.offset + match},
|
||||
to: {node: self.line, offset: self.offset + match + string.length}};
|
||||
@ -262,19 +282,21 @@ var Editor = (function(){
|
||||
// end of the line and the last match starts at the start.
|
||||
function() {
|
||||
var firstLine = cleanText(self.history.textAfter(self.line).slice(self.offset));
|
||||
var match = firstLine.lastIndexOf(target[0]);
|
||||
var match = (self.caseFold ? firstLine.toLowerCase() : firstLine).lastIndexOf(target[0]);
|
||||
if (match == -1 || match != firstLine.length - target[0].length)
|
||||
return false;
|
||||
var startOffset = self.offset + match;
|
||||
|
||||
var line = self.history.nodeAfter(self.line);
|
||||
for (var i = 1; i < target.length - 1; i++) {
|
||||
if (cleanText(self.history.textAfter(line)) != target[i])
|
||||
var lineText = cleanText(self.history.textAfter(line));
|
||||
if ((self.caseFold ? lineText.toLowerCase() : lineText) != target[i])
|
||||
return false;
|
||||
line = self.history.nodeAfter(line);
|
||||
}
|
||||
|
||||
if (cleanText(self.history.textAfter(line)).indexOf(target[target.length - 1]) != 0)
|
||||
var lastLine = cleanText(self.history.textAfter(line));
|
||||
if ((self.caseFold ? lastLine.toLowerCase() : lastLine).indexOf(target[target.length - 1]) != 0)
|
||||
return false;
|
||||
|
||||
return {from: {node: self.line, offset: startOffset},
|
||||
@ -351,8 +373,7 @@ var Editor = (function(){
|
||||
this.doc = document;
|
||||
var container = this.container = this.doc.body;
|
||||
this.win = window;
|
||||
this.history = new History(container, options.undoDepth, options.undoDelay,
|
||||
this, options.onChange);
|
||||
this.history = new History(container, options.undoDepth, options.undoDelay, this);
|
||||
var self = this;
|
||||
|
||||
if (!Editor.Parser)
|
||||
@ -364,10 +385,8 @@ var Editor = (function(){
|
||||
select.setCursorPos(container, {node: null, offset: 0});
|
||||
|
||||
this.dirty = [];
|
||||
if (options.content)
|
||||
this.importCode(options.content);
|
||||
else // FF acts weird when the editable document is completely empty
|
||||
container.appendChild(this.doc.createElement("BR"));
|
||||
this.importCode(options.content || "");
|
||||
this.history.onChange = options.onChange;
|
||||
|
||||
if (!options.readOnly) {
|
||||
if (options.continuousScanning !== false) {
|
||||
@ -409,6 +428,11 @@ var Editor = (function(){
|
||||
addEventHandler(document.body, "mouseup", cursorActivity);
|
||||
addEventHandler(document.body, "cut", cursorActivity);
|
||||
|
||||
// workaround for a gecko bug [?] where going forward and then
|
||||
// back again breaks designmode (no more cursor)
|
||||
if (gecko)
|
||||
addEventHandler(this.win, "pagehide", function(){self.unloaded = true;});
|
||||
|
||||
addEventHandler(document.body, "paste", function(event) {
|
||||
cursorActivity();
|
||||
var text = null;
|
||||
@ -418,15 +442,14 @@ var Editor = (function(){
|
||||
}
|
||||
catch(e) {}
|
||||
if (text !== null) {
|
||||
self.replaceSelection(text);
|
||||
event.stop();
|
||||
self.replaceSelection(text);
|
||||
select.scrollToCursor(self.container);
|
||||
}
|
||||
});
|
||||
|
||||
addEventHandler(document.body, "beforepaste", method(this, "reroutePasteEvent"));
|
||||
|
||||
if (this.options.autoMatchParens)
|
||||
addEventHandler(document.body, "click", method(this, "scheduleParenBlink"));
|
||||
addEventHandler(document.body, "click", method(this, "scheduleParenHighlight"));
|
||||
}
|
||||
else if (!options.textWrapping) {
|
||||
container.style.whiteSpace = "nowrap";
|
||||
@ -491,6 +514,16 @@ var Editor = (function(){
|
||||
return startOfLine(line.previousSibling);
|
||||
},
|
||||
|
||||
visibleLineCount: function() {
|
||||
var line = this.container.firstChild;
|
||||
while (line && isBR(line)) line = line.nextSibling; // BR heights are unreliable
|
||||
if (!line) return false;
|
||||
var innerHeight = (window.innerHeight
|
||||
|| document.documentElement.clientHeight
|
||||
|| document.body.clientHeight);
|
||||
return Math.floor(innerHeight / line.offsetHeight);
|
||||
},
|
||||
|
||||
selectLines: function(startLine, startOffset, endLine, endOffset) {
|
||||
this.checkLine(startLine);
|
||||
var start = {node: startLine, offset: startOffset}, end = null;
|
||||
@ -503,10 +536,9 @@ var Editor = (function(){
|
||||
},
|
||||
|
||||
lineContent: function(line) {
|
||||
this.checkLine(line);
|
||||
var accum = [];
|
||||
for (line = line ? line.nextSibling : this.container.firstChild;
|
||||
line && line.nodeName != "BR"; line = line.nextSibling)
|
||||
line && !isBR(line); line = line.nextSibling)
|
||||
accum.push(nodeText(line));
|
||||
return cleanText(accum.join(""));
|
||||
},
|
||||
@ -520,6 +552,18 @@ var Editor = (function(){
|
||||
this.scheduleHighlight();
|
||||
},
|
||||
|
||||
removeLine: function(line) {
|
||||
var node = line ? line.nextSibling : this.container.firstChild;
|
||||
while (node) {
|
||||
var next = node.nextSibling;
|
||||
removeElement(node);
|
||||
if (isBR(node)) break;
|
||||
node = next;
|
||||
}
|
||||
this.addDirtyNode(line);
|
||||
this.scheduleHighlight();
|
||||
},
|
||||
|
||||
insertIntoLine: function(line, position, content) {
|
||||
var before = null;
|
||||
if (position == "end") {
|
||||
@ -531,7 +575,7 @@ var Editor = (function(){
|
||||
before = cur;
|
||||
break;
|
||||
}
|
||||
var text = (cur.innerText || cur.textContent || cur.nodeValue || "");
|
||||
var text = nodeText(cur);
|
||||
if (text.length > position) {
|
||||
before = cur.nextSibling;
|
||||
content = text.slice(0, position) + content + text.slice(position);
|
||||
@ -586,13 +630,9 @@ var Editor = (function(){
|
||||
reroutePasteEvent: function() {
|
||||
if (this.capturingPaste || window.opera) return;
|
||||
this.capturingPaste = true;
|
||||
var te = parent.document.createElement("TEXTAREA");
|
||||
te.style.position = "absolute";
|
||||
te.style.left = "-500px";
|
||||
te.style.width = "10px";
|
||||
te.style.top = nodeTop(frameElement) + "px";
|
||||
parent.document.body.appendChild(te);
|
||||
var te = window.frameElement.CodeMirror.textareaHack;
|
||||
parent.focus();
|
||||
te.value = "";
|
||||
te.focus();
|
||||
|
||||
var self = this;
|
||||
@ -600,10 +640,12 @@ var Editor = (function(){
|
||||
self.capturingPaste = false;
|
||||
self.win.focus();
|
||||
if (self.selectionSnapshot) // IE hack
|
||||
self.win.select.selectCoords(self.win, self.selectionSnapshot);
|
||||
self.win.select.setBookmark(self.container, self.selectionSnapshot);
|
||||
var text = te.value;
|
||||
if (text) self.replaceSelection(text);
|
||||
removeElement(te);
|
||||
if (text) {
|
||||
self.replaceSelection(text);
|
||||
select.scrollToCursor(self.container);
|
||||
}
|
||||
}, 10);
|
||||
},
|
||||
|
||||
@ -618,8 +660,8 @@ var Editor = (function(){
|
||||
offset: lastLine.length};
|
||||
},
|
||||
|
||||
getSearchCursor: function(string, fromCursor) {
|
||||
return new SearchCursor(this, string, fromCursor);
|
||||
getSearchCursor: function(string, fromCursor, caseFold) {
|
||||
return new SearchCursor(this, string, fromCursor, caseFold);
|
||||
},
|
||||
|
||||
// Re-indent the whole buffer
|
||||
@ -655,7 +697,7 @@ var Editor = (function(){
|
||||
forEach(this.container.childNodes, function(n) {
|
||||
if (n.nodeType != 3) n.dirty = true;
|
||||
});
|
||||
this.addDirtyNode(this.firstChild);
|
||||
this.addDirtyNode(this.container.firstChild);
|
||||
this.scheduleHighlight();
|
||||
}
|
||||
},
|
||||
@ -663,7 +705,7 @@ var Editor = (function(){
|
||||
// Intercept enter and tab, and assign their new functions.
|
||||
keyDown: function(event) {
|
||||
if (this.frozen == "leave") this.frozen = null;
|
||||
if (this.frozen && (!this.keyFilter || this.keyFilter(event.keyCode))) {
|
||||
if (this.frozen && (!this.keyFilter || this.keyFilter(event.keyCode, event))) {
|
||||
event.stop();
|
||||
this.frozen(event);
|
||||
return;
|
||||
@ -674,7 +716,7 @@ var Editor = (function(){
|
||||
this.delayScanning();
|
||||
// Schedule a paren-highlight event, if configured.
|
||||
if (this.options.autoMatchParens)
|
||||
this.scheduleParenBlink();
|
||||
this.scheduleParenHighlight();
|
||||
|
||||
// The various checks for !altKey are there because AltGr sets both
|
||||
// ctrlKey and altKey to true, and should not be recognised as
|
||||
@ -690,8 +732,8 @@ var Editor = (function(){
|
||||
}
|
||||
event.stop();
|
||||
}
|
||||
else if (code == 9 && this.options.tabMode != "default") { // tab
|
||||
this.handleTab(!event.ctrlKey && !event.shiftKey);
|
||||
else if (code == 9 && this.options.tabMode != "default" && !event.ctrlKey) { // tab
|
||||
this.handleTab(!event.shiftKey);
|
||||
event.stop();
|
||||
}
|
||||
else if (code == 32 && event.shiftKey && this.options.tabMode == "default") { // space
|
||||
@ -699,11 +741,20 @@ var Editor = (function(){
|
||||
event.stop();
|
||||
}
|
||||
else if (code == 36 && !event.shiftKey && !event.ctrlKey) { // home
|
||||
if (this.home())
|
||||
event.stop();
|
||||
if (this.home()) event.stop();
|
||||
}
|
||||
else if (code == 35 && !event.shiftKey && !event.ctrlKey) { // end
|
||||
if (this.end()) event.stop();
|
||||
}
|
||||
// Only in Firefox is the default behavior for PgUp/PgDn correct.
|
||||
else if (code == 33 && !event.shiftKey && !event.ctrlKey && !gecko) { // PgUp
|
||||
if (this.pageUp()) event.stop();
|
||||
}
|
||||
else if (code == 34 && !event.shiftKey && !event.ctrlKey && !gecko) { // PgDn
|
||||
if (this.pageDown()) event.stop();
|
||||
}
|
||||
else if ((code == 219 || code == 221) && event.ctrlKey && !event.altKey) { // [, ]
|
||||
this.blinkParens(event.shiftKey);
|
||||
this.highlightParens(event.shiftKey, true);
|
||||
event.stop();
|
||||
}
|
||||
else if (event.metaKey && !event.shiftKey && (code == 37 || code == 39)) { // Meta-left/right
|
||||
@ -730,6 +781,9 @@ var Editor = (function(){
|
||||
this.options.saveFunction();
|
||||
event.stop();
|
||||
}
|
||||
else if (internetExplorer && code == 86) {
|
||||
this.reroutePasteEvent();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -741,7 +795,7 @@ var Editor = (function(){
|
||||
// keydown event does not prevent the associated keypress event
|
||||
// from happening, so we have to cancel enter and tab again
|
||||
// here.
|
||||
if ((this.frozen && (!this.keyFilter || this.keyFilter(event.keyCode))) ||
|
||||
if ((this.frozen && (!this.keyFilter || this.keyFilter(event.keyCode, event))) ||
|
||||
event.code == 13 || (event.code == 9 && this.options.tabMode != "default") ||
|
||||
(event.keyCode == 32 && event.shiftKey && this.options.tabMode == "default"))
|
||||
event.stop();
|
||||
@ -812,17 +866,17 @@ var Editor = (function(){
|
||||
if (start) insertAfter(whiteSpace, start);
|
||||
else this.container.insertBefore(whiteSpace, this.container.firstChild);
|
||||
}
|
||||
if (firstText) select.snapshotMove(firstText.firstChild, whiteSpace.firstChild, curIndent, false, true);
|
||||
var fromNode = firstText && (firstText.firstChild || firstText);
|
||||
select.snapshotMove(fromNode, whiteSpace.firstChild, newIndent, false, true);
|
||||
}
|
||||
if (indentDiff != 0) this.addDirtyNode(start);
|
||||
return whiteSpace;
|
||||
},
|
||||
|
||||
// Re-highlight the selected part of the document.
|
||||
highlightAtCursor: function() {
|
||||
var pos = select.selectionTopNode(this.container, true);
|
||||
var to = select.selectionTopNode(this.container, false);
|
||||
if (pos === false || to === false) return;
|
||||
if (pos === false || to === false) return false;
|
||||
|
||||
select.markSelection(this.win);
|
||||
if (this.highlight(pos, endOfLine(to, this.container), true, 20) === false)
|
||||
@ -841,12 +895,14 @@ var Editor = (function(){
|
||||
this.reindentSelection(direction);
|
||||
},
|
||||
|
||||
// Custom home behaviour that doesn't land the cursor in front of
|
||||
// leading whitespace unless pressed twice.
|
||||
home: function() {
|
||||
var cur = select.selectionTopNode(this.container, true), start = cur;
|
||||
if (cur === false || !(!cur || cur.isPart || cur.nodeName == "BR") || !this.container.firstChild)
|
||||
if (cur === false || !(!cur || cur.isPart || isBR(cur)) || !this.container.firstChild)
|
||||
return false;
|
||||
|
||||
while (cur && cur.nodeName != "BR") cur = cur.previousSibling;
|
||||
while (cur && !isBR(cur)) cur = cur.previousSibling;
|
||||
var next = cur ? cur.nextSibling : this.container.firstChild;
|
||||
if (next && next != start && next.isPart && hasClass(next, "whitespace"))
|
||||
select.focusAfterNode(next, this.container);
|
||||
@ -857,18 +913,88 @@ var Editor = (function(){
|
||||
return true;
|
||||
},
|
||||
|
||||
// Delay (or initiate) the next paren blink event.
|
||||
scheduleParenBlink: function() {
|
||||
// Some browsers (Opera) don't manage to handle the end key
|
||||
// properly in the face of vertical scrolling.
|
||||
end: function() {
|
||||
var cur = select.selectionTopNode(this.container, true);
|
||||
if (cur === false) return false;
|
||||
cur = endOfLine(cur, this.container);
|
||||
if (!cur) return false;
|
||||
select.focusAfterNode(cur.previousSibling, this.container);
|
||||
select.scrollToCursor(this.container);
|
||||
return true;
|
||||
},
|
||||
|
||||
pageUp: function() {
|
||||
var line = this.cursorPosition().line, scrollAmount = this.visibleLineCount();
|
||||
if (line === false || scrollAmount === false) return false;
|
||||
// Try to keep one line on the screen.
|
||||
scrollAmount -= 2;
|
||||
for (var i = 0; i < scrollAmount; i++) {
|
||||
line = this.prevLine(line);
|
||||
if (line === false) break;
|
||||
}
|
||||
if (i == 0) return false; // Already at first line
|
||||
select.setCursorPos(this.container, {node: line, offset: 0});
|
||||
select.scrollToCursor(this.container);
|
||||
return true;
|
||||
},
|
||||
|
||||
pageDown: function() {
|
||||
var line = this.cursorPosition().line, scrollAmount = this.visibleLineCount();
|
||||
if (line === false || scrollAmount === false) return false;
|
||||
// Try to move to the last line of the current page.
|
||||
scrollAmount -= 2;
|
||||
for (var i = 0; i < scrollAmount; i++) {
|
||||
var nextLine = this.nextLine(line);
|
||||
if (nextLine === false) break;
|
||||
line = nextLine;
|
||||
}
|
||||
if (i == 0) return false; // Already at last line
|
||||
select.setCursorPos(this.container, {node: line, offset: 0});
|
||||
select.scrollToCursor(this.container);
|
||||
return true;
|
||||
},
|
||||
|
||||
// Delay (or initiate) the next paren highlight event.
|
||||
scheduleParenHighlight: function() {
|
||||
if (this.parenEvent) this.parent.clearTimeout(this.parenEvent);
|
||||
var self = this;
|
||||
this.parenEvent = this.parent.setTimeout(function(){self.blinkParens();}, 300);
|
||||
this.parenEvent = this.parent.setTimeout(function(){self.highlightParens();}, 300);
|
||||
},
|
||||
|
||||
// Take the token before the cursor. If it contains a character in
|
||||
// '()[]{}', search for the matching paren/brace/bracket, and
|
||||
// highlight them in green for a moment, or red if no proper match
|
||||
// was found.
|
||||
blinkParens: function(jump) {
|
||||
highlightParens: function(jump, fromKey) {
|
||||
var self = this;
|
||||
// give the relevant nodes a colour.
|
||||
function highlight(node, ok) {
|
||||
if (!node) return;
|
||||
if (self.options.markParen) {
|
||||
self.options.markParen(node, ok);
|
||||
}
|
||||
else {
|
||||
node.style.fontWeight = "bold";
|
||||
node.style.color = ok ? "#8F8" : "#F88";
|
||||
}
|
||||
}
|
||||
function unhighlight(node) {
|
||||
if (!node) return;
|
||||
if (self.options.unmarkParen) {
|
||||
self.options.unmarkParen(node);
|
||||
}
|
||||
else {
|
||||
node.style.fontWeight = "";
|
||||
node.style.color = "";
|
||||
}
|
||||
}
|
||||
if (!fromKey && self.highlighted) {
|
||||
unhighlight(self.highlighted[0]);
|
||||
unhighlight(self.highlighted[1]);
|
||||
}
|
||||
|
||||
if (!window.select) return;
|
||||
// Clear the event property.
|
||||
if (this.parenEvent) this.parent.clearTimeout(this.parenEvent);
|
||||
@ -886,7 +1012,7 @@ var Editor = (function(){
|
||||
return /[\(\[\{]/.test(ch);
|
||||
}
|
||||
|
||||
var ch, self = this, cursor = select.selectionTopNode(this.container, true);
|
||||
var ch, cursor = select.selectionTopNode(this.container, true);
|
||||
if (!cursor || !this.highlightAtCursor()) return;
|
||||
cursor = select.selectionTopNode(this.container, true);
|
||||
if (!(cursor && ((ch = paren(cursor)) || (cursor = cursor.nextSibling) && (ch = paren(cursor)))))
|
||||
@ -899,9 +1025,9 @@ var Editor = (function(){
|
||||
// have to scan, we just try, and when we find dirty nodes we
|
||||
// abort, parse them, and re-try.
|
||||
function tryFindMatch() {
|
||||
var stack = [], ch, ok = true;;
|
||||
var stack = [], ch, ok = true;
|
||||
for (var runner = cursor; runner; runner = dir ? runner.nextSibling : runner.previousSibling) {
|
||||
if (runner.className == className && runner.nodeName == "SPAN" && (ch = paren(runner))) {
|
||||
if (runner.className == className && isSpan(runner) && (ch = paren(runner))) {
|
||||
if (forward(ch) == dir)
|
||||
stack.push(ch);
|
||||
else if (!stack.length)
|
||||
@ -910,18 +1036,12 @@ var Editor = (function(){
|
||||
ok = false;
|
||||
if (!stack.length) break;
|
||||
}
|
||||
else if (runner.dirty || runner.nodeName != "SPAN" && runner.nodeName != "BR") {
|
||||
else if (runner.dirty || !isSpan(runner) && !isBR(runner)) {
|
||||
return {node: runner, status: "dirty"};
|
||||
}
|
||||
}
|
||||
return {node: runner, status: runner && ok};
|
||||
}
|
||||
// Temporarily give the relevant nodes a colour.
|
||||
function blink(node, ok) {
|
||||
node.style.fontWeight = "bold";
|
||||
node.style.color = ok ? "#8F8" : "#F88";
|
||||
self.parent.setTimeout(function() {node.style.fontWeight = ""; node.style.color = "";}, 500);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
var found = tryFindMatch();
|
||||
@ -933,11 +1053,14 @@ var Editor = (function(){
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
blink(cursor, found.status);
|
||||
if (found.node) {
|
||||
blink(found.node, found.status);
|
||||
if (jump) select.focusAfterNode(found.node.previousSibling, this.container);
|
||||
}
|
||||
highlight(cursor, found.status);
|
||||
highlight(found.node, found.status);
|
||||
if (fromKey)
|
||||
self.parent.setTimeout(function() {unhighlight(cursor); unhighlight(found.node);}, 500);
|
||||
else
|
||||
self.highlighted = [cursor, found.node];
|
||||
if (jump && found.node)
|
||||
select.focusAfterNode(found.node.previousSibling, this.container);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -955,20 +1078,17 @@ var Editor = (function(){
|
||||
// there's nothing to indent.
|
||||
if (cursor === false)
|
||||
return;
|
||||
var lineStart = startOfLine(cursor);
|
||||
var whiteSpace = this.indentLineAfter(lineStart, direction);
|
||||
if (cursor == lineStart && whiteSpace)
|
||||
cursor = whiteSpace;
|
||||
// This means the indentation has probably messed up the cursor.
|
||||
if (cursor == whiteSpace)
|
||||
select.focusAfterNode(cursor, this.container);
|
||||
select.markSelection(this.win);
|
||||
this.indentLineAfter(startOfLine(cursor), direction);
|
||||
select.selectMarked();
|
||||
},
|
||||
|
||||
// Indent all lines whose start falls inside of the current
|
||||
// selection.
|
||||
indentRegion: function(start, end, direction) {
|
||||
var current = (start = startOfLine(start)), before = start && startOfLine(start.previousSibling);
|
||||
if (end.nodeName != "BR") end = endOfLine(end, this.container);
|
||||
if (!isBR(end)) end = endOfLine(end, this.container);
|
||||
this.addDirtyNode(start);
|
||||
|
||||
do {
|
||||
var next = endOfLine(current, this.container);
|
||||
@ -983,9 +1103,16 @@ var Editor = (function(){
|
||||
// Find the node that the cursor is in, mark it as dirty, and make
|
||||
// sure a highlight pass is scheduled.
|
||||
cursorActivity: function(safe) {
|
||||
// pagehide event hack above
|
||||
if (this.unloaded) {
|
||||
this.win.document.designMode = "off";
|
||||
this.win.document.designMode = "on";
|
||||
this.unloaded = false;
|
||||
}
|
||||
|
||||
if (internetExplorer) {
|
||||
this.container.createTextRange().execCommand("unlink");
|
||||
this.selectionSnapshot = select.selectionCoords(this.win);
|
||||
this.selectionSnapshot = select.getBookmark(this.container);
|
||||
}
|
||||
|
||||
var activity = this.options.cursorActivity;
|
||||
@ -1021,6 +1148,10 @@ var Editor = (function(){
|
||||
this.dirty.push(node);
|
||||
},
|
||||
|
||||
allClean: function() {
|
||||
return !this.dirty.length;
|
||||
},
|
||||
|
||||
// Cause a highlight pass to happen in options.passDelay
|
||||
// milliseconds. Clear the existing timeout, if one exists. This
|
||||
// way, the passes do not happen while the user is typing, and
|
||||
@ -1043,7 +1174,7 @@ var Editor = (function(){
|
||||
// If the node has been coloured in the meantime, or is no
|
||||
// longer in the document, it should not be returned.
|
||||
while (found && found.parentNode != this.container)
|
||||
found = found.parentNode
|
||||
found = found.parentNode;
|
||||
if (found && (found.dirty || found.nodeType == 3))
|
||||
return found;
|
||||
} catch (e) {}
|
||||
@ -1060,7 +1191,7 @@ var Editor = (function(){
|
||||
highlightDirty: function(force) {
|
||||
// Prevent FF from raising an error when it is firing timeouts
|
||||
// on a page that's no longer loaded.
|
||||
if (!window.select) return;
|
||||
if (!window.select) return false;
|
||||
|
||||
if (!this.options.readOnly) select.markSelection(this.win);
|
||||
var start, endTime = force ? null : time() + this.options.passTime;
|
||||
@ -1123,17 +1254,17 @@ var Editor = (function(){
|
||||
var endTime = (typeof target == "number" ? target : null);
|
||||
|
||||
if (!container.firstChild)
|
||||
return;
|
||||
return false;
|
||||
// Backtrack to the first node before from that has a partial
|
||||
// parse stored.
|
||||
while (from && (!from.parserFromHere || from.dirty)) {
|
||||
if (maxBacktrack != null && from.nodeName == "BR" && (--maxBacktrack) < 0)
|
||||
if (maxBacktrack != null && isBR(from) && (--maxBacktrack) < 0)
|
||||
return false;
|
||||
from = from.previousSibling;
|
||||
}
|
||||
// If we are at the end of the document, do nothing.
|
||||
if (from && !from.nextSibling)
|
||||
return;
|
||||
return false;
|
||||
|
||||
// Check whether a part (<span> node) and the corresponding token
|
||||
// match.
|
||||
@ -1178,6 +1309,11 @@ var Editor = (function(){
|
||||
stream = stringStream(traversal),
|
||||
parsed = from ? from.parserFromHere(stream) : Editor.Parser.make(stream);
|
||||
|
||||
function surroundedByBRs(node) {
|
||||
return (node.previousSibling == null || isBR(node.previousSibling)) &&
|
||||
(node.nextSibling == null || isBR(node.nextSibling));
|
||||
}
|
||||
|
||||
// parts is an interface to make it possible to 'delay' fetching
|
||||
// the next DOM node until we are completely done with the one
|
||||
// before it. This is necessary because often the next node is
|
||||
@ -1208,13 +1344,23 @@ var Editor = (function(){
|
||||
// Allow empty nodes when they are alone on a line, needed
|
||||
// for the FF cursor bug workaround (see select.js,
|
||||
// insertNewlineAtCursor).
|
||||
while (part && part.nodeName == "SPAN" && part.currentText == "") {
|
||||
var old = part;
|
||||
this.remove();
|
||||
part = this.get();
|
||||
// Adjust selection information, if any. See select.js for details.
|
||||
select.snapshotMove(old.firstChild, part && (part.firstChild || part), 0);
|
||||
while (part && isSpan(part) && part.currentText == "") {
|
||||
// Leave empty nodes that are alone on a line alone in
|
||||
// Opera, since that browsers doesn't deal well with
|
||||
// having 2 BRs in a row.
|
||||
if (window.opera && surroundedByBRs(part)) {
|
||||
this.next();
|
||||
part = this.get();
|
||||
}
|
||||
else {
|
||||
var old = part;
|
||||
this.remove();
|
||||
part = this.get();
|
||||
// Adjust selection information, if any. See select.js for details.
|
||||
select.snapshotMove(old.firstChild, part && (part.firstChild || part), 0);
|
||||
}
|
||||
}
|
||||
|
||||
return part;
|
||||
}
|
||||
};
|
||||
@ -1230,7 +1376,7 @@ var Editor = (function(){
|
||||
if (token.value == "\n"){
|
||||
// The idea of the two streams actually staying synchronized
|
||||
// is such a long shot that we explicitly check.
|
||||
if (part.nodeName != "BR")
|
||||
if (!isBR(part))
|
||||
throw "Parser out of sync. Expected BR.";
|
||||
|
||||
if (part.dirty || !part.indentation) lineDirty = true;
|
||||
@ -1258,7 +1404,7 @@ var Editor = (function(){
|
||||
parts.next();
|
||||
}
|
||||
else {
|
||||
if (part.nodeName != "SPAN")
|
||||
if (!isSpan(part))
|
||||
throw "Parser out of sync. Expected SPAN.";
|
||||
if (part.dirty)
|
||||
lineDirty = true;
|
||||
@ -1314,6 +1460,6 @@ var Editor = (function(){
|
||||
|
||||
addEventHandler(window, "load", function() {
|
||||
var CodeMirror = window.frameElement.CodeMirror;
|
||||
CodeMirror.editor = new Editor(CodeMirror.options);
|
||||
var e = CodeMirror.editor = new Editor(CodeMirror.options);
|
||||
this.parent.setTimeout(method(CodeMirror, "init"), 0);
|
||||
});
|
||||
|
@ -34,7 +34,7 @@ var indentUnit = 2;
|
||||
}
|
||||
|
||||
window.highlightText = function(string, callback, parser) {
|
||||
var parser = (parser || Editor.Parser).make(stringStream(normaliseString(string)));
|
||||
parser = (parser || Editor.Parser).make(stringStream(normaliseString(string)));
|
||||
var line = [];
|
||||
if (callback.nodeType == 1) {
|
||||
var node = callback;
|
||||
|
@ -36,7 +36,7 @@ MirrorFrame.prototype = {
|
||||
|
||||
var first = true;
|
||||
do {
|
||||
var cursor = this.mirror.getSearchCursor(text, first);
|
||||
var cursor = this.mirror.getSearchCursor(text, first, true);
|
||||
first = false;
|
||||
while (cursor.findNext()) {
|
||||
cursor.select();
|
||||
|
@ -10,6 +10,8 @@
|
||||
var JSParser = Editor.Parser = (function() {
|
||||
// Token types that can be considered to be atoms.
|
||||
var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};
|
||||
// Setting that can be used to have JSON data indent properly.
|
||||
var json = false;
|
||||
// Constructor for the lexical context objects.
|
||||
function JSLexical(indented, column, type, align, prev, info) {
|
||||
// indentation at start of this line
|
||||
@ -58,7 +60,7 @@ var JSParser = Editor.Parser = (function() {
|
||||
// semicolon. Actions at the end of the stack go first. It is
|
||||
// initialized with an infinitely looping action that consumes
|
||||
// whole statements.
|
||||
var cc = [statements];
|
||||
var cc = [json ? singleExpr : statements];
|
||||
// Context contains information about the current local scope, the
|
||||
// variables defined in that, and the scopes above it.
|
||||
var context = null;
|
||||
@ -224,6 +226,9 @@ var JSParser = Editor.Parser = (function() {
|
||||
function statements(type){
|
||||
return pass(statement, statements);
|
||||
}
|
||||
function singleExpr(type){
|
||||
return pass(expression, statements);
|
||||
}
|
||||
// Dispatches various types of statements based on the type of the
|
||||
// current token.
|
||||
function statement(type){
|
||||
@ -282,7 +287,7 @@ var JSParser = Editor.Parser = (function() {
|
||||
if (type == ",") cont(what, proceed);
|
||||
else if (type == end) cont();
|
||||
else cont(expect(end));
|
||||
};
|
||||
}
|
||||
return function commaSeparated(type) {
|
||||
if (type == end) cont();
|
||||
else pass(what, proceed);
|
||||
@ -337,5 +342,11 @@ var JSParser = Editor.Parser = (function() {
|
||||
return parser;
|
||||
}
|
||||
|
||||
return {make: parseJS, electricChars: "{}:"};
|
||||
return {
|
||||
make: parseJS,
|
||||
electricChars: "{}:",
|
||||
configure: function(obj) {
|
||||
if (obj.json != null) json = obj.json;
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
@ -125,11 +125,11 @@ var XMLParser = Editor.Parser = (function() {
|
||||
// parseJavaScript in parsejavascript.js (there is actually a bit more
|
||||
// shared code than I'd like), but it is quite a bit simpler.
|
||||
function parseXML(source) {
|
||||
var tokens = tokenizeXML(source);
|
||||
var tokens = tokenizeXML(source), token;
|
||||
var cc = [base];
|
||||
var tokenNr = 0, indented = 0;
|
||||
var currentTag = null, context = null;
|
||||
var consume, marked;
|
||||
var consume;
|
||||
|
||||
function push(fs) {
|
||||
for (var i = fs.length - 1; i >= 0; i--)
|
||||
@ -144,13 +144,13 @@ var XMLParser = Editor.Parser = (function() {
|
||||
consume = false;
|
||||
}
|
||||
|
||||
function mark(style) {
|
||||
marked = style;
|
||||
function markErr() {
|
||||
token.style += " xml-error";
|
||||
}
|
||||
function expect(text) {
|
||||
return function(style, content) {
|
||||
if (content == text) cont();
|
||||
else mark("xml-error") || cont(arguments.callee);
|
||||
else {markErr(); cont(arguments.callee);}
|
||||
};
|
||||
}
|
||||
|
||||
@ -192,12 +192,12 @@ var XMLParser = Editor.Parser = (function() {
|
||||
cont();
|
||||
}
|
||||
else if (harmlessTokens.hasOwnProperty(style)) cont();
|
||||
else mark("xml-error") || cont();
|
||||
else {markErr(); cont();}
|
||||
}
|
||||
function tagname(style, content) {
|
||||
if (style == "xml-name") {
|
||||
currentTag = content.toLowerCase();
|
||||
mark("xml-tagname");
|
||||
token.style = "xml-tagname";
|
||||
cont();
|
||||
}
|
||||
else {
|
||||
@ -206,24 +206,22 @@ var XMLParser = Editor.Parser = (function() {
|
||||
}
|
||||
}
|
||||
function closetagname(style, content) {
|
||||
if (style == "xml-name" && context && content.toLowerCase() == context.name) {
|
||||
popContext();
|
||||
mark("xml-tagname");
|
||||
}
|
||||
else {
|
||||
mark("xml-error");
|
||||
if (style == "xml-name") {
|
||||
token.style = "xml-tagname";
|
||||
if (context && content.toLowerCase() == context.name) popContext();
|
||||
else markErr();
|
||||
}
|
||||
cont();
|
||||
}
|
||||
function endtag(startOfLine) {
|
||||
return function(style, content) {
|
||||
if (content == "/>" || (content == ">" && UseKludges.autoSelfClosers.hasOwnProperty(currentTag))) cont();
|
||||
else if (content == ">") pushContext(currentTag, startOfLine) || cont();
|
||||
else mark("xml-error") || cont(arguments.callee);
|
||||
else if (content == ">") {pushContext(currentTag, startOfLine); cont();}
|
||||
else {markErr(); cont(arguments.callee);}
|
||||
};
|
||||
}
|
||||
function attributes(style) {
|
||||
if (style == "xml-name") mark("xml-attname") || cont(attribute, attributes);
|
||||
if (style == "xml-name") {token.style = "xml-attname"; cont(attribute, attributes);}
|
||||
else pass();
|
||||
}
|
||||
function attribute(style, content) {
|
||||
@ -240,7 +238,7 @@ var XMLParser = Editor.Parser = (function() {
|
||||
indentation: function() {return indented;},
|
||||
|
||||
next: function(){
|
||||
var token = tokens.next();
|
||||
token = tokens.next();
|
||||
if (token.style == "whitespace" && tokenNr == 0)
|
||||
indented = token.value.length;
|
||||
else
|
||||
@ -254,13 +252,9 @@ var XMLParser = Editor.Parser = (function() {
|
||||
return token;
|
||||
|
||||
while(true){
|
||||
consume = marked = false;
|
||||
consume = false;
|
||||
cc.pop()(token.style, token.content);
|
||||
if (consume){
|
||||
if (marked)
|
||||
token.style = marked;
|
||||
return token;
|
||||
}
|
||||
if (consume) return token;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -37,7 +37,7 @@ var select = {};
|
||||
atEnd = !element.nextSibling || !element.nextSibling.nextSibling
|
||||
|| !element.nextSibling.nextSibling.nextSibling;
|
||||
// In Opera (and recent Webkit versions), BR elements *always*
|
||||
// have a scrollTop property of zero.
|
||||
// have a offsetTop property of zero.
|
||||
var compensateHack = 0;
|
||||
while (element && !element.offsetTop) {
|
||||
compensateHack++;
|
||||
@ -52,7 +52,7 @@ var select = {};
|
||||
while (pos && pos.offsetParent) {
|
||||
y += pos.offsetTop;
|
||||
// Don't count X offset for <br> nodes
|
||||
if (pos.nodeName != "BR")
|
||||
if (!isBR(pos))
|
||||
x += pos.offsetLeft;
|
||||
pos = pos.offsetParent;
|
||||
}
|
||||
@ -66,7 +66,7 @@ var select = {};
|
||||
scroll = true;
|
||||
}
|
||||
if (screen_y < 0 || atEnd || screen_y > (win.innerHeight || html.clientHeight || 0) - 50) {
|
||||
scroll_y = atEnd ? 1e10 : y;
|
||||
scroll_y = atEnd ? 1e6 : y;
|
||||
scroll = true;
|
||||
}
|
||||
if (scroll) win.scrollTo(scroll_x, scroll_y);
|
||||
@ -247,13 +247,17 @@ var select = {};
|
||||
}
|
||||
if (cur) {
|
||||
try{range.moveToElementText(cur);}
|
||||
catch(e){}
|
||||
catch(e){return false;}
|
||||
range.collapse(false);
|
||||
}
|
||||
else range.moveToElementText(node.parentNode);
|
||||
if (count) range.move("character", count);
|
||||
}
|
||||
else range.moveToElementText(node);
|
||||
else {
|
||||
try{range.moveToElementText(node);}
|
||||
catch(e){return false;}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Do a binary search through the container object, comparing
|
||||
@ -262,7 +266,7 @@ var select = {};
|
||||
while (start < end) {
|
||||
var middle = Math.ceil((end + start) / 2), node = container.childNodes[middle];
|
||||
if (!node) return false; // Don't ask. IE6 manages this sometimes.
|
||||
moveToNodeStart(range2, node);
|
||||
if (!moveToNodeStart(range2, node)) return false;
|
||||
if (range.compareEndPoints("StartToStart", range2) == 1)
|
||||
start = middle;
|
||||
else
|
||||
@ -314,7 +318,7 @@ var select = {};
|
||||
if (!selection) return null;
|
||||
|
||||
var topNode = select.selectionTopNode(container, start);
|
||||
while (topNode && topNode.nodeName != "BR")
|
||||
while (topNode && !isBR(topNode))
|
||||
topNode = topNode.previousSibling;
|
||||
|
||||
var range = selection.createRange(), range2 = range.duplicate();
|
||||
@ -356,32 +360,15 @@ var select = {};
|
||||
}
|
||||
|
||||
// Some hacks for storing and re-storing the selection when the editor loses and regains focus.
|
||||
select.selectionCoords = function (win) {
|
||||
var selection = win.document.selection;
|
||||
if (!selection) return null;
|
||||
var start = selection.createRange(), end = start.duplicate();
|
||||
start.collapse(true);
|
||||
end.collapse(false);
|
||||
|
||||
var body = win.document.body;
|
||||
return {start: {x: start.boundingLeft + body.scrollLeft - 1,
|
||||
y: start.boundingTop + body.scrollTop},
|
||||
end: {x: end.boundingLeft + body.scrollLeft - 1,
|
||||
y: end.boundingTop + body.scrollTop}};
|
||||
select.getBookmark = function (container) {
|
||||
var from = select.cursorPos(container, true), to = select.cursorPos(container, false);
|
||||
if (from && to) return {from: from, to: to};
|
||||
};
|
||||
|
||||
// Restore a stored selection.
|
||||
select.selectCoords = function(win, coords) {
|
||||
if (!coords) return;
|
||||
|
||||
var range1 = win.document.body.createTextRange(), range2 = range1.duplicate();
|
||||
// This can fail for various hard-to-handle reasons.
|
||||
try {
|
||||
range1.moveToPoint(coords.start.x, coords.start.y);
|
||||
range2.moveToPoint(coords.end.x, coords.end.y);
|
||||
range1.setEndPoint("EndToStart", range2);
|
||||
range1.select();
|
||||
} catch(e) {}
|
||||
select.setBookmark = function(container, mark) {
|
||||
if (!mark) return;
|
||||
select.setCursorPos(container, mark.from, mark.to);
|
||||
};
|
||||
}
|
||||
// W3C model
|
||||
@ -407,7 +394,7 @@ var select = {};
|
||||
// ancestors with a suitable offset. This goes down the DOM tree
|
||||
// until a 'leaf' is reached (or is it *up* the DOM tree?).
|
||||
function normalize(point){
|
||||
while (point.node.nodeType != 3 && point.node.nodeName != "BR") {
|
||||
while (point.node.nodeType != 3 && !isBR(point.node)) {
|
||||
var newNode = point.node.childNodes[point.offset] || point.node.nextSibling;
|
||||
point.offset = 0;
|
||||
while (!newNode && point.node.parentNode) {
|
||||
@ -425,8 +412,17 @@ var select = {};
|
||||
};
|
||||
|
||||
select.selectMarked = function () {
|
||||
if (!currentSelection || !currentSelection.changed) return;
|
||||
var win = currentSelection.window, range = win.document.createRange();
|
||||
var cs = currentSelection;
|
||||
// on webkit-based browsers, it is apparently possible that the
|
||||
// selection gets reset even when a node that is not one of the
|
||||
// endpoints get messed with. the most common situation where
|
||||
// this occurs is when a selection is deleted or overwitten. we
|
||||
// check for that here.
|
||||
function focusIssue() {
|
||||
return cs.start.node == cs.end.node && cs.start.offset == 0 && cs.end.offset == 0;
|
||||
}
|
||||
if (!cs || !(cs.changed || (webkit && focusIssue()))) return;
|
||||
var win = cs.window, range = win.document.createRange();
|
||||
|
||||
function setPoint(point, which) {
|
||||
if (point.node) {
|
||||
@ -442,8 +438,8 @@ var select = {};
|
||||
}
|
||||
}
|
||||
|
||||
setPoint(currentSelection.end, "End");
|
||||
setPoint(currentSelection.start, "Start");
|
||||
setPoint(cs.end, "End");
|
||||
setPoint(cs.start, "Start");
|
||||
selectRange(range, win);
|
||||
};
|
||||
|
||||
@ -452,7 +448,7 @@ var select = {};
|
||||
var selection = window.getSelection();
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
};
|
||||
}
|
||||
function selectionRange(window) {
|
||||
var selection = window.getSelection();
|
||||
if (!selection || selection.rangeCount == 0)
|
||||
@ -471,7 +467,7 @@ var select = {};
|
||||
var offset = start ? range.startOffset : range.endOffset;
|
||||
// Work around (yet another) bug in Opera's selection model.
|
||||
if (window.opera && !start && range.endContainer == container && range.endOffset == range.startOffset + 1 &&
|
||||
container.childNodes[range.startOffset] && container.childNodes[range.startOffset].nodeName == "BR")
|
||||
container.childNodes[range.startOffset] && isBR(container.childNodes[range.startOffset]))
|
||||
offset--;
|
||||
|
||||
// For text nodes, we look at the node itself if the cursor is
|
||||
@ -486,7 +482,7 @@ var select = {};
|
||||
// Occasionally, browsers will return the HTML node as
|
||||
// selection. If the offset is 0, we take the start of the frame
|
||||
// ('after null'), otherwise, we take the last node.
|
||||
else if (node.nodeName == "HTML") {
|
||||
else if (node.nodeName.toUpperCase() == "HTML") {
|
||||
return (offset == 1 ? null : container.lastChild);
|
||||
}
|
||||
// If the given node is our 'container', we just look up the
|
||||
@ -557,7 +553,7 @@ var select = {};
|
||||
if (!range) return;
|
||||
|
||||
var topNode = select.selectionTopNode(container, start);
|
||||
while (topNode && topNode.nodeName != "BR")
|
||||
while (topNode && !isBR(topNode))
|
||||
topNode = topNode.previousSibling;
|
||||
|
||||
range = range.cloneRange();
|
||||
@ -574,13 +570,17 @@ var select = {};
|
||||
range = win.document.createRange();
|
||||
|
||||
function setPoint(node, offset, side) {
|
||||
if (offset == 0 && node && !node.nextSibling) {
|
||||
range["set" + side + "After"](node);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!node)
|
||||
node = container.firstChild;
|
||||
else
|
||||
node = node.nextSibling;
|
||||
|
||||
if (!node)
|
||||
return;
|
||||
if (!node) return;
|
||||
|
||||
if (offset == 0) {
|
||||
range["set" + side + "Before"](node);
|
||||
|
@ -14,7 +14,7 @@
|
||||
// Make a stringstream stream out of an iterator that returns strings.
|
||||
// This is applied to the result of traverseDOM (see codemirror.js),
|
||||
// and the resulting stream is fed to the parser.
|
||||
window.stringStream = function(source){
|
||||
var stringStream = function(source){
|
||||
// String that's currently being iterated over.
|
||||
var current = "";
|
||||
// Position in that string.
|
||||
|
@ -5,7 +5,6 @@ var tokenizeJavaScript = (function() {
|
||||
// backslash) is encountered, or the end of the line is reached.
|
||||
function nextUntilUnescaped(source, end) {
|
||||
var escaped = false;
|
||||
var next;
|
||||
while (!source.endOfLine()) {
|
||||
var next = source.next();
|
||||
if (next == end && !escaped)
|
||||
@ -48,7 +47,7 @@ var tokenizeJavaScript = (function() {
|
||||
}();
|
||||
|
||||
// Some helper regexps
|
||||
var isOperatorChar = /[+\-*&%\/=<>!?|]/;
|
||||
var isOperatorChar = /[+\-*&%=<>!?|]/;
|
||||
var isHexDigit = /[0-9A-Fa-f]/;
|
||||
var isWordChar = /[\w\$_]/;
|
||||
|
||||
@ -66,7 +65,7 @@ var tokenizeJavaScript = (function() {
|
||||
};
|
||||
}
|
||||
|
||||
// The token reader, inteded to be used by the tokenizer from
|
||||
// The token reader, intended to be used by the tokenizer from
|
||||
// tokenize.js (through jsTokenState). Advances the source stream
|
||||
// over a token, and returns an object containing the type and style
|
||||
// of that token.
|
||||
|
@ -26,11 +26,10 @@
|
||||
// delay (of no input) after which it commits a set of changes, and,
|
||||
// unfortunately, the 'parent' window -- a window that is not in
|
||||
// designMode, and on which setTimeout works in every browser.
|
||||
function History(container, maxDepth, commitDelay, editor, onChange) {
|
||||
function History(container, maxDepth, commitDelay, editor) {
|
||||
this.container = container;
|
||||
this.maxDepth = maxDepth; this.commitDelay = commitDelay;
|
||||
this.editor = editor; this.parent = editor.parent;
|
||||
this.onChange = onChange;
|
||||
// This line object represents the initial, empty editor.
|
||||
var initial = {text: "", from: null, to: null};
|
||||
// As the borders between lines are represented by BR elements, the
|
||||
@ -73,7 +72,7 @@ History.prototype = {
|
||||
// shadow in the redo history.
|
||||
var item = this.history.pop();
|
||||
this.redoHistory.push(this.updateTo(item, "applyChain"));
|
||||
if (this.onChange) this.onChange();
|
||||
this.notifyEnvironment();
|
||||
return this.chainNode(item);
|
||||
}
|
||||
},
|
||||
@ -85,7 +84,7 @@ History.prototype = {
|
||||
// The inverse of undo, basically.
|
||||
var item = this.redoHistory.pop();
|
||||
this.addUndoLevel(this.updateTo(item, "applyChain"));
|
||||
if (this.onChange) this.onChange();
|
||||
this.notifyEnvironment();
|
||||
return this.chainNode(item);
|
||||
}
|
||||
},
|
||||
@ -109,6 +108,7 @@ History.prototype = {
|
||||
from = end;
|
||||
}
|
||||
this.pushChains([chain], from == null && to == null);
|
||||
this.notifyEnvironment();
|
||||
},
|
||||
|
||||
pushChains: function(chains, doNotHighlight) {
|
||||
@ -162,7 +162,7 @@ History.prototype = {
|
||||
if (chains.length) {
|
||||
this.addUndoLevel(this.updateTo(chains, "linkChain"));
|
||||
this.redoHistory = [];
|
||||
if (this.onChange) this.onChange();
|
||||
this.notifyEnvironment();
|
||||
}
|
||||
},
|
||||
|
||||
@ -191,6 +191,13 @@ History.prototype = {
|
||||
this.editor.scheduleHighlight();
|
||||
},
|
||||
|
||||
notifyEnvironment: function() {
|
||||
// Used by the line-wrapping line-numbering code.
|
||||
if (window.frameElement && window.frameElement.CodeMirror.updateNumbers)
|
||||
window.frameElement.CodeMirror.updateNumbers();
|
||||
if (this.onChange) this.onChange();
|
||||
},
|
||||
|
||||
// Link a chain into the DOM nodes (or the first/last links for null
|
||||
// nodes).
|
||||
linkChain: function(chain) {
|
||||
@ -250,7 +257,7 @@ History.prototype = {
|
||||
function buildLine(node) {
|
||||
var text = [];
|
||||
for (var cur = node ? node.nextSibling : self.container.firstChild;
|
||||
cur && cur.nodeName != "BR"; cur = cur.nextSibling)
|
||||
cur && !isBR(cur); cur = cur.nextSibling)
|
||||
if (cur.currentText) text.push(cur.currentText);
|
||||
return {from: node, to: cur, text: cleanText(text.join(""))};
|
||||
}
|
||||
@ -275,7 +282,7 @@ History.prototype = {
|
||||
// Get the BR element after/before the given node.
|
||||
function nextBR(node, dir) {
|
||||
var link = dir + "Sibling", search = node[link];
|
||||
while (search && search.nodeName != "BR")
|
||||
while (search && !isBR(search))
|
||||
search = search[link];
|
||||
return search;
|
||||
}
|
||||
|
@ -1,9 +1,5 @@
|
||||
/* A few useful utility functions. */
|
||||
|
||||
var internetExplorer = document.selection && window.ActiveXObject && /MSIE/.test(navigator.userAgent);
|
||||
var webkit = /AppleWebKit/.test(navigator.userAgent);
|
||||
var safari = /Apple Computers, Inc/.test(navigator.vendor);
|
||||
|
||||
// Capture a method on an object.
|
||||
function method(obj, name) {
|
||||
return function() {obj[name].apply(obj, arguments);};
|
||||
@ -112,7 +108,7 @@ function addEventHandler(node, type, handler, removeFunc) {
|
||||
}
|
||||
|
||||
function nodeText(node) {
|
||||
return node.innerText || node.textContent || node.nodeValue || "";
|
||||
return node.textContent || node.innerText || node.nodeValue || "";
|
||||
}
|
||||
|
||||
function nodeTop(node) {
|
||||
@ -123,3 +119,12 @@ function nodeTop(node) {
|
||||
}
|
||||
return top;
|
||||
}
|
||||
|
||||
function isBR(node) {
|
||||
var nn = node.nodeName;
|
||||
return nn == "BR" || nn == "br";
|
||||
}
|
||||
function isSpan(node) {
|
||||
var nn = node.nodeName;
|
||||
return nn == "SPAN" || nn == "span";
|
||||
}
|
||||
|
1077
public/javascripts/admin/plugins/fancybox.js
Executable file
86
public/javascripts/admin/plugins/plupload/gears_init.js
Normal file
@ -0,0 +1,86 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// 3. Neither the name of Google Inc. nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Sets up google.gears.*, which is *the only* supported way to access Gears.
|
||||
//
|
||||
// Circumvent this file at your own risk!
|
||||
//
|
||||
// In the future, Gears may automatically define google.gears.* without this
|
||||
// file. Gears may use these objects to transparently fix bugs and compatibility
|
||||
// issues. Applications that use the code below will continue to work seamlessly
|
||||
// when that happens.
|
||||
|
||||
(function() {
|
||||
// We are already defined. Hooray!
|
||||
if (window.google && google.gears) {
|
||||
return;
|
||||
}
|
||||
|
||||
var factory = null;
|
||||
|
||||
// Firefox
|
||||
if (typeof GearsFactory != 'undefined') {
|
||||
factory = new GearsFactory();
|
||||
} else {
|
||||
// IE
|
||||
try {
|
||||
factory = new ActiveXObject('Gears.Factory');
|
||||
// privateSetGlobalObject is only required and supported on WinCE.
|
||||
if (factory.getBuildInfo().indexOf('ie_mobile') != -1) {
|
||||
factory.privateSetGlobalObject(this);
|
||||
}
|
||||
} catch (e) {
|
||||
// Safari
|
||||
if ((typeof navigator.mimeTypes != 'undefined')
|
||||
&& navigator.mimeTypes["application/x-googlegears"]) {
|
||||
factory = document.createElement("object");
|
||||
factory.style.display = "none";
|
||||
factory.width = 0;
|
||||
factory.height = 0;
|
||||
factory.type = "application/x-googlegears";
|
||||
document.documentElement.appendChild(factory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *Do not* define any objects if Gears is not installed. This mimics the
|
||||
// behavior of Gears defining the objects in the future.
|
||||
if (!factory) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Now set up the objects, being careful not to overwrite anything.
|
||||
//
|
||||
// Note: In Internet Explorer for Windows Mobile, you can't add properties to
|
||||
// the window object. However, global objects are automatically added as
|
||||
// properties of the window object in all browsers.
|
||||
if (!window.google) {
|
||||
google = {};
|
||||
}
|
||||
|
||||
if (!google.gears) {
|
||||
google.gears = {factory: factory};
|
||||
}
|
||||
})();
|
1
public/javascripts/admin/plugins/plupload/jquery.plupload.queue.min.js
vendored
Normal file
1
public/javascripts/admin/plugins/plupload/plupload.browserplus.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
(function(a){a.runtimes.BrowserPlus=a.addRuntime("browserplus",{getFeatures:function(){return{dragdrop:true,jpgresize:true,pngresize:true,chunks:true,progress:true,multipart:true}},init:function(g,i){var e=window.BrowserPlus,h={},d=g.settings,c=d.resize;function f(n){var m,l,j=[],k,o;for(l=0;l<n.length;l++){k=n[l];o=a.guid();h[o]=k;j.push(new a.File(o,k.name,k.size))}if(l){g.trigger("FilesAdded",j)}}function b(){g.bind("PostInit",function(){var m,k=d.drop_element,o=g.id+"_droptarget",j=document.getElementById(k),l;function p(r,q){e.DragAndDrop.AddDropTarget({id:r},function(s){e.DragAndDrop.AttachCallbacks({id:r,hover:function(t){if(!t&&q){q()}},drop:function(t){if(q){q()}f(t)}},function(){})})}function n(){document.getElementById(o).style.top="-1000px"}if(j){if(document.attachEvent&&(/MSIE/gi).test(navigator.userAgent)){m=document.createElement("div");m.setAttribute("id",o);a.extend(m.style,{position:"absolute",top:"-1000px",background:"red",filter:"alpha(opacity=0)",opacity:0});document.body.appendChild(m);a.addEvent(j,"dragenter",function(r){var q,s;q=document.getElementById(k);s=a.getPos(q);a.extend(document.getElementById(o).style,{top:s.y+"px",left:s.x+"px",width:q.offsetWidth+"px",height:q.offsetHeight+"px"})});p(o,n)}else{p(k)}}a.addEvent(document.getElementById(d.browse_button),"click",function(v){var t=[],r,q,u=d.filters,s;v.preventDefault();for(r=0;r<u.length;r++){s=u[r].extensions.split(",");for(q=0;q<s.length;q++){t.push(a.mimeTypes[s[q]])}}e.FileBrowse.OpenBrowseDialog({mimeTypes:t},function(w){if(w.success){f(w.value)}})});j=m=null});g.bind("UploadFile",function(n,k){var m=h[k.id],j={},l=n.settings.chunk_size,o,p=[];function r(s,u){var t;if(k.status==a.FAILED){return}j.name=k.target_name||k.name;if(l){j.chunk=s;j.chunks=u}t=p.shift();e.Uploader.upload({url:a.buildUrl(n.settings.url,j),files:{file:t},cookies:document.cookies,postvars:n.settings.multipart_params,progressCallback:function(x){var w,v=0;o[s]=parseInt(x.filePercent*t.size/100,10);for(w=0;w<o.length;w++){v+=o[w]}k.loaded=v;n.trigger("UploadProgress",k)}},function(w){var v,x;if(w.success){v=w.value.statusCode;if(l){n.trigger("ChunkUploaded",k,{chunk:s,chunks:u,response:w.value.body,status:v})}if(p.length>0){r(++s,u)}else{k.status=a.DONE;n.trigger("FileUploaded",k,{response:w.value.body,status:v});if(v>=400){n.trigger("Error",{code:a.HTTP_ERROR,message:"HTTP Error.",file:k,status:v})}}}else{n.trigger("Error",{code:a.GENERIC_ERROR,message:"Generic Error.",file:k,details:w.error})}})}function q(s){k.size=s.size;if(l){e.FileAccess.chunk({file:s,chunkSize:l},function(v){if(v.success){var w=v.value,t=w.length;o=Array(t);for(var u=0;u<t;u++){o[u]=0;p.push(w[u])}r(0,t)}})}else{o=Array(1);p.push(s);r(0,1)}}if(c&&/\.(png|jpg|jpeg)$/i.test(k.name)){BrowserPlus.ImageAlter.transform({file:m,quality:c.quality||90,actions:[{scale:{maxwidth:c.width,maxheight:c.height}}]},function(s){if(s.success){q(s.value.file)}})}else{q(m)}});i({success:true})}if(e){e.init(function(k){var j=[{service:"Uploader",version:"3"},{service:"DragAndDrop",version:"1"},{service:"FileBrowse",version:"1"},{service:"FileAccess",version:"2"}];if(c){j.push({service:"ImageAlter",version:"4"})}if(k.success){e.require({services:j},function(l){if(l.success){b()}else{i()}})}else{i()}})}else{i()}}})})(plupload);
|
1
public/javascripts/admin/plugins/plupload/plupload.flash.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
(function(c){var a={};function b(){var d;try{d=navigator.plugins["Shockwave Flash"];d=d.description}catch(f){try{d=new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version")}catch(e){d="0.0"}}d=d.match(/\d+/g);return parseFloat(d[0]+"."+d[1])}c.flash={trigger:function(f,d,e){setTimeout(function(){var j=a[f],h,g;if(j){j.trigger("Flash:"+d,e)}},0)}};c.runtimes.Flash=c.addRuntime("flash",{getFeatures:function(){return{jpgresize:true,pngresize:true,chunks:true,progress:true,multipart:true}},init:function(g,l){var k,f,h,e,m=0,d=document.body;if(b()<10){l({success:false});return}a[g.id]=g;k=document.getElementById(g.settings.browse_button);f=document.createElement("div");f.id=g.id+"_flash_container";c.extend(f.style,{position:"absolute",top:"0px",background:g.settings.shim_bgcolor||"transparent",zIndex:99999,width:"100%",height:"100%"});f.className="plupload flash";if(g.settings.container){d=document.getElementById(g.settings.container);d.style.position="relative"}d.appendChild(f);h="id="+escape(g.id);f.innerHTML='<object id="'+g.id+'_flash" width="100%" height="100%" style="outline:0" type="application/x-shockwave-flash" data="'+g.settings.flash_swf_url+'"><param name="movie" value="'+g.settings.flash_swf_url+'" /><param name="flashvars" value="'+h+'" /><param name="wmode" value="transparent" /><param name="allowscriptaccess" value="always" /></object>';function j(){return document.getElementById(g.id+"_flash")}function i(){if(m++>5000){l({success:false});return}if(!e){setTimeout(i,1)}}i();k=f=null;g.bind("Flash:Init",function(){var p={},o,n=g.settings.resize||{};e=true;j().setFileFilters(g.settings.filters,g.settings.multi_selection);g.bind("UploadFile",function(q,r){var s=q.settings;j().uploadFile(p[r.id],c.buildUrl(s.url,{name:r.target_name||r.name}),{chunk_size:s.chunk_size,width:n.width,height:n.height,quality:n.quality||90,multipart:s.multipart,multipart_params:s.multipart_params,file_data_name:s.file_data_name,format:/\.(jpg|jpeg)$/i.test(r.name)?"jpg":"png",headers:s.headers})});g.bind("Flash:UploadProcess",function(r,q){var s=r.getFile(p[q.id]);if(s.status!=c.FAILED){s.loaded=q.loaded;s.size=q.size;r.trigger("UploadProgress",s)}});g.bind("Flash:UploadChunkComplete",function(q,s){var t,r=q.getFile(p[s.id]);t={chunk:s.chunk,chunks:s.chunks,response:s.text};q.trigger("ChunkUploaded",r,t);if(r.status!=c.FAILED){j().uploadNextChunk()}if(s.chunk==s.chunks-1){r.status=c.DONE;q.trigger("FileUploaded",r,{response:s.text})}});g.bind("Flash:SelectFiles",function(q,t){var s,r,u=[],v;for(r=0;r<t.length;r++){s=t[r];v=c.guid();p[v]=s.id;p[s.id]=v;u.push(new c.File(v,s.name,s.size))}if(u.length){g.trigger("FilesAdded",u)}});g.bind("Flash:SecurityError",function(q,r){g.trigger("Error",{code:c.SECURITY_ERROR,message:"Security error.",details:r.message,file:g.getFile(p[r.id])})});g.bind("Flash:GenericError",function(q,r){g.trigger("Error",{code:c.GENERIC_ERROR,message:"Generic error.",details:r.message,file:g.getFile(p[r.id])})});g.bind("Flash:IOError",function(q,r){g.trigger("Error",{code:c.IO_ERROR,message:"IO error.",details:r.message,file:g.getFile(p[r.id])})});g.bind("QueueChanged",function(q){g.refresh()});g.bind("FilesRemoved",function(q,s){var r;for(r=0;r<s.length;r++){j().removeFile(p[s[r].id])}});g.bind("StateChanged",function(q){g.refresh()});g.bind("Refresh",function(q){var r,s,t;j().setFileFilters(g.settings.filters,g.settings.multi_selection);r=document.getElementById(q.settings.browse_button);s=c.getPos(r,document.getElementById(q.settings.container));t=c.getSize(r);c.extend(document.getElementById(q.id+"_flash_container").style,{top:s.y+"px",left:s.x+"px",width:t.w+"px",height:t.h+"px"})});l({success:true})})}})})(plupload);
|
BIN
public/javascripts/admin/plugins/plupload/plupload.flash.swf
Normal file
1
public/javascripts/admin/plugins/plupload/plupload.gears.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
(function(b){var c={};function a(i,e,k,j,d){var l,g,f,h;g=google.gears.factory.create("beta.canvas");g.decode(i);h=Math.min(e/g.width,k/g.height);if(h<1){e=Math.round(g.width*h);k=Math.round(g.height*h)}else{e=g.width;k=g.height}g.resize(e,k);return g.encode(d,{quality:j/100})}b.runtimes.Gears=b.addRuntime("gears",{getFeatures:function(){return{dragdrop:true,jpgresize:true,pngresize:true,chunks:true,progress:true,multipart:true}},init:function(g,i){var h;if(!window.google||!google.gears){return i({success:false})}try{h=google.gears.factory.create("beta.desktop")}catch(f){return i({success:false})}function d(k){var j,e,l=[],m;for(e=0;e<k.length;e++){j=k[e];m=b.guid();c[m]=j.blob;l.push(new b.File(m,j.name,j.blob.length))}g.trigger("FilesAdded",l)}g.bind("PostInit",function(){var j=g.settings,e=document.getElementById(j.drop_element);if(e){b.addEvent(e,"dragover",function(k){h.setDropEffect(k,"copy");k.preventDefault()});b.addEvent(e,"drop",function(l){var k=h.getDragData(l,"application/x-gears-files");if(k){d(k.files)}l.preventDefault()});e=0}b.addEvent(document.getElementById(j.browse_button),"click",function(o){var n=[],l,k,m;o.preventDefault();for(l=0;l<j.filters.length;l++){m=j.filters[l].extensions.split(",");for(k=0;k<m.length;k++){n.push("."+m[k])}}h.openFiles(d,{singleFile:!j.multi_selection,filter:n})})});g.bind("UploadFile",function(o,l){var q=0,p,m,n=0,k=o.settings.resize,e;m=o.settings.chunk_size;e=m>0;p=Math.ceil(l.size/m);if(!e){m=l.size;p=1}if(k&&/\.(png|jpg|jpeg)$/i.test(l.name)){c[l.id]=a(c[l.id],k.width,k.height,k.quality||90,/\.png$/i.test(l.name)?"image/png":"image/jpeg")}l.size=c[l.id].length;function j(){var u,w,s=o.settings.multipart,r=0,v={name:l.target_name||l.name};function t(y){var x,C="----pluploadboundary"+b.guid(),A="--",B="\r\n",z;if(s){u.setRequestHeader("Content-Type","multipart/form-data; boundary="+C);x=google.gears.factory.create("beta.blobbuilder");b.each(o.settings.multipart_params,function(E,D){x.append(A+C+B+'Content-Disposition: form-data; name="'+D+'"'+B+B);x.append(E+B)});x.append(A+C+B+'Content-Disposition: form-data; name="'+o.settings.file_data_name+'"; filename="'+l.name+'"'+B+"Content-Type: application/octet-stream"+B+B);x.append(y);x.append(B+A+C+A+B);z=x.getAsBlob();r=z.length-y.length;y=z}u.send(y)}if(l.status==b.DONE||l.status==b.FAILED||o.state==b.STOPPED){return}if(e){v.chunk=q;v.chunks=p}w=Math.min(m,l.size-(q*m));u=google.gears.factory.create("beta.httprequest");u.open("POST",b.buildUrl(o.settings.url,v));if(!s){u.setRequestHeader("Content-Disposition",'attachment; filename="'+l.name+'"');u.setRequestHeader("Content-Type","application/octet-stream")}b.each(o.settings.headers,function(y,x){u.setRequestHeader(x,y)});u.upload.onprogress=function(x){l.loaded=n+x.loaded-r;o.trigger("UploadProgress",l)};u.onreadystatechange=function(){var x;if(u.readyState==4){if(u.status==200){x={chunk:q,chunks:p,response:u.responseText,status:u.status};o.trigger("ChunkUploaded",l,x);if(x.cancelled){l.status=b.FAILED;return}n+=w;if(++q>=p){l.status=b.DONE;o.trigger("FileUploaded",l,{response:u.responseText,status:u.status})}else{j()}}else{o.trigger("Error",{code:b.HTTP_ERROR,message:"HTTP Error.",file:l,chunk:q,chunks:p,status:u.status})}}};if(q<p){t(c[l.id].slice(q*m,w))}}j()});i({success:true})}})})(plupload);
|
1
public/javascripts/admin/plugins/plupload/plupload.html4.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
(function(a){a.runtimes.Html4=a.addRuntime("html4",{getFeatures:function(){return{multipart:true}},init:function(f,g){var d={},c,b;function e(l){var k,j,m=[],n,h;h=l.value.replace(/\\/g,"/");h=h.substring(h.length,h.lastIndexOf("/")+1);n=a.guid();k=new a.File(n,h);d[n]=k;k.input=l;m.push(k);if(m.length){f.trigger("FilesAdded",m)}}f.bind("Init",function(p){var h,x,v,t=[],o,u,m=p.settings.filters,l,s,r=/MSIE/.test(navigator.userAgent),k="javascript",w,j=document.body,n;if(f.settings.container){j=document.getElementById(f.settings.container);j.style.position="relative"}c=(typeof p.settings.form=="string")?document.getElementById(p.settings.form):p.settings.form;if(!c){n=document.getElementById(f.settings.browse_button);for(;n;n=n.parentNode){if(n.nodeName=="FORM"){c=n}}}if(!c){c=document.createElement("form");c.style.display="inline";n=document.getElementById(f.settings.container);n.parentNode.insertBefore(c,n);c.appendChild(n)}c.setAttribute("method","post");c.setAttribute("enctype","multipart/form-data");a.each(p.settings.multipart_params,function(z,y){var i=document.createElement("input");a.extend(i,{type:"hidden",name:y,value:z});c.appendChild(i)});b=document.createElement("iframe");b.setAttribute("src",k+':""');b.setAttribute("name",p.id+"_iframe");b.setAttribute("id",p.id+"_iframe");b.style.display="none";a.addEvent(b,"load",function(B){var C=B.target,z=f.currentfile,A;try{A=C.contentWindow.document||C.contentDocument||window.frames[C.id].document}catch(y){p.trigger("Error",{code:a.SECURITY_ERROR,message:"Security error.",file:z});return}if(A.location.href=="about:blank"||!z){return}var i=A.documentElement.innerText||A.documentElement.textContent;if(i!=""){z.status=a.DONE;z.loaded=1025;z.percent=100;if(z.input){z.input.removeAttribute("name")}p.trigger("UploadProgress",z);p.trigger("FileUploaded",z,{response:i});if(c.tmpAction){c.setAttribute("action",c.tmpAction)}if(c.tmpTarget){c.setAttribute("target",c.tmpTarget)}}});c.appendChild(b);if(r){window.frames[b.id].name=b.name}x=document.createElement("div");x.id=p.id+"_iframe_container";for(o=0;o<m.length;o++){l=m[o].extensions.split(/,/);for(u=0;u<l.length;u++){s=a.mimeTypes[l[u]];if(s){t.push(s)}}}a.extend(x.style,{position:"absolute",background:"transparent",width:"100px",height:"100px",overflow:"hidden",zIndex:99999,opacity:0});w=f.settings.shim_bgcolor;if(w){a.extend(x.style,{background:w,opacity:1})}x.className="plupload_iframe";j.appendChild(x);function q(){v=document.createElement("input");v.setAttribute("type","file");v.setAttribute("accept",t.join(","));v.setAttribute("size",1);a.extend(v.style,{width:"100%",height:"100%",opacity:0});if(r){a.extend(v.style,{filter:"alpha(opacity=0)"})}a.addEvent(v,"change",function(i){var y=i.target;if(y.value){q();y.style.display="none";e(y)}});x.appendChild(v);return true}q()});f.bind("Refresh",function(h){var i,j,k;i=document.getElementById(f.settings.browse_button);j=a.getPos(i,document.getElementById(h.settings.container));k=a.getSize(i);a.extend(document.getElementById(f.id+"_iframe_container").style,{top:j.y+"px",left:j.x+"px",width:k.w+"px",height:k.h+"px"})});f.bind("UploadFile",function(h,i){if(i.status==a.DONE||i.status==a.FAILED||h.state==a.STOPPED){return}if(!i.input){i.status=a.ERROR;return}i.input.setAttribute("name",h.settings.file_data_name);c.tmpAction=c.getAttribute("action");c.setAttribute("action",a.buildUrl(h.settings.url,{name:i.target_name||i.name}));c.tmpTarget=c.getAttribute("target");c.setAttribute("target",b.name);this.currentfile=i;c.submit()});f.bind("FilesRemoved",function(h,k){var j,l;for(j=0;j<k.length;j++){l=k[j].input;if(l){l.parentNode.removeChild(l)}}});g({success:true})}})})(plupload);
|
1
public/javascripts/admin/plugins/plupload/plupload.html5.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
(function(b){function a(i,l,j,c,k){var e,d,h,g,f;e=document.createElement("canvas");e.style.display="none";document.body.appendChild(e);d=e.getContext("2d");h=new Image();h.onload=function(){var o,m,n;f=Math.min(l/h.width,j/h.height);if(f<1){o=Math.round(h.width*f);m=Math.round(h.height*f)}else{o=h.width;m=h.height}e.width=o;e.height=m;d.drawImage(h,0,0,o,m);g=e.toDataURL(c);g=g.substring(g.indexOf("base64,")+7);g=atob(g);e.parentNode.removeChild(e);k({success:true,data:g})};h.src=i}b.runtimes.Html5=b.addRuntime("html5",{getFeatures:function(){var g,d,f,e,c;d=f=e=c=false;if(window.XMLHttpRequest){g=new XMLHttpRequest();f=!!g.upload;d=!!(g.sendAsBinary||g.upload)}if(d){e=!!(File&&File.prototype.getAsDataURL);c=!!(File&&File.prototype.slice)}return{html5:d,dragdrop:window.mozInnerScreenX!==undefined||c,jpgresize:e,pngresize:e,multipart:e,progress:f}},init:function(e,f){var c={};function d(k){var h,g,j=[],l;for(g=0;g<k.length;g++){h=k[g];l=b.guid();c[l]=h;j.push(new b.File(l,h.fileName,h.fileSize))}if(j.length){e.trigger("FilesAdded",j)}}if(!this.getFeatures().html5){f({success:false});return}e.bind("Init",function(l){var p,n=[],k,o,h=l.settings.filters,j,m,g=document.body;p=document.createElement("div");p.id=l.id+"_html5_container";for(k=0;k<h.length;k++){j=h[k].extensions.split(/,/);for(o=0;o<j.length;o++){m=b.mimeTypes[j[o]];if(m){n.push(m)}}}b.extend(p.style,{position:"absolute",background:e.settings.shim_bgcolor||"transparent",width:"100px",height:"100px",overflow:"hidden",zIndex:99999,opacity:e.settings.shim_bgcolor?"":0});p.className="plupload html5";if(e.settings.container){g=document.getElementById(e.settings.container);g.style.position="relative"}g.appendChild(p);p.innerHTML='<input id="'+e.id+'_html5" style="width:100%;" type="file" accept="'+n.join(",")+'" '+(e.settings.multi_selection?'multiple="multiple"':"")+" />";document.getElementById(e.id+"_html5").onchange=function(){d(this.files);this.value=""}});e.bind("PostInit",function(){var g=document.getElementById(e.settings.drop_element);if(g){b.addEvent(g,"dragover",function(h){h.preventDefault()});b.addEvent(g,"drop",function(i){var h=i.dataTransfer;if(h&&h.files){d(h.files)}i.preventDefault()})}});e.bind("Refresh",function(g){var h,i,j;h=document.getElementById(e.settings.browse_button);i=b.getPos(h,document.getElementById(g.settings.container));j=b.getSize(h);b.extend(document.getElementById(e.id+"_html5_container").style,{top:i.y+"px",left:i.x+"px",width:j.w+"px",height:j.h+"px"})});e.bind("UploadFile",function(g,j){var n=new XMLHttpRequest(),i=n.upload,h=g.settings.resize,m,l=0;function k(o){var s="----pluploadboundary"+b.guid(),q="--",r="\r\n",p="";if(g.settings.multipart){n.setRequestHeader("Content-Type","multipart/form-data; boundary="+s);b.each(g.settings.multipart_params,function(u,t){p+=q+s+r+'Content-Disposition: form-data; name="'+t+'"'+r+r;p+=u+r});p+=q+s+r+'Content-Disposition: form-data; name="'+g.settings.file_data_name+'"; filename="'+j.name+'"'+r+"Content-Type: application/octet-stream"+r+r+o+r+q+s+q+r;l=p.length-o.length;o=p}n.sendAsBinary(o)}if(j.status==b.DONE||j.status==b.FAILED||g.state==b.STOPPED){return}if(i){i.onprogress=function(o){j.loaded=o.loaded-l;g.trigger("UploadProgress",j)}}n.onreadystatechange=function(){var o;if(n.readyState==4){try{o=n.status}catch(p){o=0}j.status=b.DONE;j.loaded=j.size;g.trigger("UploadProgress",j);g.trigger("FileUploaded",j,{response:n.responseText,status:o});if(o>=400){g.trigger("Error",{code:b.HTTP_ERROR,message:"HTTP Error.",file:j,status:o})}}};n.open("post",b.buildUrl(g.settings.url,{name:j.target_name||j.name}),true);n.setRequestHeader("Content-Type","application/octet-stream");b.each(g.settings.headers,function(p,o){n.setRequestHeader(o,p)});m=c[j.id];if(n.sendAsBinary){if(h&&/\.(png|jpg|jpeg)$/i.test(j.name)){a(m.getAsDataURL(),h.width,h.height,/\.png$/i.test(j.name)?"image/png":"image/jpeg",function(o){if(o.success){j.size=o.data.length;k(o.data)}else{k(m.getAsBinary())}})}else{k(m.getAsBinary())}}else{n.send(m)}});f({success:true})}})})(plupload);
|
1
public/javascripts/admin/plugins/plupload/plupload.js
Normal file
1
public/javascripts/admin/plugins/plupload/plupload.silverlight.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
(function(c){var a={};function b(l){var k,j=typeof l,h,e,g,f;if(j==="string"){k="\bb\tt\nn\ff\rr\"\"''\\\\";return'"'+l.replace(/([\u0080-\uFFFF\x00-\x1f\"])/g,function(n,m){var i=k.indexOf(m);if(i+1){return"\\"+k.charAt(i+1)}n=m.charCodeAt().toString(16);return"\\u"+"0000".substring(n.length)+n})+'"'}if(j=="object"){e=l.length!==h;k="";if(e){for(g=0;g<l.length;g++){if(k){k+=","}k+=b(l[g])}k="["+k+"]"}else{for(f in l){if(l.hasOwnProperty(f)){if(k){k+=","}k+=b(f)+":"+b(l[f])}}k="{"+k+"}"}return k}if(l===h){return"null"}return""+l}function d(o){var r=false,f=null,k=null,g,h,i,q,j,m=0;try{try{k=new ActiveXObject("AgControl.AgControl");if(k.IsVersionSupported(o)){r=true}k=null}catch(n){var l=navigator.plugins["Silverlight Plug-In"];if(l){g=l.description;if(g==="1.0.30226.2"){g="2.0.30226.2"}h=g.split(".");while(h.length>3){h.pop()}while(h.length<4){h.push(0)}i=o.split(".");while(i.length>4){i.pop()}do{q=parseInt(i[m],10);j=parseInt(h[m],10);m++}while(m<i.length&&q===j);if(q<=j&&!isNaN(q)){r=true}}}}catch(p){r=false}return r}c.silverlight={trigger:function(j,f){var h=a[j],g,e;if(h){e=c.toArray(arguments).slice(1);e[0]="Silverlight:"+f;setTimeout(function(){h.trigger.apply(h,e)},0)}}};c.runtimes.Silverlight=c.addRuntime("silverlight",{getFeatures:function(){return{jpgresize:true,pngresize:true,chunks:true,progress:true,multipart:true}},init:function(l,m){var k,h="",j=l.settings.filters,g,f=document.body;if(!d("2.0.31005.0")||(window.opera&&window.opera.buildNumber)){m({success:false});return}a[l.id]=l;k=document.createElement("div");k.id=l.id+"_silverlight_container";c.extend(k.style,{position:"absolute",top:"0px",background:l.settings.shim_bgcolor||"transparent",zIndex:99999,width:"100px",height:"100px",overflow:"hidden",opacity:l.settings.shim_bgcolor?"":0.01});k.className="plupload silverlight";if(l.settings.container){f=document.getElementById(l.settings.container);f.style.position="relative"}f.appendChild(k);for(g=0;g<j.length;g++){h+=(h!=""?"|":"")+j[g].title+" | *."+j[g].extensions.replace(/,/g,";*.")}k.innerHTML='<object id="'+l.id+'_silverlight" data="data:application/x-silverlight," type="application/x-silverlight-2" style="outline:none;" width="1024" height="1024"><param name="source" value="'+l.settings.silverlight_xap_url+'"/><param name="background" value="Transparent"/><param name="windowless" value="true"/><param name="initParams" value="id='+l.id+",filter="+h+'"/></object>';function e(){return document.getElementById(l.id+"_silverlight").content.Upload}l.bind("Silverlight:Init",function(){var i,n={};l.bind("Silverlight:StartSelectFiles",function(o){i=[]});l.bind("Silverlight:SelectFile",function(o,r,p,q){var s;s=c.guid();n[s]=r;n[r]=s;i.push(new c.File(s,p,q))});l.bind("Silverlight:SelectSuccessful",function(){if(i.length){l.trigger("FilesAdded",i)}});l.bind("Silverlight:UploadChunkError",function(o,r,p,s,q){l.trigger("Error",{code:c.IO_ERROR,message:"IO Error.",details:q,file:o.getFile(n[r])})});l.bind("Silverlight:UploadFileProgress",function(o,s,p,r){var q=o.getFile(n[s]);if(q.status!=c.FAILED){q.size=r;q.loaded=p;o.trigger("UploadProgress",q)}});l.bind("Refresh",function(o){var p,q,r;p=document.getElementById(o.settings.browse_button);q=c.getPos(p,document.getElementById(o.settings.container));r=c.getSize(p);c.extend(document.getElementById(o.id+"_silverlight_container").style,{top:q.y+"px",left:q.x+"px",width:r.w+"px",height:r.h+"px"})});l.bind("Silverlight:UploadChunkSuccessful",function(o,r,p,u,t){var s,q=o.getFile(n[r]);s={chunk:p,chunks:u,response:t};o.trigger("ChunkUploaded",q,s);if(q.status!=c.FAILED){e().UploadNextChunk()}if(p==u-1){q.status=c.DONE;o.trigger("FileUploaded",q,{response:t})}});l.bind("Silverlight:UploadSuccessful",function(o,r,p){var q=o.getFile(n[r]);q.status=c.DONE;o.trigger("FileUploaded",q,{response:p})});l.bind("FilesRemoved",function(o,q){var p;for(p=0;p<q.length;p++){e().RemoveFile(n[q[p].id])}});l.bind("UploadFile",function(o,q){var r=o.settings,p=r.resize||{};e().UploadFile(n[q.id],c.buildUrl(o.settings.url,{name:q.target_name||q.name}),b({chunk_size:r.chunk_size,image_width:p.width,image_height:p.height,image_quality:p.quality||90,multipart:!!r.multipart,multipart_params:r.multipart_params||{},headers:r.headers}))});m({success:true})})}})})(plupload);
|
@ -18,14 +18,63 @@ var enableFileOrTextToggling = function() {
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var setupUploader = function() {
|
||||
var multipartParams = {};
|
||||
multipartParams[$('meta[name=csrf-param]').attr('content')] = $('meta[name=csrf-token]').attr('content');
|
||||
|
||||
var uploader = new plupload.Uploader({
|
||||
runtimes : 'html5,flash',
|
||||
container: 'theme-images',
|
||||
browse_button : 'upload-link',
|
||||
max_file_size : '5mb',
|
||||
url : $('a#upload-link').attr('href'),
|
||||
flash_swf_url : '/javascripts/admin/plugins/plupload/plupload.flash.swf',
|
||||
multipart: true,
|
||||
multipart_params: multipartParams
|
||||
});
|
||||
|
||||
uploader.bind('QueueChanged', function() {
|
||||
uploader.start();
|
||||
});
|
||||
|
||||
uploader.init();
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
enableFileOrTextToggling();
|
||||
|
||||
$('code.stylesheet textarea').each(function() { addCodeMirrorEditor('css', $(this)); });
|
||||
$('code.javascript textarea').each(function() {
|
||||
addCodeMirrorEditor('javascript', $(this), ["tokenizejavascript.js", "parsejavascript.js"]);
|
||||
// $('code.stylesheet textarea').each(function() {
|
||||
// addCodeMirrorEditor(null, $(this), ["tokenizejavascript.js", "parsejavascript.js", "parsecss.js"]);
|
||||
// });
|
||||
// $('code.javascript textarea').each(function() {
|
||||
// addCodeMirrorEditor(null, $(this), ["parsecss.js", "tokenizejavascript.js", "parsejavascript.js"]);
|
||||
// });
|
||||
|
||||
$('select#theme_asset_content_type').bind('change', function() {
|
||||
var editor = CodeMirrorEditors[0].editor;
|
||||
editor.setParser($(this).val() == 'stylesheet' ? 'CSSParser' : 'JSParser');
|
||||
});
|
||||
|
||||
$('a#asset-picker-link').fancybox({
|
||||
'onComplete': function() {
|
||||
setupUploader();
|
||||
|
||||
$('ul.assets h4 a').bind('click', function(e) {
|
||||
var editor = CodeMirrorEditors[0].editor;
|
||||
var handle = editor.cursorLine(), position = editor.cursorPosition(handle).character;
|
||||
var text = 'url("' + $(this).attr('href') + '")';
|
||||
|
||||
editor.insertIntoLine(handle, position, text);
|
||||
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
$.fancybox.close();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('a#asset-picker-link').click();
|
||||
});
|
@ -121,10 +121,10 @@ ul.assets li.asset h4 { margin: 0px; height: 30px; }
|
||||
|
||||
ul.assets li.asset h4 a {
|
||||
position: relative;
|
||||
top: 6px;
|
||||
top: 7px;
|
||||
left: 12px;
|
||||
font-weight: bold;
|
||||
font-size: 0.7em;
|
||||
font-size: 0.6em;
|
||||
color: #1f82bc;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
13
public/stylesheets/admin/box.css
Normal file
@ -0,0 +1,13 @@
|
||||
/* custom styles for fancybox */
|
||||
|
||||
div.asset-picker { width: 470px; position: relative; }
|
||||
div.asset-picker .actions { position: absolute; right: 4px; top: 0px; }
|
||||
div.asset-picker h2 {
|
||||
border-bottom:1px dotted #BBBBBD;
|
||||
color:#1E1F26;
|
||||
font-size:1.1em;
|
||||
font-weight:bold;
|
||||
padding-bottom:10px;
|
||||
}
|
||||
|
||||
div.asset-picker ul { overflow: auto; height: 471px; }
|
@ -54,6 +54,11 @@
|
||||
color: #8B8D9A;
|
||||
}
|
||||
|
||||
.button.small.add {
|
||||
padding-left: 24px;
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
||||
.button.remove, .button.remove span {
|
||||
color: #ff092c !important;
|
||||
font-size: 1.1em;
|
||||
|
@ -137,6 +137,10 @@ form.formtastic fieldset ol li p.inline-errors {
|
||||
font-size: 0.7em !important;
|
||||
}
|
||||
|
||||
form.formtastic fieldset ol li.more { text-align: right; width: auto; margin-right: 20px; line-height: 0.6em; }
|
||||
form.formtastic fieldset ol li.more a { text-decoration: none; color: #787A89; font-size: 0.7em; }
|
||||
form.formtastic fieldset ol li.more a:hover { text-decoration: underline; }
|
||||
|
||||
|
||||
/*form.formtastic hr { border-top: 2px solid #ccc; }*/
|
||||
|
||||
|
@ -1,10 +1,13 @@
|
||||
html {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.editbox {
|
||||
margin: .4em;
|
||||
padding: 0;
|
||||
font-family: monospace;
|
||||
font-size: 10pt;
|
||||
color: black;
|
||||
background: white url(/images/admin/form/field.png) repeat-x 0 0 !important;
|
||||
}
|
||||
|
||||
pre.code, .editbox {
|
||||
|
@ -17,6 +17,10 @@ h2 {
|
||||
font-size: 14pt;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
p.rel {
|
||||
padding-left: 2em;
|
||||
text-indent: -2em;
|
||||
|
59
public/stylesheets/admin/plugins/codemirror/jscolors.css
Normal file
@ -0,0 +1,59 @@
|
||||
html {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.editbox {
|
||||
margin: .4em;
|
||||
padding: 0;
|
||||
font-family: monospace;
|
||||
font-size: 10pt;
|
||||
color: black;
|
||||
}
|
||||
|
||||
pre.code, .editbox {
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.editbox p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
span.js-punctuation {
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
span.js-operator {
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
span.js-keyword {
|
||||
color: #770088;
|
||||
}
|
||||
|
||||
span.js-atom {
|
||||
color: #228811;
|
||||
}
|
||||
|
||||
span.js-variable {
|
||||
color: black;
|
||||
}
|
||||
|
||||
span.js-variabledef {
|
||||
color: #0000FF;
|
||||
}
|
||||
|
||||
span.js-localvariable {
|
||||
color: #004499;
|
||||
}
|
||||
|
||||
span.js-property {
|
||||
color: black;
|
||||
}
|
||||
|
||||
span.js-comment {
|
||||
color: #AA7700;
|
||||
}
|
||||
|
||||
span.js-string {
|
||||
color: #AA2222;
|
||||
}
|
@ -1,3 +1,7 @@
|
||||
html {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.editbox {
|
||||
margin: .4em;
|
||||
padding: 0;
|
||||
|
@ -1,10 +1,13 @@
|
||||
html {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.editbox {
|
||||
margin: .4em;
|
||||
padding: 0;
|
||||
font-family: monospace;
|
||||
font-size: 10pt;
|
||||
color: black;
|
||||
background: white url(/images/admin/form/field.png) repeat-x 0 0 !important;
|
||||
}
|
||||
|
||||
.editbox p {
|
||||
@ -44,7 +47,7 @@ span.xml-entity {
|
||||
}
|
||||
|
||||
span.xml-error {
|
||||
color: #F00;
|
||||
color: #F00 !important;
|
||||
}
|
||||
|
||||
span.xml-text {
|
||||
|
363
public/stylesheets/admin/plugins/fancybox.css
Executable file
@ -0,0 +1,363 @@
|
||||
/*
|
||||
* FancyBox - jQuery Plugin
|
||||
* Simple and fancy lightbox alternative
|
||||
*
|
||||
* Examples and documentation at: http://fancybox.net
|
||||
*
|
||||
* Copyright (c) 2008 - 2010 Janis Skarnelis
|
||||
*
|
||||
* Version: 1.3.1 (05/03/2010)
|
||||
* Requires: jQuery v1.3+
|
||||
*
|
||||
* Dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*/
|
||||
|
||||
#fancybox-loading {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
margin-top: -20px;
|
||||
margin-left: -20px;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
z-index: 1104;
|
||||
display: none;
|
||||
}
|
||||
|
||||
* html #fancybox-loading { /* IE6 */
|
||||
position: absolute;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#fancybox-loading div {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 40px;
|
||||
height: 480px;
|
||||
background-image: url('/images/admin/plugins/fancybox/fancybox.png');
|
||||
}
|
||||
|
||||
#fancybox-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: #000;
|
||||
z-index: 1100;
|
||||
display: none;
|
||||
}
|
||||
|
||||
* html #fancybox-overlay { /* IE6 */
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#fancybox-tmp {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
overflow: auto;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#fancybox-wrap {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
z-index: 1101;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#fancybox-outer {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #FFF;
|
||||
}
|
||||
|
||||
#fancybox-inner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
outline: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#fancybox-hide-sel-frame {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
#fancybox-close {
|
||||
position: absolute;
|
||||
top: -15px;
|
||||
right: -15px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background-image: url('/images/admin/plugins/fancybox/fancybox.png');
|
||||
background-position: -40px 0px;
|
||||
cursor: pointer;
|
||||
z-index: 1103;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#fancybox_error {
|
||||
color: #444;
|
||||
font: normal 12px/20px Arial;
|
||||
padding: 7px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#fancybox-content {
|
||||
height: auto;
|
||||
width: auto;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#fancybox-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
outline: none;
|
||||
line-height: 0;
|
||||
vertical-align: top;
|
||||
-ms-interpolation-mode: bicubic;
|
||||
}
|
||||
|
||||
#fancybox-frame {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#fancybox-title {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
font-family: Arial;
|
||||
font-size: 12px;
|
||||
z-index: 1102;
|
||||
}
|
||||
|
||||
.fancybox-title-inside {
|
||||
padding: 10px 0;
|
||||
text-align: center;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.fancybox-title-outside {
|
||||
padding-top: 5px;
|
||||
color: #FFF;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.fancybox-title-over {
|
||||
color: #FFF;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#fancybox-title-over {
|
||||
padding: 10px;
|
||||
background-image: url('/images/admin/plugins/fancybox/fancy_title_over.png');
|
||||
display: block;
|
||||
}
|
||||
|
||||
#fancybox-title-wrap {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#fancybox-title-wrap span {
|
||||
height: 32px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#fancybox-title-left {
|
||||
padding-left: 15px;
|
||||
background-image: url('/images/admin/plugins/fancybox/fancybox.png');
|
||||
background-position: -40px -90px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
#fancybox-title-main {
|
||||
font-weight: bold;
|
||||
line-height: 29px;
|
||||
background-image: url('/images/admin/plugins/fancybox/fancybox-x.png');
|
||||
background-position: 0px -40px;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
#fancybox-title-right {
|
||||
padding-left: 15px;
|
||||
background-image: url('/images/admin/plugins/fancybox/fancybox.png');
|
||||
background-position: -55px -90px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
#fancybox-left, #fancybox-right {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
height: 100%;
|
||||
width: 35%;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
background-image: url('/images/admin/plugins/fancybox/blank.gif');
|
||||
z-index: 1102;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#fancybox-left {
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
#fancybox-right {
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
#fancybox-left-ico, #fancybox-right-ico {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: -9999px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin-top: -15px;
|
||||
cursor: pointer;
|
||||
z-index: 1102;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#fancybox-left-ico {
|
||||
background-image: url('/images/admin/plugins/fancybox/fancybox.png');
|
||||
background-position: -40px -30px;
|
||||
}
|
||||
|
||||
#fancybox-right-ico {
|
||||
background-image: url('/images/admin/plugins/fancybox/fancybox.png');
|
||||
background-position: -40px -60px;
|
||||
}
|
||||
|
||||
#fancybox-left:hover, #fancybox-right:hover {
|
||||
visibility: visible; /* IE6 */
|
||||
}
|
||||
|
||||
#fancybox-left:hover span {
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
#fancybox-right:hover span {
|
||||
left: auto;
|
||||
right: 20px;
|
||||
}
|
||||
|
||||
.fancy-bg {
|
||||
position: absolute;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
#fancy-bg-n {
|
||||
top: -20px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
background-image: url('/images/admin/plugins/fancybox/fancybox-x.png');
|
||||
}
|
||||
|
||||
#fancy-bg-ne {
|
||||
top: -20px;
|
||||
right: -20px;
|
||||
background-image: url('/images/admin/plugins/fancybox/fancybox.png');
|
||||
background-position: -40px -162px;
|
||||
}
|
||||
|
||||
#fancy-bg-e {
|
||||
top: 0;
|
||||
right: -20px;
|
||||
height: 100%;
|
||||
background-image: url('/images/admin/plugins/fancybox/fancybox-y.png');
|
||||
background-position: -20px 0px;
|
||||
}
|
||||
|
||||
#fancy-bg-se {
|
||||
bottom: -20px;
|
||||
right: -20px;
|
||||
background-image: url('/images/admin/plugins/fancybox/fancybox.png');
|
||||
background-position: -40px -182px;
|
||||
}
|
||||
|
||||
#fancy-bg-s {
|
||||
bottom: -20px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
background-image: url('/images/admin/plugins/fancybox/fancybox-x.png');
|
||||
background-position: 0px -20px;
|
||||
}
|
||||
|
||||
#fancy-bg-sw {
|
||||
bottom: -20px;
|
||||
left: -20px;
|
||||
background-image: url('/images/admin/plugins/fancybox/fancybox.png');
|
||||
background-position: -40px -142px;
|
||||
}
|
||||
|
||||
#fancy-bg-w {
|
||||
top: 0;
|
||||
left: -20px;
|
||||
height: 100%;
|
||||
background-image: url('/images/admin/plugins/fancybox/fancybox-y.png');
|
||||
}
|
||||
|
||||
#fancy-bg-nw {
|
||||
top: -20px;
|
||||
left: -20px;
|
||||
background-image: url('/images/admin/plugins/fancybox/fancybox.png');
|
||||
background-position: -40px -122px;
|
||||
}
|
||||
|
||||
/* IE */
|
||||
|
||||
#fancybox-loading.fancybox-ie div { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_loading.png', sizingMethod='scale'); }
|
||||
.fancybox-ie #fancybox-close { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_close.png', sizingMethod='scale'); }
|
||||
|
||||
.fancybox-ie #fancybox-title-over { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_title_over.png', sizingMethod='scale'); zoom: 1; }
|
||||
.fancybox-ie #fancybox-title-left { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_title_left.png', sizingMethod='scale'); }
|
||||
.fancybox-ie #fancybox-title-main { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_title_main.png', sizingMethod='scale'); }
|
||||
.fancybox-ie #fancybox-title-right { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_title_right.png', sizingMethod='scale'); }
|
||||
|
||||
.fancybox-ie #fancybox-left-ico { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_nav_left.png', sizingMethod='scale'); }
|
||||
.fancybox-ie #fancybox-right-ico { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_nav_right.png', sizingMethod='scale'); }
|
||||
|
||||
.fancybox-ie .fancy-bg { background: transparent !important; }
|
||||
|
||||
.fancybox-ie #fancy-bg-n { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_n.png', sizingMethod='scale'); }
|
||||
.fancybox-ie #fancy-bg-ne { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_ne.png', sizingMethod='scale'); }
|
||||
.fancybox-ie #fancy-bg-e { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_e.png', sizingMethod='scale'); }
|
||||
.fancybox-ie #fancy-bg-se { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_se.png', sizingMethod='scale'); }
|
||||
.fancybox-ie #fancy-bg-s { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_s.png', sizingMethod='scale'); }
|
||||
.fancybox-ie #fancy-bg-sw { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_sw.png', sizingMethod='scale'); }
|
||||
.fancybox-ie #fancy-bg-w { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_w.png', sizingMethod='scale'); }
|
||||
.fancybox-ie #fancy-bg-nw { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_nw.png', sizingMethod='scale'); }
|