From aac8dcaac3363c67a15a6fbd77da900ff4d63dbe Mon Sep 17 00:00:00 2001 From: yasushiito Date: Sun, 27 May 2012 11:25:28 +0900 Subject: [PATCH] speach rename to speech --- app/assets/javascripts/common.js | 2387 +++++++++++++ app/assets/javascripts/system.js | 2061 +++++++++++ app/assets/javascripts/work.js | 3723 ++++++++++++++++++++ ...ch_baloons.css.scss => speech_baloons.css.scss} | 0 ...emplates.css.scss => speech_templates.css.scss} | 0 ...eachbaloons.css.scss => speechbaloons.css.scss} | 0 .../{speaches.css.scss => speeches.css.scss} | 0 app/controllers/panels_controller.rb | 2 +- .../speach_balloon_templates_controller.rb | 114 - .../speech_balloon_templates_controller.rb | 114 + ...controller.rb => speech_balloons_controller.rb} | 70 +- ...ontroller.rb => speech_templates_controller.rb} | 14 +- ...eaches_controller.rb => speeches_controller.rb} | 14 +- app/helpers/speach_balloon_templates_helper.rb | 2 - app/helpers/speach_balloons_helper.rb | 2 - app/helpers/speach_templates_helper.rb | 2 - app/helpers/speaches_helper.rb | 2 - app/helpers/speech_balloon_templates_helper.rb | 2 + app/helpers/speech_balloons_helper.rb | 2 + app/helpers/speech_templates_helper.rb | 2 + app/helpers/speeches_helper.rb | 2 + app/models/balloon.rb | 4 +- app/models/balloon_template.rb | 6 +- app/models/comic.rb | 4 +- app/models/panel.rb | 10 +- app/models/speach.rb | 3 - app/models/speach_balloon_template.rb | 12 - app/models/speach_template.rb | 3 - app/models/speech.rb | 3 + .../{speach_balloon.rb => speech_balloon.rb} | 4 +- app/models/speech_balloon_template.rb | 12 + app/models/speech_template.rb | 3 + app/views/balloon_templates/index.html.erb | 4 +- app/views/balloon_templates/list.html.erb | 4 +- app/views/layouts/application.html.erb | 12 +- app/views/layouts/test.html.erb | 6 +- app/views/panels/_standard.html.erb | 6 +- app/views/panels/index.html.erb | 6 +- app/views/speach_balloon_templates/_form.html.erb | 17 - app/views/speach_balloon_templates/index.html.erb | 26 - app/views/speach_balloon_templates/list.html.erb | 28 - app/views/speach_balloons/index.html.erb | 26 - app/views/speach_balloons/list.html.erb | 28 - app/views/speach_templates/index.html.erb | 21 - app/views/speach_templates/list.html.erb | 27 - app/views/speaches/index.html.erb | 26 - app/views/speaches/list.html.erb | 31 - app/views/speech_balloon_templates/_form.html.erb | 17 + .../browse.html.erb | 10 +- app/views/speech_balloon_templates/index.html.erb | 26 + app/views/speech_balloon_templates/list.html.erb | 28 + .../show.html.erb | 12 +- .../browse.html.erb | 10 +- app/views/speech_balloons/index.html.erb | 26 + app/views/speech_balloons/list.html.erb | 28 + .../show.html.erb | 12 +- app/views/speech_templates/index.html.erb | 21 + app/views/speech_templates/list.html.erb | 27 + app/views/speeches/index.html.erb | 26 + app/views/speeches/list.html.erb | 31 + app/views/system/browse.html.erb | 6 +- config/routes.rb | 8 +- .../20111206115439_create_balloon_templates.rb | 6 +- ...b => 20111206120252_create_speech_templates.rb} | 6 +- ...eaches.rb => 20111206130635_create_speeches.rb} | 10 +- ...rb => 20111208235818_create_speech_balloons.rb} | 6 +- ...120424100555_create_speach_balloon_templates.rb | 8 - ...120424100555_create_speech_balloon_templates.rb | 8 + db/schema.rb | 35 +- .../balloon_templates_controller_spec.rb | 2 +- .../speach_balloon_templates_controller_spec.rb | 157 - .../controllers/speach_balloons_controller_spec.rb | 12 - spec/controllers/speaches_controller_spec.rb | 14 - .../speech_balloon_templates_controller_spec.rb | 157 + .../controllers/speech_balloons_controller_spec.rb | 12 + ...spec.rb => speech_templates_controller_spec.rb} | 4 +- spec/controllers/speeches_controller_spec.rb | 14 + spec/factories.rb | 18 +- ....rb => speech_balloon_templates_helper_spec.rb} | 6 +- ...lper_spec.rb => speech_balloons_helper_spec.rb} | 6 +- ...per_spec.rb => speech_templates_helper_spec.rb} | 6 +- ...ches_helper_spec.rb => speeches_helper_spec.rb} | 6 +- spec/models/panel_spec.rb | 8 +- ...each_balloon_spec.rb => speech_balloon_spec.rb} | 2 +- ...ate_spec.rb => speech_balloon_template_spec.rb} | 2 +- spec/models/{speach_spec.rb => speech_spec.rb} | 206 +- ...ch_template_spec.rb => speech_template_spec.rb} | 2 +- 87 files changed, 9009 insertions(+), 839 deletions(-) create mode 100644 app/assets/javascripts/common.js create mode 100644 app/assets/javascripts/system.js create mode 100644 app/assets/javascripts/work.js rename app/assets/stylesheets/{speach_baloons.css.scss => speech_baloons.css.scss} (100%) rename app/assets/stylesheets/{speach_templates.css.scss => speech_templates.css.scss} (100%) rename app/assets/stylesheets/{speachbaloons.css.scss => speechbaloons.css.scss} (100%) rename app/assets/stylesheets/{speaches.css.scss => speeches.css.scss} (100%) delete mode 100644 app/controllers/speach_balloon_templates_controller.rb create mode 100644 app/controllers/speech_balloon_templates_controller.rb rename app/controllers/{speach_balloons_controller.rb => speech_balloons_controller.rb} (50%) rename app/controllers/{speach_templates_controller.rb => speech_templates_controller.rb} (51%) rename app/controllers/{speaches_controller.rb => speeches_controller.rb} (57%) delete mode 100644 app/helpers/speach_balloon_templates_helper.rb delete mode 100644 app/helpers/speach_balloons_helper.rb delete mode 100644 app/helpers/speach_templates_helper.rb delete mode 100644 app/helpers/speaches_helper.rb create mode 100644 app/helpers/speech_balloon_templates_helper.rb create mode 100644 app/helpers/speech_balloons_helper.rb create mode 100644 app/helpers/speech_templates_helper.rb create mode 100644 app/helpers/speeches_helper.rb delete mode 100644 app/models/speach.rb delete mode 100644 app/models/speach_balloon_template.rb delete mode 100644 app/models/speach_template.rb create mode 100644 app/models/speech.rb rename app/models/{speach_balloon.rb => speech_balloon.rb} (64%) create mode 100644 app/models/speech_balloon_template.rb create mode 100644 app/models/speech_template.rb delete mode 100644 app/views/speach_balloon_templates/_form.html.erb delete mode 100644 app/views/speach_balloon_templates/index.html.erb delete mode 100644 app/views/speach_balloon_templates/list.html.erb delete mode 100644 app/views/speach_balloons/index.html.erb delete mode 100644 app/views/speach_balloons/list.html.erb delete mode 100644 app/views/speach_templates/index.html.erb delete mode 100644 app/views/speach_templates/list.html.erb delete mode 100644 app/views/speaches/index.html.erb delete mode 100644 app/views/speaches/list.html.erb create mode 100644 app/views/speech_balloon_templates/_form.html.erb rename app/views/{speach_balloons => speech_balloon_templates}/browse.html.erb (64%) create mode 100644 app/views/speech_balloon_templates/index.html.erb create mode 100644 app/views/speech_balloon_templates/list.html.erb rename app/views/{speach_balloon_templates => speech_balloon_templates}/show.html.erb (57%) rename app/views/{speach_balloon_templates => speech_balloons}/browse.html.erb (64%) create mode 100644 app/views/speech_balloons/index.html.erb create mode 100644 app/views/speech_balloons/list.html.erb rename app/views/{speach_balloons => speech_balloons}/show.html.erb (57%) create mode 100644 app/views/speech_templates/index.html.erb create mode 100644 app/views/speech_templates/list.html.erb create mode 100644 app/views/speeches/index.html.erb create mode 100644 app/views/speeches/list.html.erb rename db/migrate/{20111206120252_create_speach_templates.rb => 20111206120252_create_speech_templates.rb} (59%) rename db/migrate/{20111206130635_create_speaches.rb => 20111206130635_create_speeches.rb} (55%) rename db/migrate/{20111208235818_create_speach_balloons.rb => 20111208235818_create_speech_balloons.rb} (58%) delete mode 100644 db/migrate/20120424100555_create_speach_balloon_templates.rb create mode 100644 db/migrate/20120424100555_create_speech_balloon_templates.rb delete mode 100644 spec/controllers/speach_balloon_templates_controller_spec.rb delete mode 100644 spec/controllers/speach_balloons_controller_spec.rb delete mode 100644 spec/controllers/speaches_controller_spec.rb create mode 100644 spec/controllers/speech_balloon_templates_controller_spec.rb create mode 100644 spec/controllers/speech_balloons_controller_spec.rb rename spec/controllers/{speach_templates_controller_spec.rb => speech_templates_controller_spec.rb} (58%) create mode 100644 spec/controllers/speeches_controller_spec.rb rename spec/helpers/{speach_balloon_templates_helper_spec.rb => speech_balloon_templates_helper_spec.rb} (70%) rename spec/helpers/{speach_balloons_helper_spec.rb => speech_balloons_helper_spec.rb} (75%) rename spec/helpers/{speach_templates_helper_spec.rb => speech_templates_helper_spec.rb} (74%) rename spec/helpers/{speaches_helper_spec.rb => speeches_helper_spec.rb} (77%) rename spec/models/{speach_balloon_spec.rb => speech_balloon_spec.rb} (76%) rename spec/models/{speach_balloon_template_spec.rb => speech_balloon_template_spec.rb} (71%) rename spec/models/{speach_spec.rb => speech_spec.rb} (53%) rename spec/models/{speach_template_spec.rb => speech_template_spec.rb} (75%) diff --git a/app/assets/javascripts/common.js b/app/assets/javascripts/common.js new file mode 100644 index 00000000..c37ca430 --- /dev/null +++ b/app/assets/javascripts/common.js @@ -0,0 +1,2387 @@ +/* + * pettanR common.js + * version 0.4.19 + * + * author: itozyun + */ + +/* + * http://pettanr.sourceforge.jp/test/type.html + */ + var Type = { + isObject : function(v) { + return v !== null && Type.isArray(v) === false && typeof v === 'object'; + }, + isFunction : function(v) { + return typeof v === 'function'; + }, + isArray : function(v) { + return Object.prototype.toString.call(v) === "[object Array]"; + }, + isBoolean : function(v) { + return typeof v === 'boolean'; + }, + isString : function(v) { + return typeof v === 'string'; + }, + isNumber : function(v) { + return typeof v === 'number'; + }, + isFinite : function(v){ + return Type.isNumber(v) === true && isFinite(v); + }, + isHTMLElement : function(v){ + if( 'HTMLElement' in window ){ + Type.isHTMLElement = function(v){ + return v instanceof HTMLElement; + } + } else { + Type.isHTMLElement = function(v) { + if( Type.isObject(v) === false ){ + return false; + } + var r; + if(v && v.nodeType === 1){ + try{ + r = v.cloneNode(false); + } catch(n) { + return false; + } + if(r === v) return false; + try{ + r.nodeType = 9; + return r.nodeType === 1; + } catch(n) {} + return true; + } + return false; + } + } + return Type.isHTMLElement(v); + }, + /* + isElementCollection : function(v) { + return (Object.prototype.toString.call(v) === "[object HTMLCollection]"); + }, + */ + isNull : function(v) { + return v === null; + }, + isUndefined : function(v) { + return typeof v === 'undefined'; + } + }; + + +var pettanr = ( function(){ + var FUNCTION_ARRAY = [], + URL = document.location.href.split( '#')[ 0], + IS_LOCAL = URL.indexOf( 'file:') === 0, + URL_PARAMS = ( function(){ + var search = document.location.search, + l = search.length; + if( 1 < l){ + var query = search.substring( 1), + params = query.split( '&'), + ret = {}, elm, name, v; + while( params.length > 0){ + elm = params.shift().split( '='); + name = decodeURIComponent( elm[ 0]); + if( elm.length === 2){ + v = decodeURIComponent( elm[ 1]); + if( '' + parseFloat( v) === v) v = parseFloat( v); + if( '' + parseInt( v, 10 ) === '0' + v) v = parseInt( v, 10 ); + if( v === 'true') v = true; + if( v === 'false') v = false; + if( v === 'null') v = null; + if( v === 'undefined') v = undefined; + ret[ name] = v; + } else + if( elm.length === 1){ + ret[ name] = true; + } + } + return ret; + } + return {}; + })(), + IS_DEBUG = Type.isBoolean( URL_PARAMS.debug ) ? URL_PARAMS.debug : IS_LOCAL === true, + jqWindow , jqDocument , jqBody; + return { + version: '0.4.19', + init: function(){ + jqWindow = $( window); + jqDocument = $( document); + jqBody = $( document.body); + + var l = FUNCTION_ARRAY.length, + _fn; + for( var i=0; i array + for( i=0, l=_children.length; i document.createElement( 'img') + */ + function loadImage( images, abspath, onLoad, onError, delay, timeout) { + images = images || document.images; + var img, + i = 0, l = images.length, + tick = 0; + for(; i < l; ++i) { + img = images[i]; + if ( img.src === abspath && img.complete) { + var size = pettanr.util.getImageSize( img); + onLoad( abspath, size.width, size.height); + return; + } + } + img = document.createElement( 'img'); //var img = new Image(); ではieでimgのsizeが取れない、、、removeChildも失敗し、imgSizeGetterにimgが残る + img.finish = false; + img.onabort = img.onerror = function() { + if (img.finish) { return; } + img.finish = true; + onError(abspath); + img.onload = img.onabort = img.onerror = ""; + }; + img.onload = function() { + img.finish = true; + if (window.opera && !img.complete) { + onError(abspath); + img.onload = img.onabort = img.onerror = ""; + return; + } + var size = pettanr.util.getImageSize( img); + onLoad( abspath, size.width, size.height); + img.onload = img.onabort = img.onerror = ""; + //img = void 0; + }; + img.src = abspath; + if (!img.finish && timeout) { + setTimeout(function() { + if (img.finish) { return; } + if (img.complete) { + img.finish = true; + if (img.width) { return; } + onError(abspath); + img.onload = img.onabort = img.onerror = ""; + return; + } + if ((tick += delay) > timeout) { + img.finish = true; + onError(abspath); + img.onload = img.onabort = img.onerror = ""; + return; + } + setTimeout(arguments.callee, delay); + }, 0); + } + } + }, + getAbsolutePath: function( path) { + var e = document.createElement("div"); + e.innerHTML = ''; + return e.firstChild.href; + }, + getAbsolutePosition: function( _elm){ + // Find the destination's position + var destx = _elm.offsetLeft, + desty = _elm.offsetTop, + thisNode = _elm, + body = document.body; + while (thisNode.offsetParent && thisNode.offsetParent !== body){ + thisNode = thisNode.offsetParent; + destx += thisNode.offsetLeft; + desty += thisNode.offsetTop; + } + return { + x: destx, + y: desty + } + }, + pullHtmlAsTemplete: function( IDorELM){ + if( typeof IDorELM === 'string'){ + IDorELM = document.getElementById( IDorELM); + } + if( !IDorELM) return; + IDorELM.parentNode && IDorELM.parentNode.removeChild( IDorELM); + if( IDorELM.id && IDorELM.id.indexOf( 'templete-') === 0){ + IDorELM.removeAttribute( 'id'); + } + return IDorELM; + }, + getElementsByClassName: function( _elm, _className, opt_tagName){ + var _all = !opt_tagName || opt_tagName === '*', + _nodes = _all === true ? ( _elm.all || _elm.getElementsByTagName( '*')) : _elm.getElementsByTagName( opt_tagName), + _node, _classes, ret = []; + for( var i=0, l = _nodes.length; i' : 'iframe'); + + if( ua.isIE){ + el.onreadystatechange = detect; + } else { + // iron(chrome) の場合、append の前に onload を指定しないと onload が呼ばれない + el.onload = onLoad; + //setTimeout( asynkCallback, 0 ); + } + + document.body.appendChild( el); + el.id = el.name = id; + el.setAttribute( 'name', id); + el.style.cssText = 'width:1px;height:1px;visibility:hidden;position:absolute;top:1px;left:1px;'; + // http://d.hatena.ne.jp/onozaty/20070830/p1 + // [JavaScript]IE6ではJavaScriptで動的に作成したiframeに対してsubmitできない(IE7は未確認) ->解決 + el.contentWindow.name = id; + + window[id] = el; + + function detect(){ + if ( this.readyState === "complete") { + this.onreadystatechange = new Function(); + this.onreadystatechange = null; + setTimeout( asynkCallback, 0 ); + } + } + function onLoad(){ + el.onload = null; + setTimeout( asynkCallback, 0 ); + } + function asynkCallback(){ + callback( el ); + } + } + } +})(); + +/* + * pettanr.ua + * + * detect userAgent + * detect plug in + */ +pettanr.ua = ( function(){ + var ua = (function(){ + var acme = {}; + + var n = navigator; + var dua = n.userAgent; + var dav = n.appVersion; + var tv = parseFloat(dav); + acme.isOpera = (dua.indexOf("Opera") >= 0) ? tv: undefined; + acme.isKhtml = (dav.indexOf("Konqueror") >= 0) ? tv : undefined; + acme.isWebKit = parseFloat(dua.split("WebKit/")[1]) || undefined; + acme.isChrome = parseFloat(dua.split("Chrome/")[1]) || undefined; + var index = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0); + if(index && !acme.isChrome){ + acme.isSafari = parseFloat(dav.split("Version/")[1]); + if(!acme.isSafari || parseFloat(dav.substr(index + 7)) <= 419.3){ + acme.isSafari = 2; + } + } + if(document.all && !acme.isOpera){ + acme.isIE = parseFloat(dav.split("MSIE ")[1]) || undefined; + } + + return acme; + })(), + isIE = navigator.userAgent.toLowerCase().indexOf( 'msie') !== -1, + ieVersion = isIE === true ? parseInt( navigator.appVersion.toLowerCase().replace( /.*msie[ ]/, '').match( /^[0-9]+/)) : 0, + ieRenderingVersion = ieVersion === 8 ? document.documentMode : ieVersion, + isStanderdMode = document.compatMode === 'CSS1Compat', + ActiveX = ( function(){ + if( isIE === false || ieVersion > 8) return false; + var b = document.body, + c = b.className || '', + x, + ret = pettanr.URL_PARAMS.ActiveX, + ns = 'pettanr-ActiveX-', + enabled = 'enabled', + disabled = 'disabled'; + if( ret !== true && ret !== false){ + if( pettanr.util.hasClassName( b, ns + enabled) === true) return true; + if( pettanr.util.hasClassName( b, ns + disabled) === true) return false; + x = document.createElement('div'); + b.appendChild(x); + x.style.cssText = 'width:1px;height:1px;line-height:1px;filter:progid:DXImageTransform.Microsoft.Shadow()'; + ret = x.offsetHeight > 1; + b.removeChild(x); + } + b.className += [ c !== '' ? ' ' : c, ns, ret === true ? enabled : disabled ].join( ''); + return ret; + })(), + VML = ( function(){ + if( ActiveX === false || isIE === false || ieVersion > 8) return false; + var globalObjectName = pettanr.util.createGlobalUniqueName(), + script, + id = 'detectVML'; + document.write( [ ''].join( '')); + if( window[globalObjectName] === 1){ + script = document.getElementById( id); + script.parentNode.removeChild( script); + window[globalObjectName] = null; + return true; + } + return false; + })(), + isStandAloneMode = ( function(){ + if( isIE === false) return false; + if( VML === true) return false; + var globalObjectName = pettanr.util.createGlobalUniqueName(), + script, + id = 'detectStandAlone'; + document.write( [ ''].join( '')); + if( window[globalObjectName] === 1){ + script = document.getElementById( id); + script.parentNode.removeChild( script); + window[globalObjectName] = null; + return false; + } + return true; + })(); + return { + IE: ua.isIE, + GECKO: 0, + OPERA: ua.isOpera, + KHTML: ua.isKhtml, + WEBKIT: ua.isWebKit, + CHROME: ua.isChrome, + isIE: isIE, + ieVersion: ieVersion, + ieRenderingVersion: ieRenderingVersion, + isStanderdMode: isStanderdMode, + VENDER_PREFIX: ( function() { + var ua = navigator.userAgent.toLowerCase(); + if ( ua.indexOf('opera') !== -1) { + return 'O'; + } else if ( ua.indexOf('msie') !== -1) { + return 'ms'; + } else if ( ua.indexOf('webkit') !== -1) { + return 'webkit'; + } else if ( navigator.product === 'Gecko') { + return 'Moz'; + } + return ''; + })(), + ACTIVEX: ActiveX, + VML: VML, + STANDALONE: isStandAloneMode, + startVML: function(){ + delete this.startVML; + if( pettanr.ua.VML !== true) return false; + if (!document.namespaces["v"]) { + document.namespaces.add("v", "urn:schemas-microsoft-com:vml", "#default#VML"); + } + document.createStyleSheet().cssText = "v\:shape,v\:image{behavior:url(#default#VML);display:block;};"; + } + } +})(); + + +pettanr.CONST = ( function(){ + var isLocal = pettanr.LOCAL === true || pettanr.URL_PARAMS.exjson === false, + isLocalhost = document.location.href.indexOf( 'http:\/\/localhost:3000\/' ) === 0, + PETTANR_ROOT_PATH = isLocalhost === true ? 'http:\/\/localhost:3000\/' : 'http:\/\/pettanr.heroku.com\/'; + + return { + PETTANR_ROOT_PATH: PETTANR_ROOT_PATH, + URL_ORIGINAL_PICTURES_JSON: ( isLocal === true ? 'json\/' : PETTANR_ROOT_PATH) + 'original_pictures.json', + URL_RESOURCE_PICTURES_JSON: ( isLocal === true ? 'json\/' : PETTANR_ROOT_PATH) + 'resource_pictures.json', + URL_COMICS_JSON: ( isLocal === true ? 'json\/' : PETTANR_ROOT_PATH) + 'comics.json', + URL_PANELS_JSON: ( isLocal === true ? 'json\/' : PETTANR_ROOT_PATH) + 'panels.json', + NS_PETTANR_COMIC: 'pettanr-comic', + RESOURCE_PICTURE_PATH: ( isLocal === true ? '' : PETTANR_ROOT_PATH) + 'resource_pictures\/', + CREATE_COMIC_JS: isLocal === true ? 'js\/create_new_comic.js' : PETTANR_ROOT_PATH + 'comics\/new.js', + CREATE_PANEL_JS: isLocal === true ? 'js\/create_new_panel.js' : PETTANR_ROOT_PATH + 'panels\/new.js', + UPLOAD_PICTURE_JS: isLocal === true ? 'js\/upload_picture.js' : PETTANR_ROOT_PATH + 'original_pictures\/new.js', + REGISTER_ARTIST_JS: isLocal === true ? 'js\/register_artist.js' : PETTANR_ROOT_PATH + 'artists\/new.js', + JQUERY_URL: isLocal === true ? 'javascripts\/jquery-1.6.2.min.js' : PETTANR_ROOT_PATH + 'assets\/jquery-162_min.js' + } +})(); + +pettanr.view = ( function(){ + /* create iframe overlay for user console */ + var location = document.location.pathname, + isWorkPage = document.location.href.indexOf( 'http:\/\/localhost:3000\/' ) === 0 || + document.location.href.indexOf( pettanr.CONST.PETTANR_ROOT_PATH ) === 0 || + location.indexOf( '\/work.html') !== -1 || + location.indexOf( '\work.html') !== -1, // for ie6 + deep = location.indexOf( '\/diary\/') !== -1 || + location.indexOf( '\/test\/') !== -1 || + location.indexOf( '\/help\/') !== -1 || + location.indexOf( '\/sitemap\/') !== -1 || + location.indexOf( '\/wiki\/') !== -1, + LoginUserNavi; + + if( isWorkPage === false){ + LoginUserNavi = { + show: function(){ + var i = pettanr.util.getChildIndex( this.parentNode, this ); + document.location.href = [ + deep === true ? '../' : '', + 'work.html', + typeof i === 'number' ? '?view=' + i : '' + ].join( ''); + return false; + }, + hide: function(){} + } + } else { + LoginUserNavi = { + show: function(){ + var i = pettanr.util.getChildIndex( this.parentNode, this ); + i !== -1 && bootApplication( i ); + return false; + }, + hide: function(){} + } + } + + /* debug info */ + // ua version, lang, os, plugin ( vml, svg), standerdmode, balloon, rimg + +/* + * window resize event, overlay と currentなviewに流す + * view modeの保持 + * editor, overlay, comic-viewer, image-explorer + * fadeIn, faseOut + */ + + var jqWindow, + APPLICATION_LIST = [], + LUNCHER_APPLICATION_LIST = [], + currentApplication = null; + + var AbstractBasicPane = function(){ + this.rootElement = null; + this.parentElement = null; + this.nextSibling = null; + this.onOpen = function( _w, _h /*, _option */ ){ + // overrride + }; + this.onClose = function(){ + // overrride + return true; + } // false の場合、close の拒否 + this.onPaneResize = function( _w, _h ){} + this.open = function( _w, _h /*, _option */ ){ + if( this.nextSibling && this.nextSibling.parentNode === this.parentElement ){ + this.parentElement.insertBefore( this.rootElement, this.nextSibling ); + } else + if( this.parentElement ){ + this.parentElement.appendChild( this.rootElement ); + } else { + this.rootElement && document.body.appendChild( this.rootElement ); + } + if( this.MIN_WIDTH > _w || this.MIN_HEIGHT > _h ){ + if( Type.isHTMLElement( this.rootElement ) === true ){ + // 小さすぎる!、と表示 + } + } + if( arguments.length > 2){ + // argumentsRellay( this.onOpen, arguments ); + this.onOpen.apply( this, arguments ); + } else { + this.onOpen( _w, _h ); + } + } + this.close = function(){ + if( this.onClose() === false ){ + + } + if( this.rootElement && this.rootElement.parentNode ){ + this.rootElement.parentNode.removeChild( this.rootElement ); + } + } + this.resize = function( _w, _h ){ + if( this.MIN_WIDTH > _w || this.MIN_HEIGHT > _h ){ + if( Type.isHTMLElement( this.rootElement ) === true ){ + // 小さすぎる!、と表示 + } + return; + } + this.onPaneResize( _w, _h ); + } + this.MIN_WIDTH = 240; + this.MIN_HEIGHT = 240; + } + + var AbstractApplication = function(){ + this.displayName = 'app name'; + this.ID = 'app id'; + } + AbstractApplication.prototype = new AbstractBasicPane(); + + var ApplicationReference = function( _application ){ + this.inOverlay = false; + this.boot = function( /* _option */ ){ + if( arguments.length > 0 ){ + bootApplication( _application, pettanr.util.copyArray( arguments ) ); + } else { + bootApplication( _application ); + } + } + this.bootInOverlay = function( /* _option */ ){ + this.inOverlay = true; + pettanr.overlay.show( _application ); + + if( arguments.length > 0 ){ + var _arguments = pettanr.util.copyArray( arguments ); + _arguments.unshift( jqWindow.width(), jqWindow.height() ) + // argumentsRellay( _application.open, _arguments ); + _application.open.apply( _application, _arguments ); + } else { + _application.open( jqWindow.width(), jqWindow.height() ); + } + } + this.shutdown = function(){ + if( this.inOverlay === true ){ + pettanr.overlay.hide(); + _application.close(); + this.inOverlay = false; + } else { + bootApplication( 0 ); + } + } + this.addToLancher = function(){ + if( pettanr.util.getIndex( LUNCHER_APPLICATION_LIST, _application ) !== -1 ) return; + LUNCHER_APPLICATION_LIST.push( _application ); + + var navi = document.getElementById('global-navi'), + item = document.createElement('a'); + navi.appendChild( item ); + navi.style.width = ( ( item.offsetWidth || 80 ) * LUNCHER_APPLICATION_LIST.length ) + 'px'; + item.href = '#'; + item.appendChild( document.createTextNode( _application.displayName )); + item.onclick = LoginUserNavi.show; + } + } + + function bootApplication( APPLICATIONorINDEX, _arguments ){ + if( isWorkPage === false ) return; + + var _application, + i, j, l, + nodesA = document.getElementById('global-navi').getElementsByTagName( 'a') || [], + _index = -1; + if( typeof APPLICATIONorINDEX === 'number' && APPLICATIONorINDEX < LUNCHER_APPLICATION_LIST.length){ + _application = LUNCHER_APPLICATION_LIST[ APPLICATIONorINDEX ]; + } else + if( typeof APPLICATIONorINDEX === 'string' ){ + for( i=0, l=LUNCHER_APPLICATION_LIST.length; i 0 ){ + var _arg = []; + for( i=0; i overlay -> view + * + */ +pettanr.form = ( function(){ + var FORM_GROUP_TABLE = {}, + currentID = null, + currentItem = null, + ELM_A_ORIGIN = ( function(){ + var ret = document.createElement( 'a'); + ret.href = '#'; + return ret; + })(), + ELM_INPUT_TEXT = ( function(){ + var ret = document.createElement( 'input'); + ret.type = 'text'; + return ret; + })(); + + var InputTextClass = function( WRAPPER_ELM, ON_UPDATE_FUNCTION, GROUP_ID, validater){ + validater = typeof validater === 'function' ? validater : null; + + var elmValue = pettanr.util.getElementsByClassName( WRAPPER_ELM, 'editable-value' )[ 0], + value, + index = GROUP_ID ? FORM_GROUP_TABLE[ GROUP_ID].length : -1, + instance, + focus = false, + visible = true, + enabled = true, + elmA = ELM_A_ORIGIN.cloneNode( true ); + + if( elmValue === undefined){ + alert( 'error!'); + } + value = elmValue.innerHTML; + elmValue.innerHTML = ''; + elmValue.className += ' editable-text'; + try { + elmA.innerHTML = value; + } catch(e){ + alert( value + elmA) + } + + elmValue.appendChild( elmA ); + WRAPPER_ELM.onclick = onClick; + + function onClick( e){ + focus = true; + start( instance); + elmA.style.display = 'none'; + elmValue.appendChild( ELM_INPUT_TEXT); + ELM_INPUT_TEXT.value = value; + ELM_INPUT_TEXT.focus(); + ELM_INPUT_TEXT.select(); + e && e.preventDefault(); + return false; + } + + return { + init: function(){ + instance = this; + delete this.init; + }, + value: function( _value){ + if( _value !== undefined){ + elmA.innerHTML = _value; + value = _value; + + if( focus === true){ + ELM_INPUT_TEXT.value = value; + } + } + currentItem === instance && this.finish(); + return value; + }, + start: function(){ + onClick(); + }, + finish: function( keep){ + var _newValue = ELM_INPUT_TEXT.value, + _validated = validater !== null ? '' + validater( _newValue) : _newValue; + _newValue = keep !== true ? _validated : value; + + elmValue.removeChild( ELM_INPUT_TEXT); + + elmA.innerHTML = _newValue; + elmA.style.display = 'block'; + + ON_UPDATE_FUNCTION && _newValue !== value && ON_UPDATE_FUNCTION( _newValue, value); + finish( instance); + value = _newValue; + focus = false; + }, + enabled: function(){ + return enabled; + }, + visible: function( _visible){ + if( _visible === true){ + WRAPPER_ELM.style.display = ''; + visible = true; + } else + if( _visible === false){ + WRAPPER_ELM.style.display = 'none'; + visible = false; + } + return visible; + }, + index : index, + groupID: GROUP_ID + } + } + + var FileInputClass = function( WRAPPER_ELM, ON_UPDATE_FUNCTION, GROUP_ID, validater, elmFileInput){ + validater = typeof validater === 'function' ? validater : null; + + var elmFilePath = pettanr.util.getElementsByClassName( WRAPPER_ELM, 'file-path')[ 0], + value, + index = GROUP_ID ? FORM_GROUP_TABLE[ GROUP_ID].length : -1, + instance, + focus = false, + visible = true, + enabled = true; + elmFileInput = WRAPPER_ELM.getElementsByTagName('input')[0] || elmFileInput || document.createElement( 'input'); + elmFileInput.type = 'file'; + elmFileInput.style.visivility = 'hidden'; + + WRAPPER_ELM.onclick = onClick; + elmFileInput.onchenge = onChange; + + function onClick( e){ + focus = true; + start( instance); + elmFileInput.click(); + return false; + } + + function onChange(){ + elmFilePath.innerHTML = elmFileInput.value; + } + return { + init: function(){ + instance = this; + delete this.init; + }, + start: function(){ + onClick(); + }, + finish: function( keep){ + focus = false; + }, + enabled: function(){ + return enabled; + }, + visible: function( _visible){ + if( _visible === true){ + WRAPPER_ELM.style.display = ''; + visible = true; + } else + if( _visible === false){ + WRAPPER_ELM.style.display = 'none'; + visible = false; + } + return visible; + }, + index : index, + groupID: GROUP_ID + } + } + + + function start( _currentItem){ + currentItem !== _currentItem && currentItem && currentItem.finish(); + currentItem = _currentItem; + } + function finish( _currentItem){ + if( currentItem !== _currentItem) return; + currentItem = null; + } + + function tabShift( _groupID, _index, _way){ + var GROUP_ARRAY = FORM_GROUP_TABLE[ _groupID] || [], + l = GROUP_ARRAY.length, + i = _index +_way; + if( l < 2) return; + while( i !== _index){ + i = i < 0 ? + l -1 : + i === l ? 0 : i; // 0 < i < l + if( GROUP_ARRAY[ i].enabled() === true && GROUP_ARRAY[ i].visible() === true) break; + i += _way; + } + if( i === _index) return; + setTimeout( GROUP_ARRAY[ i].start, 0); + } + + return { + init: function(){}, + focus: function(){ + return currentItem !== null; + }, + keyEventRellay: function( e){ + if( e.type === 'keyup') return false; + if( currentItem === null) return false; + + var keyCode = e.keyCode; + if( keyCode === 13 || keyCode === 27 || keyCode === 9 || keyCode === 18 || e.altKey === true){ // 13.return 27.esc 9.tab 18.alt + var _groupID = currentItem.groupID, + _index = currentItem.index; + currentItem.finish( keyCode === 27); + keyCode === 9 && _groupID && tabShift( _groupID, _index, e.shiftKey === true ? -1 : 1); + keyCode === 13 && _groupID && tabShift( _groupID, _index, 1); + } + return true; + }, + createInputText: function( _elm, _onUpdate, _groupID, _validater){ + if( typeof _groupID === 'string' && !FORM_GROUP_TABLE[ _groupID]){ + FORM_GROUP_TABLE[ _groupID] = []; + } + var ret = new InputTextClass( _elm, _onUpdate, _groupID, _validater); + ret.init(); + _groupID && FORM_GROUP_TABLE[ _groupID].push( ret); + return ret; + }, + createFileInput: function( _elm, _onUpdate, _groupID, _validater, _elmFileInput){ + if( typeof _groupID === 'string' && !FORM_GROUP_TABLE[ _groupID]){ + FORM_GROUP_TABLE[ _groupID] = []; + } + var ret = FileInputClass( _elm, _onUpdate, _groupID, _validater, _elmFileInput); + ret.init(); + _groupID && FORM_GROUP_TABLE[ _groupID].push( ret); + return ret; + }, + createCheckBox: function(){ + + }, + createRadio: function(){ + + }, + createButton: function(){ + + }, + createListBox: function(){ + + } + } +})(); + + +/* ---------------------------------------- + * Vector Support + * + * __________ + * / \ + * / \ + * |,startX,Y | + * tailX,Y - < | + * |'endX,Y | + * \ / + * \__________/ + * + * SVG + * ----------------------- + * ie9, other modern browser + * + * XML + * ----------------------- + * ie5.5-8 + * + * 内部の角度計算は radian で統一したい。 + * 当初 vectorEnabled = true で一度書いてみる。 + * 駄目なら、代替のイメージのsrcの用意もここで担当。 + * 閲覧と編集両方で使う。 + * + */ +pettanr.balloon = ( function() { + var MIN_BALLOON_WIDTH = 30, + MIN_BALLOON_HEIGHT = 30, + TAIL_WIDTH = 6, + TAIL_HEIGHT = 10, + STROKE_WIDTH = 1.2, + PADDING_TOP = TAIL_HEIGHT, + PADDING_LEFT = TAIL_HEIGHT, + ACCURACY = 1, // 有効少数桁 + IS_VML = pettanr.ua.isIE === true && pettanr.ua.ieVersion < 9, + ELM_BALLOON_ORIGIN = ( function(){ + var ret; + try { + if( IS_VML === true){ + ret = document.createElement( 'DIV'); + var shape = document.createElement( 'v:shape'); + shape.coordorigin = "0,0"; + shape.strokecolor = "black"; + shape.strokeweight = STROKE_WIDTH; + shape.fillcolor = "white"; + ret.appendChild( shape); + } else { + var kSVGNS = 'http://www.w3.org/2000/svg'; + ret = document.createElementNS( kSVGNS, 'svg'); + var path = document.createElementNS( kSVGNS, 'path'); + path.setAttribute( 'fill', "white"); + path.setAttribute( 'stroke', "black"); + path.setAttribute( 'strokeWidth', STROKE_WIDTH); + ret.appendChild( path); + } + return ret; + } catch( e){ + return null; + } + })(), + NUM_BALLOON_IMAGE = 24, + vectorEnabled = ELM_BALLOON_ORIGIN !== null && pettanr.URL_PARAMS.vector !== false; + if( IS_VML === true && pettanr.ua.VML === false) vectorEnabled = false; + + var XBROWSER_BALLOON_CLASS = function( w, h, a){ + var balloonElm = vectorEnabled === true ? ELM_BALLOON_ORIGIN.cloneNode( true) : document.createElement( 'img'), // pettanr.imageに変更 + path = balloonElm.getElementsByTagName( 'path')[ 0], + shape = balloonElm.getElementsByTagName( 'shape')[ 0], + cos = Math.cos, sin = Math.sin, + abs = Math.abs, pow = Math.pow, + round = Math.round, + floor = Math.floor, + TARGET = TAIL_WIDTH * TAIL_WIDTH, + DEG_TO_RAD = Math.PI / 180, + l = ','; + + draw( a, w, h); + + function draw( _a, _w, _h){ + a = _a !== undefined ? _a : a; + w = _w !== undefined ? _w -PADDING_TOP *2 : w; + h = _h !== undefined ? _h -PADDING_LEFT *2 : h; + + if( vectorEnabled === false){ + balloonElm.setAttribute( 'src', balloonUrlBuilder( a)); + return; + } + + var rx = w /2, + ry = h /2, + tailRad = a * DEG_TO_RAD, + tailX = rx +( rx +TAIL_HEIGHT) * cos( tailRad), + tailY = ry +( ry +TAIL_HEIGHT) * sin( tailRad), + startX, startY, endX, endY; + /* + * tailの太さをTAIL_WIDTHに一致させるため、角度を絞りつつ計算 + */ + var startRad, endRad, + _startX, _startY, _endX, _endY, + tailDeg = 0, d; + + for( var i = 45; i > 0.01; i /= 2){ + d = ( tailDeg +i) /2; + startRad = ( a +d) * DEG_TO_RAD; + endRad = ( a -d) * DEG_TO_RAD; + + _startX = rx +cos( startRad) *rx; + _startY = ry +sin( startRad) *ry; + _endX = rx +cos( endRad) *rx; + _endY = ry +sin( endRad) *ry; //円弧上のY位置=円中心Y+sin(角度×PI÷180)×円半径 + + if( pow( ( _startX -_endX), 2) + pow( ( _startY -_endY), 2) < TARGET){ + tailDeg += i; + startX = _startX; + startY = _startY; + endX = _endX; + endY = _endY; + } + } + + /* + * + */ + if( IS_VML === true){ + var _tailX = tailX *10, + _tailY = tailY *10, + __startX = startX *10, + __startY = startY *10, + __endX = endX *10, + __endY = endY *10, + __w = w *10, + __h = h *10; + + shape.style.width = w +'px'; + shape.style.height = h +'px'; + shape.coordsize = [ __w, __h].join( l); + shape.path = [ + ' ar ', 0, l, 0, l, __w, l, __h, l, + round( __endX), l, round( __endY), l, + round( __startX), l, round( __startY), + ' l ', round( _tailX), l, round( _tailY), + ' x e' + ].join( ''); + + balloonElm.style.marginTop = _tailY < 0 ? floor( ( 60 +_tailY) /10) : 10; + balloonElm.style.marginLeft = _tailX < 0 ? floor( ( 60 +_tailX) /10) : 10; + } else { + balloonElm.setAttribute( 'width', w +PADDING_LEFT *2); + balloonElm.setAttribute( 'height', h +PADDING_TOP *2); + path.setAttribute( 'd', [ + 'M', cround( tailX + PADDING_LEFT), l, cround( tailY +PADDING_TOP), + 'L', cround( startX +PADDING_LEFT), l, cround( startY +PADDING_TOP), + 'A', rx, l, ry, + '0 1 1', // flag + cround( endX +PADDING_LEFT), l, cround( endY +PADDING_TOP), + 'z' + ].join( ' ')); + } + function cround( v, r){ + r = r || ACCURACY; + return round( v *pow( 10.0, r)) /pow( 10.0, r); + } + } + + function balloonUrlBuilder( _a){ + var d = 360 /NUM_BALLOON_IMAGE; + _a += 90 +d /2; + return [ 'system_pictures\/_w', _a < 360 -d /2 ? floor( _a /d) : 0, '.gif'].join( ''); + } + return { + elm: balloonElm, + resize: draw, + angle: function( _a){ + _a !== undefined && _a !== a && + vectorEnabled === false ? balloonUrlBuilder( _a) : draw( _a); + return a; + }, + type: function( _type){ + //draw( _a); + }, + getURL: function(){ + return balloonUrlBuilder( a); + }, + destroy: function(){ + balloonElm.parentNode && balloonElm.parentNode.removeChild( balloonElm); + balloonElm = null; + delete this.destroy; + } + } + }; + + IS_VML === false && vectorEnabled === true && ( function(){ + var detect = XBROWSER_BALLOON_CLASS.apply( {}, [ 100, 100, 0]), + size = pettanr.util.getElementSize( detect.elm); + vectorEnabled = size.width !== 0 && size.height !== 0; + detect.destroy(); + detect = size = null; + })(); + + return { + createBalloon: function( _w, _h, _a){ + return XBROWSER_BALLOON_CLASS.apply( {}, [ _w, _h, _a]); + }, + TYPE_NONE: 0, + TYPE_SPEACH_BALLOON: 1, + TYPE_THINKING: 2, + TYPE_BOM: 3, + TYPE_BLACK_BOX: 4, + TYPE_BLUE_BOX: 5 + } +})(); + +/* ---------------------------------------- + * pettanr.image + * + * xBackendな画像反転、画像描画機能。 + * + * 画像の反転 + * - css3 + * - ActiveX (ie) + * - VML (ie) + * - canvas ?? + * - flash(lite) + * - silverlight + * - pettan server + * + * png画像の表示(アルファpngをサポートしないie6以下のため) + * - ActiveX + * - VML + * - flash(lite) + * - silverlight + * + * -moz-transform:scale( -1, -1); + */ +pettanr.image = ( function(){ + var REG_PNG = /\.png?/i, + IS_CSS3 = 0, + IS_VML = 1, + IS_ACTIVEX = 2, + IS_CANVAS = 3, + IS_FLASH = 4, + IS_SILVERLIGHT = 5, + IS_SERVER = 6, + IS_ACTIVEX_SERVER = 7, + BACKEND = ( function(){ + if( pettanr.DEBUG === true && pettanr.URL_PARAMS.rimg){ + var rimg = pettanr.URL_PARAMS.rimg.toLowerCase(); + if( rimg === 'css3') return IS_CSS3; + if( rimg === 'activex') return IS_ACTIVEX; + if( rimg === 'vml') return IS_VML; + } + if( pettanr.ua.isIE === false || pettanr.ua.ieVersion >= 9) return IS_CSS3; // 不十分! + if( pettanr.ua.VML === true) return IS_VML; + if( pettanr.ua.ACTIVEX === true) return IS_ACTIVEX; + if( pettanr.FLASH === true) return IS_FLASH; + if( pettanr.SILVERLIGHT === true) return IS_SILVERLIGHT; + return IS_SERVER; + })(), + BACKEND_WHEN_PNG = ( function(){ + if( pettanr.ua.isIE === false || pettanr.ua.ieVersion > 6) return BACKEND; + if( pettanr.ua.VML === true) return IS_VML; + if( pettanr.FLASH === true) return IS_FLASH; + if( pettanr.SILVERLIGHT === true) return IS_SILVERLIGHT; + if( pettanr.ua.ACTIVEX === true) return IS_ACTIVEX_SERVER; + return IS_SERVER; + })(), + ReversibleImageClass, + ReversibleImageClassWithPingfix; + + var XBackendReversibleImageClass = ( function(){ + var CLASS_NAME = 'reversible-image-container', + CLASS_NAME_LOADING = CLASS_NAME + ' loading', + CLASS_NAME_ERROR = CLASS_NAME +' error', + RETRY_DELAY = 5000; + NUM_RETRY = 3; + + var css3Image = function( url, w, h, onLoadCallback){ + var elmWrap = document.createElement( 'div'), + elmImg, + loaded = false, + retryTimer = null; + elmWrap.className = CLASS_NAME_LOADING; + pettanr.util.loadImage( url, onLoad, onError, 100, 10000); + function onLoad( _url, _actualW, _actualH){ + if( elmWrap === null) return; + elmImg = new Image; + /* + * createElement 直後に append しないと、ie(ActiveX)で img が正しく表示されない. + */ + elmWrap.appendChild( elmImg); + elmImg.setAttribute( 'src', url); + elmWrap.className = CLASS_NAME; + onLoadCallback && onLoadCallback( _url, _actualW, _actualH); + onLoadCallback = null; + loaded = true; + resize( w, h); + } + function onError( _url){ + if( elmWrap === null) return; + elmWrap.className = CLASS_NAME_ERROR; + retryTimer = setTimeout( function(){ + elmWrap.className = CLASS_NAME_LOADING; + pettanr.util.loadImage( url, onLoad, onError, 100, 10000); + }, RETRY_DELAY); + } + function resize( _w, _h){ + w = _w !== undefined ? _w : w; + h = _h !== undefined ? _h : h; + if( loaded === false) return; + elmImg.className = w < 0 || h < 0 ? ( 'img-flip-' + ( w < 0 && h < 0 ? 'vh' : ( w < 0 ? 'h' : 'v'))) : ''; + } + return { + elm : elmWrap, + resize: resize, + destroy: function(){ + loaded === true && elmWrap.removeChild( elmImg); + retryTimer !== null && clearTimeout( retryTimer); + elmWrap = vmlImg = onLoadCallback = retryTimer = null; + elmWrap = elmImg = onLoadCallback = null; + delete this.destroy; + } + } + } + var activexImage = css3Image; + var vmlImage = function( url, w, h, onLoadCallback ){ + var elmWrap = document.createElement( 'div'), + vmlImg, + loaded = false, + retryTimer = null; + elmWrap.className = CLASS_NAME_LOADING; + pettanr.util.loadImage( url, onLoad, onError, 100, 10000); + function onLoad( _url, _actualW, _actualH){ + if( elmWrap === null) return; + elmWrap.className = CLASS_NAME; + vmlImg = document.createElement( 'v:image'); + vmlImg.src = url; + loaded = true; + resize( w, h); + onLoadCallback && onLoadCallback( _url, _actualW, _actualH); + onLoadCallback = null; + } + function onError( _url){ + if( elmWrap === null) return; + elmWrap.className = CLASS_NAME_ERROR; + retryTimer = setTimeout( function(){ + elmWrap.className = CLASS_NAME_LOADING; + pettanr.util.loadImage( url, onLoad, onError, 100, 10000); + }, RETRY_DELAY); + } + function resize( _w, _h){ + w = _w !== undefined ? _w : w; + h = _h !== undefined ? _h : h; + if( loaded !== true) return; + vmlImg.style.width = w < 0 ? -w : w +'px'; + vmlImg.style.height = h < 0 ? -h : h +'px'; + //if( flipH !== _flipH || flipV !== _flipV){ + vmlImg.parentNode === elmWrap && elmWrap.removeChild( vmlImg ); + //} + vmlImg.className = w < 0 || h < 0 ? ( 'img-flip-' + ( w < 0 && h < 0 ? 'vh' : ( w < 0 ? 'h' : 'v'))) : ''; + elmWrap.appendChild( vmlImg); + } + return { + elm : elmWrap, + resize: resize, + destroy: function(){ + loaded === true && elmWrap.removeChild( vmlImg); + retryTimer !== null && clearTimeout( retryTimer); + elmWrap = vmlImg = onLoadCallback = retryTimer = null; + delete this.destroy; + } + } + } + var serverImage = function( url, w, h, onLoadCallback){ + + } + + return function( url, w, h, onLoadCallback ){ + var flipH = w < 0, + flipV = h < 0, + onLoadCallbackAsync = onLoadCallback,// ? function(){ setTimeout( onLoadCallback, 0);} : undefined,// 一度読み込んだ画像は即座にonLoadになるため遅延 + xBackendImage = ( function( urlIsXDomain ){ + if( BACKEND === IS_CSS3) return new css3Image( url, w, h, onLoadCallbackAsync ); + if( BACKEND === IS_VML) return new vmlImage( url, w, h, onLoadCallbackAsync ); + if( BACKEND === IS_ACTIVEX) return new activexImage( url, w, h, onLoadCallbackAsync ); + return new serverImage( url, w, h, onLoadCallbackAsync ); + })(); + return { + elm: xBackendImage.elm, + w: function( _w){ + _w !== undefined && xBackendImage.resize( _w, h); + return w; + }, + h: function( _h){ + _h !== undefined && xBackendImage.resize( w, _h); + return h; + }, + resize: xBackendImage.resize, + destroy: function(){ + xBackendImage.destroy && xBackendImage.destroy(); + xBackendImage = onLoadCallback = onLoadCallbackAsync = null; + delete this.destroy; + } + } + } + })(); + return { + createReversibleImage: function( url, w, h, onLoadCallback){ + return XBackendReversibleImageClass.apply( {}, [ url, w, h, onLoadCallback]); + } + } +})(); + +/* + * bind : 製本 + */ +pettanr.bind = ( function(){ + var BIND_WORKER_ARRAY = [], + NAMESPACE_CLASSNAME = pettanr.CONST.NS_PETTANR_COMIC + '-', + RESOURCE_PICTURE_PATH = pettanr.CONST.RESOURCE_PICTURE_PATH, + ELM_DETECT_WIDTH = ( function(){ + var ret = document.createElement( 'div'); + ret.style.cssText = 'width: auto;height: 0;padding: 0;margin: 0;display: block;visibility: hidden;float: none;position: static;'; + return ret; + })(); + + /* + * original + * http://d.hatena.ne.jp/uupaa/20090720/1248097177 + */ + var ResizeAgentClass = function( onResizeFunction, opt_elmCheck){ + var _globalLock = 0, + _size = { w: 0, h: 0 }; + _ie = !!document.all, + _quirks = (document.compatMode || "") !== "CSS1Compat", + _ieroot = _quirks ? "body" : "documentElement"; + _root = opt_elmCheck ? opt_elmCheck : ( _ie ? document[_ieroot] : window); + + function getInnerSize() { + return { + w: _root.innerWidth || _root.clientWidth, + h: _root.innerHeight || _root.clientHeight + }; + } + + function loop() { + if (!_globalLock++) { + var size = getInnerSize(); + if (_size.w !== size.w || _size.h !== size.h) { // resized + _size = size; // update + onResizeFunction( _size); + } + setTimeout( unlock, 0); // delay unlock + } + setTimeout(loop, 500); + } + function unlock(){ + _globalLock = 0; + } + loop(); + } + + + var ElementBuilder = ( function(){ + var ELM_TITLE_ORIGN = ( function(){ + + })(), + ELM_TEXT_ORIGN = ( function(){ + var _table = document.createElement( 'table'), + _tr = document.createElement( 'tr'); + _table.appendChild( _tr); + _tr.appendChild( document.createElement( 'td')); + _table.cellspacing = '0'; + return _table; + })(); + + function buildComicElement(){ + + } + + function buildPanelElement( elmTarget, json, noClassnameMode){ + var _elmPanel = document.createElement( 'div'), + _style = { + "border-width": typeof json.border === 'number' ? json.border + 'px' : 0, + width: json.width + 'px', + height: json.height + 'px' + }, + _cssText = [], + _comicElements = json.panel_elements || [], + _comicElement, _elmImgWrap, _rImg, _rPic, _balloon, _elmBalloonWrap, _elmText; + if( noClassnameMode === true){ + + } else { + _elmPanel.className = NAMESPACE_CLASSNAME + 'panel'; + } + for( var _key in _style){ + _cssText.push( _key + ':' + _style[ _key]); + } + _elmPanel.style.cssText = _cssText.join( ';'); + elmTarget.appendChild( _elmPanel); + + for( var i=0, l=_comicElements.length; i 1){ + var _cssTexts = _elm.style.cssText.split( ';'), _css, + _separate, + _cssObject = {}, _target, _value, _number, _px, + j; + for(var i=0, l=_cssTexts.length; i= 3){ + _target = _css.substr( 0, _separate +1); + _value = _css.substr( _separate +1); + /* + * ie filter + */ + if( _target === FILTER){ + for( j=0; j<_numAttributes; ++j){ + if( _targetAttributes[ j] === OPACITY){ + _cssTexts[ i] = [ + _target, ':', + _value.replace( REG_ALPHA, "alpha(opacity=" + _updateParameters[ j] * 100 + ")") + ].join( ''); + break; + } + } + /* + * other + */ + } else { + _number = '' + parseFloat( _value); + _px = _value.indexOf( _number); + _px = _px > 0 ? _value.substr( _px + _number.length) : ''; + for( j=0; j<_numAttributes; ++j){ + if( _targetAttributes[ j] === _target){ + _cssTexts[ i] = [ _target, ':', _updateParameters[ j], _px].join( ''); + break; + } + } + } + } + } + _elm.style.cssText = _cssTexts.join( ';'); + return; + } + /* + * 一度に update する Attributes が少ない場合、cssText は使用しない. + */ + } + + var AnimationTaskClass = function( ELM, currentParameters, offsetParameters, endParameters, targetAttributes, onComplete, onEnterFrame, numFrames){ + var l = targetAttributes.length; + return { + elm: ELM, + onEnterFrame: function(){ + var _updateCss = {}, i; + if( numFrames === 1){ + for( i=0; i tag:ペン次郎 > ペン次郎:笑う + * 最近アップロードされた画像 > images + * 最近使われた画像 > images + * キャラクター画像庫 > アニマル系 > tag:ペン次郎 > ペン次郎:笑う + * 風景画像庫 > + * 効果画像庫 > + * アイテム画像庫 > + * + * 画像一覧を読み込むタイミング + */ +pettanr.file = ( function(){ + var FILE_TYPE_IS_FOLDER = 1, + numFileType = FILE_TYPE_IS_FOLDER, + FILEDATA_RESITER = [], // store all of fileData( json object ) + FILEDATA_ACCESS = [], // file operations for Kernel only ! hide from Out of pettanr.file + FILE_OBJECT_POOL = [], + EVENT_LISTENER_REGISTER = [], + TREE_ARRAY = [], + TREE_ACCESS_ARRAY = []; + + var REQUEST_CONTROLER = ( function(){ + var REQUEST_TICKET_RESISTER = [], + DATA_TYPE_ARRAY = 'json,xml,html,text'.split( ','), + DATA_IS_JSON = 0, + DATA_IS_XML = 1, + DATA_IS_HTML = 2, + DATA_IS_TEXT = 3, + numError = 0; + + var RequestTicketClass = function( _type, _data, _url, _onLoad, _onError){ + this.type = DATA_TYPE_ARRAY[ _type]; + this.data = _data; + this.url = _url; + this.onLoad = _onLoad; + this.onError = _onError; + this.state = 0; + }; + + function request(){ + if( REQUEST_TICKET_RESISTER.length === 0) return; + var _ticket = REQUEST_TICKET_RESISTER.shift(); + $.ajax({ + url: _ticket.url, + dataType: _ticket.type, + success: function( _data){ + _ticket.onLoad( _ticket.data, _data); + }, + error: function(){ + ++numError; + _ticket.onError( _ticket.data); + } + }); + } + + return { + getNumTask: function(){ + return REQUEST_TICKET_RESISTER.length; + }, + getNumError: function(){ + return numError; + }, + getJson: function( _data, _url, _onLoad, _onError){ + REQUEST_TICKET_RESISTER.push( new RequestTicketClass( DATA_IS_JSON, _data, _url, _onLoad, _onError)); + request(); + } + } + })(); + + + + var FILE_CONTROLER = { + createTree: function( _rootFileData){ + var _tree = new TreeClass( _rootFileData); + _tree.init(); + TREE_ARRAY.push( _tree); + return _tree; + }, + getFileUID: function( FILEDATAorFILE ){ + if( FILEDATAorFILE instanceof FileClass ){ + return FILEDATAorFILE.getUID(); + } + + var uid = pettanr.util.getIndex( FILEDATA_RESITER, FILEDATAorFILE ); + if( uid === -1){ + uid = FILEDATA_RESITER.length; + FILEDATA_RESITER.push( FILEDATAorFILE ); + } + return uid; + }, + getFileDataAccess: function( UIDorFILEorFILEDATA){ + var _uid, _data, _access; + + if( typeof UIDorFILEorFILEDATA === 'number'){ + _data = FILEDATA_RESITER[ UIDorFILEorFILEDATA] || null; + } else + if( UIDorFILEorFILEDATA instanceof FileClass){ + _uid = UIDorFILEorFILEDATA.getUID(); + _data = FILEDATA_RESITER[ _uid ] || null; + } else { + _data = UIDorFILEorFILEDATA || null; + } + + if( _data === null || typeof _data !== 'object') return null; + for( var i=0, l = FILEDATA_ACCESS.length; i= _bit; + }, + move: function( _prentUID, _targetfile, _newFolder, _newIndex, _opt_callback){ + var _parentData = FILE_CONTROLER.getFileDataAccess( _prentUID), + _parentType = _parentData.TYPE, + _targetData = FILE_CONTROLER.getFileDataAccess( _targetfile), + _targetType = _targetData.TYPE; + }, + replace: function( _uid, _file, _newIndex){ + + }, + addEventListener: function( FILEorNULL, _eventType, _callback){ + var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL; + EVENT_LISTENER_REGISTER.push( new FileEventTicketClass( _uid, _eventType, _callback)); + }, + removeEventListener: function( FILEorNULL, _eventType, _callback){ + var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL, + _ticket; + for(var i=0, l = EVENT_LISTENER_REGISTER.length; i= l) return null; + return PARENT_FILE_RESITER[ l -1 -_index]; + }, + down: function( _index){ + if( typeof _index !== 'number' || _index < 0 || _index >= currentFile.getChildFileLength()) return; + PARENT_FILE_RESITER.unshift( currentFile ); + currentFile = currentFile.getChildFileByIndex( _index ); + currentFile.getSeqentialFiles(); + return currentFile; + }, + up: function( _index){ + var l = PARENT_FILE_RESITER.length; + if( l === 0) return null; + + if( currentFile ){ + var _currentFile = currentFile; + currentFile = null; + _currentFile.destroy(); + } + if( typeof _index === 'number'){ + if( _index >= l) return null; + currentFile = this.getParentFileAt( _index ); + PARENT_FILE_RESITER.splice( 0, l -_index); + } else { + currentFile = PARENT_FILE_RESITER.shift(); + } + currentFile.getSeqentialFiles(); + return currentFile; + }, + addTreeEventListener: function( _eventType, _callback){ + FILE_CONTROLER.addEventListener( null, _eventType, _callback); + }, + removeTreeEventListener: function( _eventType, _callback){ + FILE_CONTROLER.removeEventListener( null, _eventType, _callback); + }, + destroy: function(){ + FILE_CONTROLER.destroyTree( instance.getUID() ); + // removeEvent + var _currentFile = currentFile; + currentFile = rootFile = rootFileData = null; + // currentFile, rootFile を null にしないと .File.destroy() ができない. + _currentFile.destroy(); + while( PARENT_FILE_RESITER.length > 0 ){ + _currentFile = PARENT_FILE_RESITER.shift(); + _currentFile.destroy(); + } + instance = null; + } + } + }; + + var FileEventTicketClass = function( UID, _eventType, _callback){ + this.fileUID = UID; + this.eventType = _eventType; + this.callBack = _callback; + this.destroy = function(){ + this.callBack = _callback = null; + } + } + + var FileEventClass = function( eventType, file, key, value){ + this.eventType = eventType; + this.targetFile = file; + this.updatedAttribute = key; + this.updatedValue = value; + } + +/* + * fileのdataはobjectで保持している。 + * pettanr.file.の外からファイルをみるときは、FileClassを通して操作する。 + * fileの変更、それに付随して追加されたイベントは、TreeClassで管理される。 + * treeがdestryされると、fileのイベントリスナーも全て削除される。 + * 他の tree も data の共通する currentFile に対してのみは、file の変更イベントを受け取って流す. + * + * parentData のほうがいい! + */ + + var FileClass = function( tree, parentData, data ){ + var uid = FILE_CONTROLER.getFileUID( data ), + instance = this; + + FILEDATA_ACCESS.push( + { + TREE: tree, + parentData: parentData, + DATA: data, + dispatchFileEvent: dispatchEvent + } + ); + + tree = parentData = data = null; + + function dispatchEvent( e ){ + FILE_CONTROLER.fileEventRellay( uid, e ); + } + this.getUID = function(){ + return uid; + } + }; + + FileClass.prototype = { + isChildFile: function( _FILEorFILEDATA){ + return this.getChildFileIndex( _FILEorFILEDATA) !== -1; + }, + getSeqentialFiles: function(){ + var _driver = FILE_CONTROLER.getDriver( this ); + if( _driver !== null && typeof _driver.getSeqentialFiles === 'function' ){ + _driver.getSeqentialFiles( this ); + } + }, + addEventListener: function( _eventType, _callback ){ + FILE_CONTROLER.addEventListener( this, _eventType, _callback ); + }, + removeEventListener: function( _eventType, _callback ){ + FILE_CONTROLER.removeEventListener( this, _eventType, _callback ); + }, + getChildFileLength: function(){ + var children = FILE_CONTROLER.getChildren( this ); + return Type.isArray( children ) === true ? children.length : -1; + }, + getChildFileIndex: function( _FILEorFILEDATA ){ + var children = FILE_CONTROLER.getChildren( this); + if( Type.isArray( children ) === false ) return -1; + var l = children.length, + _fileData = FILE_CONTROLER.getFileData( _FILEorFILEDATA ); + if( _fileData === null ) return -1; + for( var i=0; i= _children.length) return null; + var _file = new FileClass( _access.TREE, _access.data, _children[ _index ]); + // _file.init(); + return _file; + }, + move: function( _newFolder, _newIndex, opt_callback ){ + var _access = FILE_CONTROLER.getFileDataAccess( this ); + _access.TREE.move( _access.parentData, this.getUID(), _newFolder, _newIndex, opt_callback ); + }, + replace: function( _newIndex, opt_callback ){ + var _access = FILE_CONTROLER.getFileDataAccess( this ); + _access.TREE.replace( _access.parentData, this.getUID(), _newIndex, opt_callback); + }, + /** + * サーチ + * 探しているファイルの属性と値を指定.一致する child の index を配列で返す. + */ + search: function( obj, rule ){ + var _children = FILE_CONTROLER.getChildren( this ), + _child, + ret = [], k, c; + for( var i=0, l=_children.length; i 0 ){ + ELM_VIEWER_BUTTON.style.display = ''; + } else { + ELM_VIEWER_BUTTON.style.display = 'none'; + }; + if( Type.isArray( editorList ) === true && editorList.length > 0 ){ + ELM_EDITOR_BUTTON.style.display = ''; + } else { + ELM_EDITOR_BUTTON.style.display = 'none'; + }; + } + function resize(){ + ELM_WRAPPER.style.top = (index * ICON_HEIGHT) +'px'; + } + function onCollect(){ + elmContainer.removeChild( ELM_WRAPPER ); + elmContainer = null; + FINDER_ICON_POOL.push( instansce ); + } + + return { + init: function( _file, _elmContainer, _w, _index, _style, _onDownCallback, _onEditorCallback, _onViewerCallback, _onActionCallback ){ + instansce = this; + if( elmContainer !== _elmContainer){ + _elmContainer.appendChild( ELM_WRAPPER); + elmContainer = _elmContainer; + } + if( file !== _file){ + file && file.destroy(); + file = _file; + viewerList = file.viewerApplicationList(); + editorList = file.editorApplicationList(); + draw(); + } + if( index !== _index){ + index = _index; + resize(); + } + onDownCallback = _onDownCallback; + onEditorCallback = _onEditorCallback; + onViewerCallback = _onViewerCallback; + onActionCallback = _onActionCallback; + }, + elm: ELM_WRAPPER, + index: function( _index){ + + return index; + }, + style: function( _style){ + + return style; + }, + onResize: function( w ){ + + }, + destroy: function(){ + elmContainer.removeChild( ELM_WRAPPER); + file && file.destroy(); + file = elmContainer = onDownCallback = onEditorCallback = onViewerCallback = onActionCallback = viewerList = editorList = null; + FINDER_ICON_POOL.push( instansce); + } + } + } + function updateIconPosition( _style, _w, _index, _elm){ + + } + var BreadcrumbClass = function(){ + var elmContainer, + ELM_WRAPPER = ELM_ORIGIN_FINDER_LOCATION_ITEM.cloneNode( true), + ELM_FILENAME = ELM_WRAPPER.getElementsByTagName( 'a')[0], + file, w, index, instansce, + callback; + ELM_WRAPPER.onclick = onClick; + function draw(){ + ELM_FILENAME.className = 'file-icon-' +file.getType(); + ELM_FILENAME.innerHTML = file.getName(); + } + function resize( index){ + ELM_WRAPPER.style.left = (index * 90) +'px'; + } + function onClick(){ + callback( index); + return false; + } + + return { + init: function( _file, _elmContainer, _index, _callback ){ + instansce = this; + if( elmContainer !== _elmContainer ){ + _elmContainer.appendChild( ELM_WRAPPER); + elmContainer = _elmContainer; + } + if( file !== _file){ + file = _file; + draw(); + } + if( index !== _index){ + index = _index; + resize( index); + } + callback = _callback; + }, + elm: ELM_WRAPPER, + index: function( _index){ + + return index; + }, + onResize: function( w){ + + }, + destroy: function(){ + elmContainer.removeChild( ELM_WRAPPER); + file = elmContainer = null; + BREAD_OBJECT_POOL.push( this ); + } + } + } + + var FinderClass = function( ELM_CONTAINER, tree, header, footer ){ + var ICON_ARRAY = [], + BREAD_ARRAY = [], + elmContainer = ELM_ORIGIN_CONTAINER.cloneNode( true ), + elmLocation = elmContainer.getElementsByTagName( 'ul' )[0], + nodesDiv = elmContainer.getElementsByTagName( 'div' ), + elmSidebarButton = nodesDiv[1], + elmStyleButton = nodesDiv[2], + elmActionButton = nodesDiv[3], + elmBody = nodesDiv[ nodesDiv.length -1 ], + //tree = pettanr.file.createTree( TREE_TYPE), + headX, + headY, + headH = pettanr.util.getElementSize( nodesDiv[0] ).height, + bodyY, + currentFile = null, + breadW = 90, + size = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON ), + iconW = size.width, + iconH = size.height, + style = 0, + w, h, bodyH, + instance = this; + + tree.addTreeEventListener( pettanr.file.TREE_EVENT.UPDATE, draw ); + + function draw( _w, _h ){ + w = Type.isFinite( _w ) === true ? _w : w; + h = Type.isFinite( _h ) === true ? _h : h; + bodyH = h - headH; + var l = tree.hierarchy() +1, + m = BREAD_ARRAY.length, + _file, _bread; + for(var i=0; i 0){ + _icon = FINDER_ICON_POOL.shift(); + } else { + _icon = new FinderIconClass(); + } + _icon.init( _file, _elmContainer, w, index, style, onDown, onEditor, onViwer, onAction ); + return _icon; + } + + function getBreadcrumb( _file, _elmContainer, index, callback){ + var _bread; + if( BREAD_OBJECT_POOL.length > 0){ + _bread = BREAD_OBJECT_POOL.shift(); + } else { + _bread = new BreadcrumbClass(); + } + _bread.init( _file, _elmContainer, index, callback); + return _bread; + } + + return { + init: function(){ + + }, + createFinder: function( _elmTarget, _tree, _header, _footer ){ + var _finder = new FinderClass( _elmTarget, _tree, _header, _footer ); + FINDER_ARRAY.push( _finder ); + return _finder; + }, + registerFinderHead: function(){ + + }, + registerFinderPane: function( _finderPane){ + + }, + isFinderInstance: function( _finder){ + return _finder instanceof FinderClass; + }, + isFinderPaneInstance: function(){ + + }, + isFinderHeadInstance: function(){ + } + } +})(); + + +pettanr.driver = ( function(){ + var MyAuthorID = 'current_author' in window ? current_author.id : ( pettanr.DEBUG ? 1 : -1 ), + MyArtistID = 'current_artist' in window ? current_artist.id : ( pettanr.DEBUG ? 1 : -1 ), + Driver = { + getSeqentialFiles: function( _file){ + var _data = FileAPI.getFileData( _file), + _json = _data !== null ? _data.json : null; + if( _json === true && _data.type === pettanr.driver.FILE_TYPE.COMIC ){ + if( pettanr.LOCAL === true ){ + _json = [ 'json\/comics_', _data.id, '.json' ].join( '' ); + } else { + _json = [ pettanr.CONST.PETTANR_ROOT_PATH, 'comics\/', _data.id, '.json\/play\/' ].join( '' ); + } + } + if( typeof _json === 'string'){ + FileAPI.getJson( _file, _json, onLoadJson, onErrorJson); + _data.state = pettanr.file.FILE_STATE.LOADING; + _data.json = null; + return; + } + }, + getName: function( _file){ + var _data = FileAPI.getFileData( _file), + _type = _data !== null ? _data.type : null; + if( _type === pettanr.driver.FILE_TYPE.PICTURE ){ + return [ _data.id, _data.ext ].join( '.'); + } else + if( _type === pettanr.driver.FILE_TYPE.PANEL ){ + return [ _data.t, ':', _data.comic.title ].join( ''); + } else + if( _type === pettanr.driver.FILE_TYPE.COMIC ){ + return _data.title; + } else + if( _type === pettanr.driver.FILE_TYPE.ARTIST ){ + return [ _data.id , ':', _data.name, '画伯' ].join( ''); + } else + if( _type === pettanr.driver.FILE_TYPE.AUTHOR ){ + return [ _data.id , ':', _data.name, '先生' ].join( ''); + } + return _data.name; + }, + getThumbnail: function( _file){ + var _data = FileAPI.getFileData( _file), + _type = _data !== null ? _data.type : null; + if( _type === pettanr.driver.FILE_TYPE.PICTURE){ + return { image: [ pettanr.CONST.RESOURCE_PICTURE_PATH, 'thumbnail/', _data.id, '.', _data.ext ].join( '')}; + } + if( _data === FILE_DATA_COMICS_ROOT){ + return { className: 'file-type-cabinet'}; + } + if( _type === pettanr.driver.FILE_TYPE.COMIC){ + return { className: 'file-type-comic'}; + } + if( _type === pettanr.driver.FILE_TYPE.PANEL){ + return { className: 'file-type-panel'}; + } + if( _type === pettanr.driver.FILE_TYPE.AUTHOR){ + return { className: 'file-type-author'}; + } + if( _type === pettanr.driver.FILE_TYPE.ARTIST){ + return { className: 'file-type-artist'}; + } + if( _type === pettanr.file.FILE_TYPE.FOLDER){ + return { className: 'file-type-folder'}; + } + return { className: 'file-type-broken'}; + }, + getSummary: function( _file ){ + var _data = FileAPI.getFileData( _file), + _type = _data !== null ? _data.type : null; + if( _type === pettanr.driver.FILE_TYPE.PICTURE){ + return [ _data.width, 'x', _data.height, ', filesize:', _data.filesize, ', lisence:', _data.license ].join( '' ); + } + if( _data === FILE_DATA_COMICS_ROOT){ + return 'cabinet file'; + } + if( _type === pettanr.driver.FILE_TYPE.COMIC){ + return 'comic file'; + } + if( _type === pettanr.driver.FILE_TYPE.PANEL){ + return [ _data.width, 'x', _data.height ].join( '' ); + } + if( _type === pettanr.driver.FILE_TYPE.AUTHOR){ + return 'author file'; + } + if( _type === pettanr.driver.FILE_TYPE.ARTIST){ + return [ 'Email:', _data.email || 'empty' , ', HP:', _data.homepage_url || 'empty' ].join( '' ); + } + if( _type === pettanr.file.FILE_TYPE.FOLDER){ + return 'pettanR folder'; + } + return 'pettanR unknown file'; + }, + write: function( _file, _newData, _onUpdateFunction ){ + var _data = FileAPI.getFileData( _file ), + _type = _data !== null ? _data.type : null; + if( _type === pettanr.driver.FILE_TYPE.COMIC ){ + } + if( _type === pettanr.driver.FILE_TYPE.PANEL ){ + } + if( _type === pettanr.driver.FILE_TYPE.PANEL_PICTURE ){ + + } + if( _type === pettanr.driver.FILE_TYPE.BALLOON ){ + } + if( _type === pettanr.driver.FILE_TYPE.PICTURE ){ + } + }, + viewerApplicationList: function( _file ){ + var _data = FileAPI.getFileData( _file ), + _type = _data !== null ? _data.type : null; + + if( _data === FILE_DATA_MY_PICTURES_ROOT ){ + return [ pettanr.premiumSatge ]; + } + if( _type === pettanr.driver.FILE_TYPE.ARTIST ){ + return [ pettanr.premiumSatge ]; + } + return []; + }, + editorApplicationList: function( _file ){ + var _data = FileAPI.getFileData( _file ), + _type = _data !== null ? _data.type : null; + if( _type === pettanr.driver.FILE_TYPE.PANEL ){ + return [ pettanr.editor ]; + } + if( _type === pettanr.driver.FILE_TYPE.COMIC ){ + return [ pettanr.editor, pettanr.comicConsole ]; + } + return []; + } + }, + FileAPI = pettanr.file.registerDriver( Driver ), + FILE_DATA_SERVICE_ROOT = { + name: 'PettanR root', + type: pettanr.file.FILE_TYPE.FOLDER, + children: [] + }, + FILE_DATA_COMICS_ROOT = { + name: 'Comics', + type: pettanr.file.FILE_TYPE.FOLDER, + children: [], + driver: Driver, + json: pettanr.CONST.URL_COMICS_JSON + }, + FILE_DATA_PANELS_ROOT = { + name: 'Panels', + type: pettanr.file.FILE_TYPE.FOLDER, + children: [], + driver: Driver, + json: pettanr.CONST.URL_PANELS_JSON + }, + FILE_DATA_PICTURE_ROOT = { + name: 'Picutures', + type: pettanr.file.FILE_TYPE.FOLDER, + children: [], + driver: Driver, + json: pettanr.CONST.URL_RESOURCE_PICTURES_JSON + }, + FILE_DATA_MY_COMICS_ROOT = { + name: 'My Comics', + type: pettanr.file.FILE_TYPE.FOLDER, + children: [], + driver: Driver + }, + FILE_DATA_LATEST_COMICS = { + name: 'Latest Comics', + type: pettanr.file.FILE_TYPE.FOLDER, + children: [] + }, + FILE_DATA_MY_PICTURES_ROOT = { + name: 'My Pictures', + type: pettanr.file.FILE_TYPE.FOLDER, + children: [], + driver: Driver, + json: pettanr.CONST.URL_ORIGINAL_PICTURES_JSON + }, + FILE_DATA_AUTHOR_ROOT = { + name: 'Authors', + type: pettanr.file.FILE_TYPE.FOLDER, + children: [] + }, + FILE_DATA_ARTIST_ROOT = { + name: 'Artists', + type: pettanr.file.FILE_TYPE.FOLDER, + children: [] + }, + FILE_DATA_LISENCE_ROOT = { + name: 'Original Lisences', + type: pettanr.file.FILE_TYPE.FOLDER, + children: [] + }, + FILE_DATA_BALLOON_ROOT = { + name: 'Balloon templetes', + type: pettanr.file.FILE_TYPE.FOLDER, + children: [] + }, + AUTHOR_ARRAY = [], + ARTIST_ARRAY = [], + PANEL_ARRAY = [], + COMIC_ARRAY = [], + RESOURCE_PICTURE_ARRAY = [], + BALLOON_TEMPLETE_ARRAY = [], + ORIGINAL_LICENSE_ARRAY = [], + BASIC_LICENSES = 'cc_by,cc_nc,cc_nd,cc_sa,keep_aspect_ratio,no_convert,no_flip,no_resize'.split( ','); + FILE_DATA_SERVICE_ROOT.children.push( FILE_DATA_COMICS_ROOT, FILE_DATA_PICTURE_ROOT, FILE_DATA_PANELS_ROOT, FILE_DATA_LISENCE_ROOT, FILE_DATA_BALLOON_ROOT); + FILE_DATA_COMICS_ROOT.children.push( FILE_DATA_MY_COMICS_ROOT, FILE_DATA_LATEST_COMICS, FILE_DATA_AUTHOR_ROOT); + FILE_DATA_PICTURE_ROOT.children.push( FILE_DATA_MY_PICTURES_ROOT, FILE_DATA_ARTIST_ROOT); + + FileAPI.createFolderUnderRoot( FILE_DATA_SERVICE_ROOT); + + function onLoadJson( _file, _json ){ + var _access = FileAPI.getFileDataAccess( _file), + _data = _access !== null ? _access.DATA : null, + l; + if( _data === null){ + onErrorJson( _file); + return; + } + _data.state = pettanr.file.FILE_STATE.OK; + + if( Type.isArray( _json ) === true ){ + l = _json.length; + if( l === 0) return; + for( var i=0; i 0 ){ + var _id = _data.id - 1, + __data = _array[ _id ], + _reserved = pettanr.file.FILE_DATA_PROPERTY_RESERVED.join( ', ' ); + if( __data ){ + for( var key in _data){ + if( _reserved.indexOf( key ) === -1 ){ + __data[ key ] = _data[ key ]; + } + } + _data = __data; // このタイミングで参照が切れるので注意!! + } else { + _array[ _id ] = _data; + } + } else { + alert( 'error' ); + } + + // Author + // Artist + if( _parent === FILE_DATA_AUTHOR_ROOT || _parent === FILE_DATA_ARTIST_ROOT ){ + addChildData( _parent, _data ); + } else + // Comic + Panels + if( _parent.type === pettanr.driver.FILE_TYPE.COMIC || _parent === FILE_DATA_COMICS_ROOT ){ + var _panels = _data.panels, + _panel; + if( _panels && Type.isArray( _panels ) === true ){ + + for( i=0, l=_panels.length; i= 8) data.RenderingVersion = ua.ieRenderingVersion; + data.browserType = ua.STANDALONE === true ? 'Standalone' : 'bundle'; + if( ua.ieVersion < 9) { + data.vml = ua.VML; + } else { + data.svg = ua.SVG; + } + } + data.RenderingMode = ua.isStanderdMode === true ? 'Standerd' : 'Quirks'; + + for( var key in data){ + elmDt = document.createElement( 'dt'); + elmDt.innerHTML = key; + elmDd = document.createElement( 'dd'); + elmDd.innerHTML = '' + data[ key]; + if( !data[ key]) elmDd.style.color = 'red'; + elmDl.appendChild( elmDt); + elmDl.appendChild( elmDd); + } + this.displayName = 'Debug'; + this.ID = 'debug'; + this.rootElement = document.getElementById( 'debug' ); + this.onOpen = function( _w, _h, _option ){ + var pageHeaderH = pettanr.util.getElementSize( document.getElementById( 'header' )).height; + document.getElementById( 'inner-wrapper' ).style.height = ( _h - pageHeaderH ) + 'px'; + } + this.onClose = function(){ + document.getElementById( 'inner-wrapper' ).style.height = '0px'; + } + this.onPaneResize = function( _w, _h ){ + pettanr.debug.onOpen( _w, _h ); + } + }); + pettanr.debug.addToLancher(); + +} else { + var _debug = document.getElementById( 'debug'); + if( _debug){ + pettanr.util.removeAllChildren( _debug); + _debug.parentNode.removeChild( _debug); + _debug = null; + } +} + +/* ---------------------------------------- + * Image Group Exproler + * - overlay + */ +pettanr.premiumSatge = pettanr.view.registerApplication( function(){ + var ICON_ARRAY = [], + WHEEL_DELTA = 64, + ARTIST_TREE = pettanr.driver.createArtistTree(), + ARTIST_ROOT_FILE = ARTIST_TREE.getRootFile(), + instance = this, + winW, winH, + wrapX, + elmWrap = document.getElementById( 'image-gruop-wrapper' ), + elmContainer = document.getElementById( 'image-icon-container' ), + containerW, + containerH = pettanr.util.getElementSize( elmContainer ).height, + elmIconOrigin = ( function(){ + var ret = document.createElement( 'div' ), + data = document.createElement( 'div' ); + ret.appendChild( data ); + ret.className = 'image-gruop-item'; + data.className = 'image-gruop-item-title'; + return ret; + })(), + jqContainer, + size = pettanr.util.getElementSize( elmIconOrigin ), + itemW = size.width, + itemH = size.height, + elmName = document.getElementById( 'gruop-name-display' ), + elmButton = document.getElementById( 'image-gruop-button' ), + buttonW = pettanr.util.getElementSize( elmButton ).width, + //onUpdateFunction, + _g_onUpdateFunction, + onEnterInterval = null; + + elmButton.onclick = clickOK; + + var BASE_PATH = pettanr.LOCAL === true ? 'resource_pictures\/' : pettanr.CONST.PETTANR_ROOT_PATH + 'resource_pictures\/', + THUMB_PATH = BASE_PATH, // + 'thumbnail/', + LIMIT_FILESIZE = 1024 * 10; // 10KB + + var ImageGroupIconClass = function( INDEX, file ){ + var elmIconWrap = elmIconOrigin.cloneNode( true ), + elmIconTitle = pettanr.util.getElementsByClassName( elmIconWrap, 'image-gruop-item-title' )[ 0 ], + data = pettanr.driver._getAPI().getFileData( file ), + SRC = [ BASE_PATH, data.id, '.', data.ext ].join( ''), + LOW_SRC = data.filesize && data.filesize > LIMIT_FILESIZE ? [ THUMB_PATH, data.id, '.', data.ext ].join( '') : null, + reversibleImage = null, + onEnterFlag = false, + imgW, imgH; + elmContainer.appendChild( elmIconWrap ); + elmIconWrap.style.left = ( INDEX * itemW ) + 'px'; + elmIconTitle.appendChild( document.createTextNode( data.filesize + 'bytes' )); + + function onImageLoad( url, _imgW, _imgH ){ + if( reversibleImage === null) { + alert( url); + return; + } + data.width = imgW = _imgW || data.width || 64; + data.height = imgH = _imgH || data.height || 64; + elmIconTitle.firstChild.data = imgW + 'x' + imgH; + var zoom = 128 /( imgW > imgH ? imgW : imgH), + MATH_FLOOR = Math.floor + h = MATH_FLOOR( imgH *zoom ), + w = MATH_FLOOR( imgW *zoom ); + reversibleImage.elm.style.cssText = [ + 'width:', w, 'px;', + 'height:', h +'px;', + 'margin:', MATH_FLOOR( itemH /2 -h /2 ), 'px ', MATH_FLOOR( itemW /2 -w /2 ), 'px 0' + ].join(''); + reversibleImage.resize( w, h ); + elmIconWrap.onclick = onClick; + } + + function onClick( e ){ + if( _g_onUpdateFunction ) { + //if( LOW_SRC === null){ + window[ _g_onUpdateFunction]( data ); + window[ _g_onUpdateFunction] = null; + /* + } else { + var _onLoad = pettanr.util.createGlobalFunc( [ + 'function( url, w, h ){', + 'window["', _g_onUpdateFunction, '"]( url, w || ', data.width,', h || ', data.height,');', + 'window["', _g_onUpdateFunction, '"] = null;', + '}' + ].join( '')), + _onError = pettanr.util.createGlobalFunc( [ + 'function( url){', + 'window["', _g_onUpdateFunction, '"]( url, ', data.width || 64 ,', ', data.height || 64,');', + 'window["', _g_onUpdateFunction, '"] = null;', + '}' + ].join( '')); + pettanr.util.loadImage( SRC, window[ _onLoad], window[ _onError]); + window[ _onLoad] = window[ _onError] = undefined; + }*/ + } + pettanr.premiumSatge.shutdown(); + } + + this.onEnter = function(){ + if( onEnterFlag === true ) return; + reversibleImage = pettanr.image.createReversibleImage( LOW_SRC || SRC, itemW, itemH, onImageLoad ); + elmIconWrap.appendChild( reversibleImage.elm ); + onEnterFlag = true; + } + this.destroy = function(){ + reversibleImage && reversibleImage.destroy(); + pettanr.util.removeAllChildren( elmIconWrap ); + elmContainer.removeChild( elmIconWrap ); + file.destroy(); + reversibleImage = elmIconWrap = elmIconTitle = data = file = null; + delete this.destroy; + } + } + + function onEnterShowImage(){ + var l = ICON_ARRAY.length, + _start = -wrapX /itemW -1, + _end = _start + winW /itemW +1; + for( var i=0; i 0 ? 0 : wrapX < winW -containerW ? winW -containerW : wrapX; + jqContainer.css( { left: wrapX}); + + onEnterInterval !== null && window.clearTimeout( onEnterInterval ); + onEnterInterval = window.setTimeout( onEnterShowImage, 500); + } + //e.stopPropagation(); + return false; + } + + /* grobal method */ + // this.rootElement = elmWrap; + this.displayName = 'premiumStage'; + this.ID = 'premiumStage'; + this.rootElement = elmWrap; + this.MIN_WIDTH = 320; + this.MIN_HEIGHT = 320; + this.init = function(){ + jqContainer = $( elmContainer ).mousewheel( onMouseWheel ); + delete instance.init; + } + this.onOpen = function( _windowW, _windowH, _ARTISTIDorFILE, _onUpdateFunction ){ + instance.init && instance.init(); + + var _data, _artistID = -1; + + if( pettanr.driver.isPettanrFileInstance( _ARTISTIDorFILE ) === true ){ + if( _ARTISTIDorFILE.getType() === pettanr.driver.FILE_TYPE.ARTIST ){ + _data = pettanr.driver._getAPI().getFileData( _ARTISTIDorFILE ); + _artistID = _data !== null ? _data.id || 0 : -1; + } + } else + if( Type.isNumber( _ARTISTIDorFILE ) === true ){ + _artistID = _ARTISTIDorFILE; + } + + //onUpdateFunction = _onUpdateFunction; + if( _onUpdateFunction ){ + _g_onUpdateFunction = pettanr.util.createGlobalFunction( _onUpdateFunction); + } else { + _g_onUpdateFunction = null; + } + + var _index = ARTIST_ROOT_FILE.search( { + id: _artistID, + type: pettanr.driver.FILE_TYPE.ARTIST + } )[ 0 ], + _artistFile = ARTIST_ROOT_FILE.getChildFileByIndex( _index ), + i, l = 0; + if( _artistFile !== null ){ + for( i=0, l=_artistFile.getChildFileLength(); i containerW ? winW : containerW, + h = _windowH > containerH ? containerH : _windowH, + MATH_FLOOR = Math.floor; + + onEnterShowImage(); + + jqContainer.css( { + width: w, + height: 0, + left: 0, + top: MATH_FLOOR( _windowH /2) + }).stop().animate( { + height: h, + top: MATH_FLOOR( _windowH /2 -h /2) + }); + + elmButton.style.cssText = [ + 'left:', MATH_FLOOR( winW /2 - buttonW /2), 'px;', + 'top:', MATH_FLOOR( _windowH /2 + containerH /2 +10), 'px' + ].join(''); + } + this.onPaneResize = function( _windowW, _windowH ){ + var w = _windowW > containerW ? _windowW : containerW, + h = _windowH > containerH ? containerH : _windowH, + MATH_FLOOR = Math.floor, + offsetW = MATH_FLOOR( _windowW /2 -winW /2); + + winW = _windowW; + winH = _windowH; + if( offsetW <= 0){ // smaller + jqContainer.css( { + left: offsetW, + width: w + }).animate( { + left: 0, + top: MATH_FLOOR( _windowH /2 -h /2) + }); + } else { + jqContainer.css( { // bigger + left: 0, + width: w, + borderLeftWidth: offsetW + }).animate( { + top: MATH_FLOOR( _windowH /2 -h /2), + borderLeftWidth: 0 + }); + } + elmButton.style.cssText = [ + 'left:', MATH_FLOOR( _windowW /2 -buttonW /2), 'px;', + 'top:', MATH_FLOOR( _windowH /2 +containerH /2 +10), 'px' + ].join(''); + onEnterShowImage(); + } + this.onClose = function(){ + jqContainer.stop().animate( { + height: 0, + top: Math.floor( winH /2 ) + }); + while( ICON_ARRAY.length > 0 ){ + ICON_ARRAY.shift().destroy(); + } + onEnterInterval !== null && window.clearTimeout( onEnterInterval ); + onEnterInterval = _g_onUpdateFunction = null; + } +}); + + +/* ---------------------------------------- + * Text Editor + * - overlay + */ +pettanr.textEditor = pettanr.view.registerApplication( function(){ + var jqWrap, jqTextarea, jqButton, + textElement, onUpdateFunction, + ID = 'textEditor', + panelX, panelY, + instance = this; + //pettanr.key.addKeyDownEvent( ID, 69, false, false, clickOK); + + function clickOK(){ + textElement && textElement.text( jqTextarea.val() ); + onUpdateFunction && onUpdateFunction( textElement ); + pettanr.textEditor.shutdown(); + } + + function keyCancel( e ){ + if( e.keyCode === 69 && e.shiftKey === false && e.ctrlKey === true){ + clickOK(); + e.preventDefault(); + e.keyCode = 0; + e.cancelBubble = true; + e.returnValue = false; + return false; + } + } + + /* grobal method */ + // this.rootElement = elmWrap; + this.displayName = 'textEditor'; + this.ID = 'textEditor'; + this.rootElement = document.getElementById( 'speach-editor-wrapper' ); + this.MIN_WIDTH = 320; + this.MIN_HEIGHT = 320; + this.init = function(){ + instance.jqWrap = jqWrap = $( '#speach-editor-wrapper' ).hide(); + jqTextarea = $( '#speach-editor' ).keydown( keyCancel ); + jqButton = $( '#speach-edit-complete-button').click( clickOK ); + delete instance.init; + } + this.jqWrap = null; + this.onOpen = function( _w, _h, _panelX, _panelY, _textElement, _onUpdateFunction ){ + instance.init && instance.init(); + + panelX = _panelX; + panelY = _panelY; + textElement = _textElement; + onUpdateFunction = _onUpdateFunction || null; + + var h = _textElement.h; + + instance.onPaneResize( _w, _h ); + jqTextarea.val( _textElement.text() ).focus(); + + /* + * ie6,7は、textarea { width:100%}でも高さが変わらない。rowsを設定。 + */ + pettanr.ua.isIE === true && pettanr.ua.ieVersion <= 7 && setTimeout( function(){ + var rows = 0; + while( jqTextarea.height() < h){ + rows++; + jqTextarea.attr( 'rows', rows); + } + rows > 1 && jqTextarea.attr( 'rows', rows -1 ); + }, 0); + } + this.onPaneResize = function( _w, _h ){ + jqWrap.show().css( { + left: textElement.x + panelX, + top: textElement.y + panelY, + width: textElement.w, + height: textElement.h + }); + } + this.onClose = function(){ + jqWrap.hide(); + textElement = onUpdateFunction = null; + } +}); + +// i18n +// login +// lib + +pettanr.fn( pettanr.view); +pettanr.fn( pettanr.overlay); +pettanr.fn( pettanr.key); +pettanr.fn( pettanr.balloon); + +pettanr.fn( pettanr.editor); + +pettanr.fn( pettanr.file); +pettanr.fn( pettanr.finder); +pettanr.fn( pettanr.gallery); +pettanr.fn( pettanr.cabinet); + +$(window).ready( pettanr.init); diff --git a/app/assets/javascripts/work.js b/app/assets/javascripts/work.js new file mode 100644 index 00000000..84e4a214 --- /dev/null +++ b/app/assets/javascripts/work.js @@ -0,0 +1,3723 @@ +/* + * pettanR work.js + * version 0.4.19 + * + * author: + * itozyun + * licence: + * 3-clause BSD + * + * + * ---------------------------------------- + * naming rules + * + * Class + * ThisIsClass + * + * const + * THIS_IS_CONST = 'this is const'; + * + * var + * thisIsVar + * + * value of jquery + * jqWrapper, JQ_WRAPPER + * + * value of dom element + * elmWrapper, ELM_WRAP + * + * value of vml element + * vmlImg, VML_SHAPE + * + */ + + +/* ---------------------------------------- + * pettanr.editor + * - MENU_BAR_CONTROL + * - HISTORY_CONTROL + * - SAVE_CONTROL + * - WINDOW_CONTROL + * - WindowClass + * - INFOMATION_WINDOW + * - TOOL_BOX_WINDOW + * - HELP_DOCUMENTS_WINDOW + * - PANEL_CONTROL + * - GRID_CONTROL + * - WHITE_GLASS_CONTROL + * - PANEL_CONTROL + * + * + * - PanelResizerClass + * - PANEL_RESIZER_TOP + * - PANEL_RESIZER_BOTTOM + * - CONSOLE_CONTROLER + * + * - TAIL_OPERATOR + * - RESIZE_OPERATOR + * - POSITION_OPERATOR + * - COMIC_ELEMENT_OPERATION_MANAGER + * + * - ImageElementClass + * - TextElementClass + * + * - COMIC_ELEMENT_CONTROL + * + * + */ +pettanr.editor = pettanr.view.registerApplication( function(){ + + var PANEL_ELEMENT_TYPE_IMAGE = 0, + PANEL_ELEMENT_TYPE_TEXT = 1, + MOUSE_LISTENER_ARRAY = [], + COMIC_ELEMENT_ARRAY = [], + ELM_MOUSE_EVENT_CHATCHER = document.getElementById( 'mouse-operation-catcher'), + MIN_PANEL_HEIGHT = 20, + MIN_ELEMENT_SIZE = 19, + MOUSE_HIT_AREA = 10, + jqMouseEventChacher, + jqEditor, + windowW, windowH, + currentListener = null, + currentCursor = '', + instance = this, + option, + log; + +/* ---------------------------------------- + * MENU BAR + * - mouseEventListener + * - controler + * + * div + * div.title + * ul + * li + * a + * span + * kbd shortcut + */ + var MENU_BAR_CONTROL = ( function(){ + var ELM_BAR = document.getElementById( 'menu-bar'), + ELM_ITEM_CLASSNAME = 'menu-bar-item', + ELM_ITEM_ORIGN = ( function(){ + var ret = document.createElement( 'div'), + div = document.createElement( 'div'), + ul = document.createElement( 'ul'); + ret.className = ELM_ITEM_CLASSNAME; + ret.appendChild( div); + ret.appendChild( ul); + return ret; + })(), + ELM_SELECTION_ORIGN = ( function(){ + var ret = document.createElement( 'li'), + a = document.createElement( 'a'), + span = document.createElement( 'span'), + key = document.createElement( 'kbd'); + a.appendChild( span); + a.appendChild( key); + ret.appendChild( a); + a.href = '#'; + return ret; + })(), + ITEM_ARRAY = [], + barH = pettanr.util.getElementSize( ELM_BAR).height, + itemW = pettanr.util.getElementSize( ELM_ITEM_ORIGN).width, + selectionW = pettanr.util.getElementSize( ELM_ITEM_ORIGN.getElementsByTagName( 'ul')[ 0]).width, + jqStage, jqBar; + ELM_BAR.style.top = ( -barH) +'px'; + + var MenubarSelectionClass = function( container, title, shortcut, visible, separateAfter){ + var ELM_WRAPPER = ELM_SELECTION_ORIGN.cloneNode( true), + ELM_TITLE = ELM_WRAPPER.getElementsByTagName( 'span')[ 0], + elmShortcut = ELM_WRAPPER.getElementsByTagName( 'kbd')[ 0]; + + if( shortcut){ + elmShortcut.innerHTML = shortcut; + } else { + elmShortcut.parentNode.removeChild( elmShortcut); + } + elmShortcut = null; + + container.appendChild( ELM_WRAPPER); + + updateTitle( title); + updateVisible( visible); + + function updateTitle( _title){ + ELM_TITLE.innerHTML = title = _title; + } + function updateVisible( _visible){ + if( _visible !== undefined){ + visible = !!_visible; + ELM_WRAPPER.className = visible === true ? '' : 'disabled'; + }; + } + return { + elm: ELM_WRAPPER, + title: function( _title){ + _title !== undefined && updateTitle( _title); + return title; + }, + visible: function( _visible){ + visible !== !!_visible && updateVisible( _visible); + return visible; + }, + separateAfter: separateAfter + } + } + + var MenuBarItemClass = function( title){ + var ELM_WRAPPER = ELM_ITEM_ORIGN.cloneNode( true), + ELM_TITLE = ELM_WRAPPER.getElementsByTagName( 'div')[ 0], + ELM_SELECTION = ELM_WRAPPER.getElementsByTagName( 'ul')[ 0], + INDEX = ITEM_ARRAY.length, + SELECTION_CALLBACK_ARRAY = [], + numSelection = 0, + visible = false; + ELM_TITLE.innerHTML = title; + + ELM_WRAPPER.style.left = ( itemW * INDEX) +'px'; + ELM_BAR.appendChild( ELM_WRAPPER); + + function onClick( e){ + var that = this, + i = pettanr.util.getChildIndex( this.parentNode, this); + i !== -1 && this.className !== 'disabled' && SELECTION_CALLBACK_ARRAY[ i]( i); + e.stopPropagation(); + return false; + } + return { + elm: ELM_WRAPPER, + onClick: onClick, + init: function(){ + $( ELM_SELECTION).children( 'li').click( onClick); + delete this.init; + }, + show: function(){ + if( visible === true) return; + jqStage.append( ELM_WRAPPER); + ELM_WRAPPER.className = ELM_ITEM_CLASSNAME +'-focus'; + this.onShow && setTimeout( this.onShow, 0); + visible = true; + }, + hide: function(){ + if( visible === false) return; + ELM_BAR.appendChild( ELM_WRAPPER); + ELM_WRAPPER.className = ELM_ITEM_CLASSNAME; + this.onHide && setTimeout( this.onHide, 0); + visible = false; + }, + createSelection: function( title, shortcut, callback, visible, separateBefore, separateAfter){ + var ret = MenubarSelectionClass.apply( {}, [ ELM_SELECTION, title, shortcut, visible, separateAfter]), + before = SELECTION_CALLBACK_ARRAY.length > 0 ? SELECTION_CALLBACK_ARRAY[ SELECTION_CALLBACK_ARRAY.length -1] : null; + SELECTION_CALLBACK_ARRAY.push( callback); + if( before !== null && ( separateBefore === true || before.separateAfter === true)){ + ret.elm.style.borderTop = '1px solid #ccc'; + } + return ret; + } + } + } + + + function createMenubarItem( title){ + var _item = new MenuBarItemClass( title); + ITEM_ARRAY.push( _item); + return _item; + } + return { + init: function(){ + jqStage = jqEditor; + jqBar = $( ELM_BAR).animate( { top: 0}); + + var l = ITEM_ARRAY.length; + for( var i=0; i= _mouseY){ + return true; + } + var l = ITEM_ARRAY.length; + for( var i=0; i 0){ + _value = _argBack.shift(); + _destroy === true && typeof _value.destroy === 'function' && _value.destroy(); + } + } + if( Type.isArray( _argForword ) === true ){ + while( _argForword.length > 0){ + _value = _argForword.shift(); + _destroy === true && typeof _value.destroy === 'function' && _value.destroy(); + } + } + } + return { + init: function(){ + log = $( '#history-log'); + delete HISTORY_CONTROL.init; + }, + open: function(){ + HISTORY_CONTROL.init && HISTORY_CONTROL.init(); + }, + close: function(){ + MENUBAR_BACK.visible( false); + MENUBAR_FORWARD.visible( false); + while( STACK_BACK.length > 0){ + destroyStack( STACK_BACK.shift(), true); + } + while( STACK_FORWARD.length > 0){ + destroyStack( STACK_FORWARD.shift(), true); + } + }, + saveState: function( _function, _argBack, _argForword, _destroy) { + STACK_BACK.push( { + fn: _function, + argBack: _argBack, + argForword: _argForword, + destroy: _destroy + }); + MENUBAR_BACK.visible( true); + SAVE_CONTROL.panelUpdated( true); + + var _stack; + while( STACK_FORWARD.length > 0){ + _stack = STACK_FORWARD.shift(); + destroyStack( _stack, _stack.destroy); + } + MENUBAR_FORWARD.visible( false); + } + } + })(); + +/* ---------------------------------------- + * SAVE_CONTROL + * - controler + */ + var SAVE_CONTROL = ( function(){ + var SAVE = MENU_BAR_CONTROL.QUIT.createSelection( 'save', 'ctrl + S', quit, false), + SAVE_AND_QUIT = MENU_BAR_CONTROL.QUIT.createSelection( 'save & quit', null, quit, false, false, true), + SAVE_AS_HTML = MENU_BAR_CONTROL.QUIT.createSelection( 'get as html', null, outputAsHtml, true, false, true), + SAVE_AS_JSON_STRING = MENU_BAR_CONTROL.QUIT.createSelection( 'get JsonStr', null, outputAsJsonString, true, false, true), + QUIT = MENU_BAR_CONTROL.QUIT.createSelection( 'quit', null, quit, true, true), + updated = false; + + function quit(){ + // 本来は os.application.close(); + pettanr.editor.shutdown(); + } + + function outputAsHtml(){ + pettanr.outputConsole.bootInOverlay( COMIC_ELEMENT_CONTROL.getAsHTML( true, false)); + } + function outputAsJsonString(){ + pettanr.outputConsole.bootInOverlay( COMIC_ELEMENT_CONTROL.getAsJsonString()); + } + return { + open: function(){}, + close: function(){}, + quit: quit, + panelUpdated: function( _updated){ + if( _updated !== undefined && updated !== _updated ){ + SAVE.visible( !!_updated ); + SAVE_AND_QUIT.visible( !!_updated ); + updated = !!_updated; + } + return updated; + }, + save: function(){ + + } + } + })(); + +/* ---------------------------------------- + * WINDOWS_CONTROL + * - contloler + * - mouseEventListener + */ + var WINDOWS_CONTROL = ( function(){ + /* + * 表示上手前にあるwindowは、WINDOW_ARRAYの先頭にあり、htmlでは後ろにある。 + */ + var DEFAULT_MIN_WINDOW_WIDTH = 200, + DEFAULT_MIN_WINDOW_HEIGHT = 200, + WINDOW_ARRAY = [], + WINDOW_BODY_BODER_SIZE = 1, + jqContainer, + currentWindow, + currentWindowIndex = -1, + log; + + var jqWindowOrigin, + closeButtonWidth; + var WindowClass = function( bodyTempleteID, title, x, y, w, h, visible, CLOSE_BUTTON_ENABLED, RESIZE_BUTTON_ENABLED, minWindowW, minWindowH){ + var MOUSE_CURSOR = updateMouseCursor, + MENUBAR_SELWCTION = MENU_BAR_CONTROL.WINDOW.createSelection( + ( visible !== true ? 'show ' : 'hide ') +title, + null, onMenuClick, true + ), + jqStage, + jqWrapper, jqHeader, jqFooter = null, + elmBody, elmBodyStyle, + startX, startY, startW, startH, + offsetX, offsetY, + headerH, bodyH, footerH = 0, + isDragging = false, + isResizing = false, + bodyIsTachable = false, + instance; + + function onMenuClick(){ + visible === true ? instance.close() : instance.open(); + } + function update( _x, _y, _w, _h){ + _x = _x !== undefined ? _x : x; + _y = _y !== undefined ? _y : y; + _y = _y > MENU_BAR_CONTROL.h ? _y : MENU_BAR_CONTROL.h; + _w = _w !== undefined ? _w : w; + _h = _h !== undefined ? _h : h; + jqWrapper.css( { + left: _x, + top: _y, + width: _w, + height: _h + }); + bodyH = _h -headerH -footerH; + elmBodyStyle.height = bodyH +'px'; + ( w !== _w || h !== _h) && instance.onResize && instance.onResize( _w, bodyH); + x = _x; + y = _y; + w = _w; + h = _h; + } + function bodyBackOrForward( isBack){ + if( !instance) return; + if( bodyIsTachable === !isBack) return; + elmBodyStyle.position = isBack === true ? 'relative' : 'absolute'; + elmBodyStyle.left = isBack === true ? 0 : x +'px'; + elmBodyStyle.top = isBack === true ? 0 : y +headerH +'px'; + elmBodyStyle.width = isBack === true ? '' : ( w -WINDOW_BODY_BODER_SIZE *2) +'px'; + bodyIsTachable === isBack && isBack === true ? jqHeader.after( elmBody) : jqStage.append( elmBody); + bodyIsTachable = !isBack; + } + function onWindowResize( e){ + bodyBackOrForward( true); + isResizing = true; + startX = x; + startY = y; + startW = w; + startH = h; + offsetX = e.pageX; + offsetY = e.pageY; + MOUSE_CURSOR( 'nw-resize'); + e.stopPropagation(); + return false; + } + return { + init: function( jqContainer){ + /* + * setTimeout で呼ばれるグローバルメソッド内では、this でなく instance を使う. + */ + instance = this; + + jqWindowOrigin = jqWindowOrigin || ( function(){ + return $( $( '#windowTemplete').remove().html()); + })(); + closeButtonWidth = closeButtonWidth || ( function(){ + return pettanr.util.getElementSize( jqWindowOrigin.clone( true).find( '.window-close-button').get( 0)).width; + })(); + + jqStage = jqEditor; + this.$ = jqWrapper = jqWindowOrigin.clone( true); + jqHeader = jqWrapper.children( '.window-header').eq( 0).html( title); + headerH = pettanr.util.getElementSize( jqHeader.get( 0)).height; + elmBody = jqWrapper.children( '.window-body').get( 0); + elmBodyStyle = elmBody.style; + + if( bodyTempleteID) { + jqWrapper.find( '.window-body-insert-position').replaceWith( $( $( '#' +bodyTempleteID).remove().html())); + } else { + jqWrapper.find( '.window-body-insert-position').remove(); + } + CLOSE_BUTTON_ENABLED !== true && jqWrapper.find( '.window-close-button').remove(); + + this.onInit && this.onInit(); + delete this.init; + }, + x: function(){ return x;}, + y: function(){ return y;}, + w: function(){ return w;}, + h: function(){ return h;}, + $: null, + title: function( _title){ + typeof _title === 'string' && jqHeader.html( _title); + title = typeof _title === 'string' ? _title : title; + return title; + }, + visible: visible, + firstOpen: function(){ + if( RESIZE_BUTTON_ENABLED === true){ + footerH = pettanr.util.getElementSize( jqWrapper.find( '.window-footer').get( 0)).height; + //jqWrapper.find( '.window-resize-button').eq( 0).mousedown( onWindowResize); + } else { + jqWrapper.find( '.window-footer').remove(); + } + this.onFirstOpen && this.onFirstOpen( w, h -headerH -footerH); + + update( x, y, w, h); + + delete this.firstOpen; + }, + open: function(){ + if( visible === true) return; + instance.visible = visible = true; + openWindow( instance); + MENUBAR_SELWCTION.title( 'hide ' +title); + + for( var i=0, l = WINDOW_ARRAY.length; i _mouseX || y > _mouseY || x +w < _mouseX || y +headerH < _mouseY ) return; + if( CLOSE_BUTTON_ENABLED === true && x +w -closeButtonWidth < _mouseX){ + instance.close(); + return; + } + + isDragging = true; + MOUSE_CURSOR( 'move'); + startX = x; + startY = y; + startW = w; + startH = h; + offsetX = _mouseX; + offsetY = _mouseY; + }, + onMouseUp: function( _mouseX, _mouseY){ + isDragging = isResizing = false; + MOUSE_CURSOR( ''); + }, + onMouseMove: function( _mouseX, _mouseY){ + var _updateX = _mouseX -offsetX, + _updateY = _mouseY -offsetY; + + if( isResizing === true){ + var _w = startW +_updateX, + _h = startH +_updateY; + update( startX, startY, _w < minWindowW ? minWindowW : _w, _h < minWindowH ? minWindowH : _h); + return; + } else + if( isDragging === true) { + update( startX +_updateX, startY +_updateY); + return; + } else + if( x > _mouseX || x +w < _mouseX ) return; + + ( y <= _mouseY && y +headerH >= _mouseY ) ? + MOUSE_CURSOR( 'pointer') : // hit to header + MOUSE_CURSOR( ''); + bodyBackOrForward( y +headerH > _mouseY || y +headerH +bodyH < _mouseY); + }, + onMouseOut: function( _mouseX, _mouseY){ + bodyIsTachable === true && bodyBackOrForward( true); + isDragging = false; + MOUSE_CURSOR( ''); + }, + busy: function(){ + return isDragging === true || isResizing === true; + }, + bodyHeight: function(){ + return bodyH; + } + } + }; + + function getCurrentIndex( _mouseX, _mouseY){ + if( currentWindow && currentWindow.busy() === true) return currentWindowIndex; + var l = WINDOW_ARRAY.length, + _currentWindow = null, + _win, _x, _y; + currentWindowIndex = -1; + for( var i=0; i= _mouseX && _y +_win.h() >= _mouseY){ + _currentWindow = _win; + currentWindowIndex = i; + break; + } + } + currentWindow && currentWindow !== _currentWindow && currentWindow.onMouseOut( _mouseX, _mouseY); + currentWindow = _currentWindow; + return currentWindowIndex; + } + function openWindow( _window){ + if( _window.visible !== true) return; + var _jqWindow = _window.$; + jqContainer.append( _jqWindow);// appendした後に fadeIn() しないと ie で filterが適用されない. + _jqWindow.fadeIn( _window.onFadeIn); + return; + } + + return { + init: function(){ + jqContainer = $( '#window-container'); + + var l = WINDOW_ARRAY.length, + _window; + for( var i=l-1; i >= 0; --i){ + _window = WINDOW_ARRAY[ i]; + _window.init && _window.init( jqContainer); + _window.visible === true && openWindow( _window); + } + log = $( '#window-log'); + + delete WINDOWS_CONTROL.init; + }, + open: function(){ + WINDOWS_CONTROL.init && WINDOWS_CONTROL.init(); + }, + close: function(){ + + }, + onMouseMove: function( _mouseX, _mouseY){ + var _index = getCurrentIndex( _mouseX, _mouseY); + if( _index === 0){ + currentWindow.onMouseMove( _mouseX, _mouseY); + return true; + } else + if( _index > 0){ // 先頭のクリックでない場合 + // Array を前に + WINDOW_ARRAY.splice( currentWindowIndex, 1); + WINDOW_ARRAY.unshift( currentWindow); + // Domを最後に + jqContainer.append( currentWindow.$); + currentWindowIndex = 0; + return true; + } + return false; + }, + onMouseUp: function( _mouseX, _mouseY){ + if( getCurrentIndex( _mouseX, _mouseY) === 0){ + currentWindow.onMouseUp( _mouseX, _mouseY); + return true; + } + return false; + }, + onMouseDown: function( _mouseX, _mouseY){ + if( getCurrentIndex( _mouseX, _mouseY) === 0){ + currentWindow.onMouseDown( _mouseX, _mouseY); + return true; + } + return false; + }, + busy: function(){ + return currentWindow !== null; + }, + onWindowResize: function( _windowW, _windowH){ + /* + * 画面外に出るwindowの移動 + */ + }, + createWindow: function( EXTENDS, bodyTempleteID, title, x, y, w, h, opt_visible, opt_closeButtonEnabled, opt_resizeButtonEnabled, opt_minWindowW, opt_minWindowH){ + opt_visible = opt_visible !== false; + opt_closeButtonEnabled = opt_closeButtonEnabled === true; + opt_resizeButtonEnabled = opt_resizeButtonEnabled === true; + opt_minWindowW = opt_minWindowW || ( w < DEFAULT_MIN_WINDOW_WIDTH) ? w : DEFAULT_MIN_WINDOW_WIDTH; + opt_minWindowH = opt_minWindowH || ( h < DEFAULT_MIN_WINDOW_HEIGHT) ? h : DEFAULT_MIN_WINDOW_HEIGHT; + + var _window = pettanr.util.extend( + new WindowClass( + bodyTempleteID, title, x, y, w, h, opt_visible, opt_closeButtonEnabled, opt_resizeButtonEnabled, opt_minWindowW, opt_minWindowH + ), + EXTENDS + ); + WINDOW_ARRAY.unshift( _window); + WINDOWS_CONTROL.init === undefined && _window.init( jqContainer); + WINDOWS_CONTROL.init === undefined && openWindow( _window); + return _window; + } + } + })(); + +/* ---------------------------------------- + * TOOL_BOX_WINDOW + * - window + */ + var TOOL_BOX_WINDOW = ( function(){ + var addImageButton, addTextButton, editBgButton, switchGridButton, popupHelpButton, postButton, + instance; + + pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 73, false, true, addImage); + MENU_BAR_CONTROL.EDIT.createSelection( 'Add Image', 'ctrl + I', addImage, true, true, false); + + pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 84, false, true, addText); + MENU_BAR_CONTROL.EDIT.createSelection( 'Add Text', 'ctrl + T', addText, true, false, true); + + pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 71, false, true, switchGrid); + MENU_BAR_CONTROL.EDIT.createSelection( 'show Grid', 'ctrl + G', switchGrid, true, true, true); + + function addImage( e){ + setTimeout( COMIC_ELEMENT_CONTROL.createImageElement, 0); + e && e.preventDefault && e.preventDefault(); + return false; + } + function addText( e){ + setTimeout( COMIC_ELEMENT_CONTROL.createTextElement, 0); + e && e.preventDefault && e.preventDefault(); + return false; + } + function switchGrid( e){ + setTimeout( GRID_CONTROL.update, 0); + e && e.preventDefault && e.preventDefault(); + return false; + } + function popupHelp( e){ + instance.bodyBackOrForward( true); + setTimeout( HELP_DOCUMENTS_WINDOW.open, 0); + e && e.preventDefault && e.preventDefault(); + return false; + } + function editBG( e){ + instance.bodyBackOrForward( true); + setTimeout( INFOMATION_WINDOW.open, 0); + e && e.preventDefault && e.preventDefault(); + return false; + } + + return WINDOWS_CONTROL.createWindow( + { + onInit: function(){ + instance = this; + delete this.onInit; + }, + onFirstOpen: function(){ + addImageButton = $( '#toolbox-add-image-button').click( addImage); + addTextButton = $( '#toolbox-add-text-button').click( addText); + editBgButton = $( '#toolbox-edit-bg-button').click( editBG); + switchGridButton = $( '#toolbox-switch-grid').click( switchGrid); + popupHelpButton = $( '#toolbox-popup-help-button').click( popupHelp); + + postButton = $( '#toolbox-post-button'); + + delete this.onFirstOpen; + } + }, + 'toolbox-window', 'Tool box', 0, 215, 110, 290, true + ); + })(); + + +/* ---------------------------------------- + * IMAGE_EXPROLER + * - window + */ + var IMAGE_EXPLORER_WINDOW = ( function(){ + var instance, finder; + + return WINDOWS_CONTROL.createWindow( + { + onInit: function(){ + instance = this; + delete this.onInit; + }, + onOpen: function( _w, _h){ + finder = finder || pettanr.finder.createFinder( document.getElementById( 'image-exproler-container'), pettanr.driver.createPictureTree()); + finder.open( _w, _h ); + }, + onResize: function( _w, _h ){ + finder.resize( _w, _h ); + } + }, + 'image-exproler', 'Album', 0, 215, 400, 350, false, true, true, 300, 300 + ); + })(); + + +/* ---------------------------------------- + * INFOMATION_WINDOW + * - window + */ + var INFOMATION_WINDOW = ( function(){ + var FADE_EFFECT_ENABLED = true, //pettanr.ua.isIE === false || pettanr.ua.ieVersion >= 8, + FADE_IN_EFFECT = FADE_EFFECT_ENABLED === true ? 'fadeIn' : 'show', + FADE_OUT_EFFECT = FADE_EFFECT_ENABLED === true ? 'fadeOut' : 'hide', + backgroundInfomationElm, + jqComicElementInformation, + inputX, inputY, inputZ, inputA, inputW, inputH, inputAspectRatio, + inputPercentW, inputPercentH, + currentComicElement = null, + currentElementType = -1, + currentLock = false; + + return WINDOWS_CONTROL.createWindow( + { + onFirstOpen: function( _w, _h){ + backgroundInfomationElm = $( '#panel-background-information'); + + jqComicElementInformation = $( '#comic-element-infomation').hide().css( { + height: _h + }); + var TAB_GROUP_ID = 'comic-element-attribute'; + var CREATER = pettanr.form.createInputText;//pettanr.key.createEditableText; + inputX = CREATER( document.getElementById( 'comic-element-x'), null, TAB_GROUP_ID); + inputY = CREATER( document.getElementById( 'comic-element-y'), null, TAB_GROUP_ID); + inputZ = CREATER( document.getElementById( 'comic-element-z'), null, TAB_GROUP_ID); + inputA = CREATER( document.getElementById( 'comic-element-a'), null, TAB_GROUP_ID); + inputW = CREATER( document.getElementById( 'comic-element-w'), null, TAB_GROUP_ID); + inputH = CREATER( document.getElementById( 'comic-element-h'), null, TAB_GROUP_ID); + inputPercentW = CREATER( document.getElementById( 'comic-element-w-percent'), null, TAB_GROUP_ID); + inputPercentH = CREATER( document.getElementById( 'comic-element-h-percent'), null, TAB_GROUP_ID); + inputAspectRatio = $( '#comic-element-keep-aspect'); + delete this.onFirstOpen; + }, + onResize: function( _w, _h){ + jqComicElementInformation.css( { + height: _h + }); + }, + update: function( currentElement){ + + if( currentLock === true && currentElement === null) return; + + var _elementType = currentElement === null ? -1 : currentElement.type, + x = currentElement !== null ? currentElement.x : 0, + y = currentElement !== null ? currentElement.y : 0, + z = currentElement !== null ? currentElement.z : 0, + a = _elementType === PANEL_ELEMENT_TYPE_TEXT ? Math.floor( currentElement.angle()) : 0, + w = currentElement !== null ? currentElement.w : 0, + h = currentElement !== null ? currentElement.h : 0, + actualW = _elementType === PANEL_ELEMENT_TYPE_IMAGE ? currentElement.actualW() : 1, + actualH = _elementType === PANEL_ELEMENT_TYPE_IMAGE ? currentElement.actualH() : 1, + wPercent = _elementType === PANEL_ELEMENT_TYPE_IMAGE ? Math.floor( w / actualW *100) : 0, + hPercent = _elementType === PANEL_ELEMENT_TYPE_IMAGE ? Math.floor( h / actualH *100) : 0, + keepAspect = currentElement !== null && currentElement.keepAspect === true; + + if( currentElementType !== _elementType){ + if( _elementType !== -1){ + if( _elementType === 1){ + inputA.visible( true); + inputPercentW.visible( false); + inputPercentH.visible( false); + inputAspectRatio.hide(); + } else { + inputA.visible( false); + inputPercentW.visible( true); + inputPercentH.visible( true); + inputAspectRatio.show(); + } + currentElementType === -1 && jqComicElementInformation.stop().css( { + filter: '', + opacity: '' + })[ FADE_IN_EFFECT](); + } else { + currentElementType !== -1 && jqComicElementInformation.stop().css({ + filter: '', + opacity: '' + })[ FADE_OUT_EFFECT](); + } + currentElementType = _elementType; + } + if( currentElementType !== -1){ + inputX.value( x); + inputY.value( y); + inputZ.value( z); + _elementType === 1 && inputA.value( a); + inputW.value( w); + inputH.value( h); + _elementType === 0 && inputPercentW.value( wPercent); + _elementType === 0 && inputPercentH.value( hPercent); + } else { + + } + }, + lock: function( _currentLock){ + currentLock = !!_currentLock; + this.bodyBackOrForward( !currentLock); + } + }, + 'infomation-window', 'Infomation', 0, 30, 200, 180, true + ); + })(); + +/* ---------------------------------------- + * HELP_WINDOW + * - window + */ + var HELP_DOCUMENTS_WINDOW = ( function(){ + var visible = true, + jqAjaxContents, + jqNaviItems, + jqPages, + currentPageIndex = 0, + numPage = 0, + HELP = MENU_BAR_CONTROL.HELP, + onLoadFunction = HELP.createAjaxSelection( onAjaxStart), + instance; + + function onAjaxStart( _pageIndex){ + currentPageIndex = _pageIndex || currentPageIndex; + if( onHelpLoad !== null){ + $.ajax({ + url: 'help/jp.xml', + dataType: 'xml', + success: onHelpLoad + }); + onHelpLoad = null; + } + onAjaxStart = new Function; + } + var onHelpLoad = function( _xml){ + var jqXML = $( _xml), + helpTitle = jqXML.find( 'pages').eq( 0).attr( 'title'), + elmNavi = document.createElement( 'div'), + elmItemOrigin = document.createElement( 'a'), + elmPages = document.createElement( 'div'), + elmPageOrigin = document.createElement( 'div'), + elmTitleOrigin = document.createElement( 'h2'), + elmPage; + elmNavi.className = 'sidenavi'; + elmItemOrigin.className = 'sidenavi-item'; + elmItemOrigin.href = '#'; + elmPages.className = 'page-contents'; + elmPageOrigin.className = 'page-content main'; + elmPageOrigin.appendChild( elmTitleOrigin); + + //helpTitle && instance.title( helpTitle); + + jqXML.find( 'page').each( function(){ + var xmlPage = $( this), + title = xmlPage.attr( 'title'), + content = xmlPage.text(); + + elmItemOrigin.innerHTML = title; + elmNavi.appendChild( elmItemOrigin.cloneNode( true)); + + elmTitleOrigin.innerHTML = title; + + elmPage = elmPageOrigin.cloneNode( true); + elmPage.innerHTML = content; + + pettanr.util.cleanElement( elmPage); + + if( elmPage.childNodes.length > 0){ + elmPage.insertBefore( elmTitleOrigin.cloneNode( true), elmPage.childNodes[0]); + } else { + elmPage.appendChild( elmTitleOrigin.cloneNode( true)); + } + elmPages.appendChild( elmPage); + + HELP.createSelection( title, null, onSelectionClick, true); + ++numPage; + }); + onLoadFunction(); + onLoadFunction = null; + + jqAjaxContents.removeClass( 'loading').append( elmNavi, elmPages); + + jqNaviItems = jqAjaxContents.find( 'a.' +elmItemOrigin.className).click( onNaviClick); + jqPages = jqAjaxContents.find( '.page-content'); + jqPages.find( 'a').click( onInnerLinkClick); + + setTimeout( jumpPage, 0); + } + function onSelectionClick( _pageIndex){ + HELP_DOCUMENTS_WINDOW.open(); + jumpPage( _pageIndex); + } + function jumpPage( _index){ + if( typeof _index === 'number' && 0 <= _index && _index < numPage && currentPageIndex !== _index){ + currentPageIndex = _index; + } + jqNaviItems.removeClass( 'current').eq( currentPageIndex).addClass( 'current'); + jqPages.hide().eq( currentPageIndex).show(); + } + function onNaviClick( e){ + // this は + jumpPage( pettanr.util.getChildIndex( this.parentNode, this)); + e.stopPropagation(); + return false; + } + function onInnerLinkClick( e){ + var jump = ( this.href || '').split( '#jump'), + n = jump[1]; + if( !n) return; + jumpPage( '' + parseFloat( n) === n ? parseFloat( n) : -1); + e.stopPropagation(); + return false; + } + return WINDOWS_CONTROL.createWindow( + { + onInit: function(){ + instance = this; + jqAjaxContents = this.$.find( '.window-body').addClass( 'loading'); + delete this.onInit; + }, + onFirstOpen: function( _w, _h){ + jqAjaxContents.css( { height: _h}); + onAjaxStart(); + delete this.onFirstOpen; + }, + onResize: function( _w, _h){ + jqAjaxContents && jqAjaxContents.css( { height: _h}); + } + }, + null, 'Help', 0, 215, 400, 350, false, true, true, 300, 300 + ); + })(); + +/* ---------------------------------------- + * GRID_CONTROL + * - control + * - panelResizeListener + */ + var GRID_CONTROL = ( function(){ + var ELM_GRID = document.getElementById( 'grid'), + BG_URL = "url('images/grid.gif')", + jqGrid, + visible = false; + + return { + init: function(){ + jqGrid = $( ELM_GRID); + delete GRID_CONTROL.init; + }, + open: function(){ + GRID_CONTROL.init && GRID_CONTROL.init(); + }, + close: function(){ + + }, + onPanelResize: function( _panelX, _panelY){ + ELM_GRID.style.backgroundPosition = [ _panelX % 10, 'px ', _panelY % 10, 'px'].join( ''); + ELM_GRID.style.height = windowH +'px'; + }, + enabled: function(){ + return visible; + }, + update: function(){ + jqGrid.css( { + opacity: '', + fliter: '' + }).stop()[ visible === true ? 'fadeOut' : 'fadeIn'](); + + visible = !visible; + + if( visible === true && BG_URL !== null){ + ELM_GRID.style.backgroundImage = BG_URL; + BG_URL = null; + } + return visible; + } + } + })(); + +/* ---------------------------------------- + * WHITE_GLASS_CONTROL + * - panelResizeListener + */ + var WHITE_GLASS_CONTROL = ( function(){ + var styleTop = document.getElementById( 'whiteGlass-top').style, + styleLeft = document.getElementById( 'whiteGlass-left').style, + styleRight = document.getElementById( 'whiteGlass-right').style, + styleBottom = document.getElementById( 'whiteGlass-bottom').style; + + return { + onPanelResize: function( _panelX, _panelY, _panelW, _panelH){ + var _w = _panelW, + _h = _panelH, + marginTop = _panelY, + marginBottom = windowH -_h -marginTop, + marginX = _panelX, + rightWidth = windowW -_w -marginX; + + styleTop.height = ( marginTop < 0 ? 0 : marginTop) +'px'; + + styleLeft.top = marginTop +'px'; + styleLeft.width = ( marginX < 0 ? 0 : marginX) +'px'; + styleLeft.height = ( _h + marginBottom) +'px'; + + styleRight.top = marginTop +'px'; + styleRight.left = _w +marginX +'px'; + styleRight.width = ( rightWidth < 0 ? 0 : rightWidth) +'px'; + styleRight.height = ( _h + marginBottom) +'px'; + + styleBottom.top = ( _h +marginTop) +'px'; + styleBottom.left = marginX +'px'; + styleBottom.width = _w +'px'; + styleBottom.height = ( marginBottom < 0 ? 0 : marginBottom) +'px'; + } + } + })(); + + +/* ---------------------------------------- + * PANEL_CONTROL + * - controler + * - mouseEventListener + * + * panel-border の表示と onPanelResize の通知. + * panel drag. + * + */ + var PANEL_CONTROL = ( function(){ + var ELM_PANEL = document.getElementById('panel-tools-container'), + ELM_PANEL_STYLE = ELM_PANEL.style, + DEFAULT_PANEL_WIDTH = 400, + DEFAULT_PANEL_HEIGHT = 300, + borderSize = 2, + panelW, panelH, panelX, panelY, + offsetX, offsetY, startX, startY, + isDragging = false, + isDraggable = false; + + pettanr.key.addKeyUpdateEvent( pettanr.view.EDITOR, 32, false, false, onSpaceUpdate); + + function onSpaceUpdate(e){ + if( e.type === 'keyup'){ + currentListener === null && updateMouseCursor( ''); + isDraggable = false; + } else { + currentListener === null && updateMouseCursor( 'move'); + isDraggable = true; + } + } + + return { + open: function( _panelW, _panelH, _borderSize ){ + panelW = Type.isFinite( _panelW ) === true ? _panelW : DEFAULT_PANEL_WIDTH; + panelH = Type.isFinite( _panelH ) === true ? _panelH : DEFAULT_PANEL_HEIGHT; + //panelX = Math.floor( ( windowW -panelW) /2); + //panelY = Math.floor( ( windowH -panelH) /2); + borderSize = Type.isFinite( _borderSize ) === true ? _borderSize : borderSize; + + //setTimeout( PANEL_CONTROL.resize, 0); + }, + close: function(){ + + }, + x: function(){ + return panelX; + }, + y: function(){ + return panelY; + }, + resize: function( isResizerTopAction, _x, _y, _w, _h){ + panelX = _x !== undefined ? _x : panelX; + panelY = _y !== undefined ? _y : panelY; + panelW = _w !== undefined ? _w : panelW; + panelH = _h !== undefined ? _h : panelH; + + ELM_PANEL_STYLE.left = ( panelX -borderSize) +'px'; + ELM_PANEL_STYLE.top = ( panelY -borderSize) +'px'; + ELM_PANEL_STYLE.width = panelW +'px'; + ELM_PANEL_STYLE.height = panelH +'px'; + + PANEL_RESIZER_TOP.onPanelResize( panelX, panelY, panelW, panelH); + PANEL_RESIZER_BOTTOM.onPanelResize( panelX, panelY, panelW, panelH); + GRID_CONTROL.onPanelResize( panelX, panelY); + WHITE_GLASS_CONTROL.onPanelResize( panelX, panelY, panelW, panelH); + COMIC_ELEMENT_CONTROL.onPanelResize( panelX, panelY, panelW, panelH, isResizerTopAction === true); + }, + onWindowResize: function( _windowW, _windowH){ + panelX = Math.floor(( _windowW - panelW) / 2); + panelY = Math.floor(( _windowH - panelH) / 2); + PANEL_CONTROL.resize(); + }, + onMouseMove: function( _mouseX, _mouseY){ + if( isDraggable === true && isDragging === true){ + PANEL_CONTROL.resize( false, startX +_mouseX -offsetX, startY +_mouseY -offsetY); + } + }, + onMouseUp: function( _mouseX, _mouseY){ + if( isDraggable === true){ + isDragging = false; + updateMouseCursor( ''); + } + }, + onMouseDown: function( _mouseX, _mouseY){ + if( isDraggable === true){ + offsetX = _mouseX; + offsetY = _mouseY; + startX = panelX; + startY = panelY; + isDragging = true; + updateMouseCursor( 'move'); + return true; + } + }, + busy: function(){ + return isDragging === true; + } + } + })(); + +/* -------------------------------------------------------------------------------------------- + * PanelResizerClass + * - mouseEventListener + */ + var PanelResizerClass = function( ID, isTop){ + var ELM = document.getElementById( ID), + BORDER_WIDTH = 2, + RESIZER_HEIGHT = 30, + x = -BORDER_WIDTH /2, + y = isTop === true ? ( -5 -RESIZER_HEIGHT -BORDER_WIDTH) : 0, + w, + h = RESIZER_HEIGHT, + panelX, panelY, panelW, panelH, + offsetY, startY, startH, + isDragging = false, + MOUSE_CURSOR = updateMouseCursor; + + function restoreState( arg){ + if( arg && arg.length > 3){ + PANEL_CONTROL.resize( isTop, arg[ 0] || panelX, arg[ 1] || panelY, arg[ 2] || panelW, arg[ 3] || panelH); + } + } + + this.onMouseDown = function( _mouseX, _mouseY){ + var _x = _mouseX -panelX, + _y = _mouseY -panelY; + if( _x < x || x + w < _x || _y < y || y + h < _y) return false; + offsetY = _y; + startY = panelY; + startH = panelH; + isDragging = true; + MOUSE_CURSOR( 'n-resize'); + return true; + } + this.onMouseMove = function( _mouseX, _mouseY){ + var _x = _mouseX -panelX, + _y = _mouseY -panelY; + if( isDragging !== true){ + if( _x < x || x + w < _x || _y < y || y + h < _y) return false; + COMIC_ELEMENT_OPERATION_MANAGER.hide(); + MOUSE_CURSOR( 'pointer'); + return true; + } else { + var move = _y -offsetY; + if( isTop === true){ + if( panelH - move < MIN_PANEL_HEIGHT){ + move = panelH -MIN_PANEL_HEIGHT; + } + PANEL_CONTROL.resize( true, panelX, panelY + move, panelW, panelH - move); + } else { + var _h = startH +move; + if( 0 < _h && _h < windowH -panelY -RESIZER_HEIGHT -5 -BORDER_WIDTH){ + PANEL_CONTROL.resize( false, panelX, panelY, panelW, _h < MIN_PANEL_HEIGHT ? MIN_PANEL_HEIGHT : _h); + } + } + } + return true; + } + this.onMouseUp = function( _mouseX, _mouseY){ + if( isDragging !== true) return; + ( startY !== panelY || startH !== panelH) && HISTORY_CONTROL.saveState( restoreState, [ NaN, startY, NaN, startH], [ NaN, panelY, NaN, panelH]); + isDragging = false; + MOUSE_CURSOR( ''); + } + this.busy = function(){ + return isDragging + } + this.onPanelResize = function( _x, _y, _w, _h){ + panelX = _x; + panelY = _y; + if( panelW !== _w){ + ELM.style.width = ( _w +2) +'px'; + panelW = _w; + } + panelH = _h; + y = isTop === true ? y : ( panelH +5 +BORDER_WIDTH); + w = panelW +2; + } + }; + var PANEL_RESIZER_TOP = new PanelResizerClass( 'panel-resizer-top', true ), + PANEL_RESIZER_BOTTOM = new PanelResizerClass( 'panel-resizer-bottom', false ); + + PanelResizerClass = undefined; + +/* -------------------------------------------------------------------------------------------- + * CONSOLE_CONTROLER + */ + var CONSOLE_CONTROLER = ( function(){ + var LAYER_BACK_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'layer back', 'ctrl + B', layerBack, false, true, false), + LAYER_FORWARD_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'layer forward', 'ctrl + F', layerForward, false, false, false), + DELETE_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'delete', 'ctrl + D', del, false, true, true), + EDIT_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'Edit Text', 'ctrl + E', edit, false, true, false), + CHANGE_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'change', 'ctrl + U', change, false, false, true), + SAVE = HISTORY_CONTROL.saveState, + jqStage, + jqConsoleParent, + jqConsoleWrapper, + jqConsoleTail, + jqImgConsole, jqTextConsole, + currentElement = null, + currentType = -1, + visible = false, + imgConsoleWidth, imgConsoleHeight, + textConsoleWidth, textConsoleHeight, + consoleWidth, consoleHeight, + consoleX, consoleY, + tailSize = 10, + buttonClickable = false; + + pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 66, false, true, layerBack); + pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 70, false, true, layerForward); + + pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 68, false, true, del); + pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 69, false, true, edit); + pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 85, false, true, change); + + function buttonBackOrForward( isBack){ + var offest = jqConsoleWrapper.offset(); + jqConsoleWrapper.css( { + position: isBack === true ? '' : 'absolute', + left: isBack === true ? consoleX : offest.left, + top: isBack === true ? consoleY : offest.top + }); + buttonClickable === isBack && ( isBack === true ? jqConsoleParent : jqStage).append( jqConsoleWrapper); + buttonClickable = !isBack; + } + function layerBack(){ + if( currentElement === null) return; + if( COMIC_ELEMENT_CONTROL.replace( currentElement, false) === false) return; + INFOMATION_WINDOW.update( currentElement); + SAVE( COMIC_ELEMENT_CONTROL.restoreReplace, [ currentElement, true], [ currentElement, false]); + var _z = currentElement.z; + LAYER_BACK_BUTTON.visible( _z > 0); + LAYER_FORWARD_BUTTON.visible( _z < COMIC_ELEMENT_ARRAY.length -1); + } + function layerForward(){ + if( currentElement === null) return; + if( COMIC_ELEMENT_CONTROL.replace( currentElement, true) === false) return; + INFOMATION_WINDOW.update( currentElement); + SAVE( COMIC_ELEMENT_CONTROL.restoreReplace, [ currentElement, false], [ currentElement, true]); + var _z = currentElement.z; + LAYER_BACK_BUTTON.visible( _z > 0); + LAYER_FORWARD_BUTTON.visible( _z < COMIC_ELEMENT_ARRAY.length -1); + } + function del(){ + if( currentElement === null) return; + buttonBackOrForward( true); + COMIC_ELEMENT_CONTROL.remove( currentElement); + SAVE( COMIC_ELEMENT_CONTROL.restore, [ true, currentElement], [ false, currentElement], true); + COMIC_ELEMENT_OPERATION_MANAGER.hide(); + } + function edit(){ + if( currentElement === null || currentElement.type !== PANEL_ELEMENT_TYPE_TEXT) return; + pettanr.textEditor.bootInOverlay( PANEL_CONTROL.x(), PANEL_CONTROL.y(), currentElement ); + buttonBackOrForward( true); + } + function change(){ + if( currentElement === null) return; + buttonBackOrForward( true); + pettanr.premiumSatge.bootInOverlay( currentElement.getArtistID(), currentElement.resourcePicture ); + } + function onImageSelect( resourcePicture ){ + currentElement.resourcePicture( resourcePicture ); + } + return { + init: function(){ + jqStage = jqEditor; + jqConsoleTail = $( '#comic-element-consol-tail'); + jqImgConsole = $( '#image-element-consol').hide(); + var imgConsoleSize = pettanr.util.getElementSize( jqImgConsole.get( 0)); + imgConsoleWidth = imgConsoleSize.width; + imgConsoleHeight = imgConsoleSize.height; + + jqTextConsole = $( '#text-element-consol').hide(); + var textConsoleSize = pettanr.util.getElementSize( jqTextConsole.get( 0)); + textConsoleWidth = textConsoleSize.width; + textConsoleHeight = textConsoleSize.height; + + jqConsoleWrapper = $( '#comic-element-consol-wrapper').hide(); + jqConsoleParent = jqConsoleWrapper.parent(); + + $( '#edit-text-button').click( edit); + $( '#delete-image-button, #delete-text-button').click( del); + $( '#change-image-button').click( change); + $( '#layer-forward-button, #forward-text-button').click( layerForward); + $( '#layer-back-button, #back-text-button').click( layerBack); + + delete CONSOLE_CONTROLER.init; + }, + show: function( _currentElement, _w, _h ){ + CONSOLE_CONTROLER.init && CONSOLE_CONTROLER.init(); + + visible === false && jqConsoleWrapper.show(); + visible = true; + currentElement = _currentElement; + var _currentType = _currentElement.type, + _z = _currentElement.z; + if( currentType !== _currentType){ + currentType = _currentType; + jqImgConsole.toggle( _currentType === PANEL_ELEMENT_TYPE_IMAGE); + jqTextConsole.toggle( _currentType === PANEL_ELEMENT_TYPE_TEXT); + consoleWidth = _currentType === PANEL_ELEMENT_TYPE_IMAGE ? imgConsoleWidth : textConsoleWidth; + consoleHeight = _currentType === PANEL_ELEMENT_TYPE_IMAGE ? imgConsoleHeight : textConsoleHeight; + } + consoleX = Math.floor( ( _w -consoleWidth) /2); + + LAYER_BACK_BUTTON.visible( _z > 0); + LAYER_FORWARD_BUTTON.visible( _z < COMIC_ELEMENT_ARRAY.length -1); + DELETE_BUTTON.visible( true); + EDIT_BUTTON.visible( _currentType === PANEL_ELEMENT_TYPE_TEXT); + CHANGE_BUTTON.visible( false); + + if( _w > consoleWidth * 1.5 && _h > consoleHeight * 1.5){ + consoleY = Math.floor( ( _h -consoleHeight) /2); + jqConsoleWrapper.css( { + left: consoleX, + top: consoleY + }).removeClass( 'console-out'); + } else { + consoleY = _h +tailSize; + jqConsoleWrapper.css( { + left: consoleX, + top: consoleY + }).addClass( 'console-out'); + } + }, + hide: function (){ + visible === true && jqConsoleWrapper.hide(); + visible = false; + currentElement = null; + LAYER_BACK_BUTTON.visible( false); + LAYER_FORWARD_BUTTON.visible( false); + DELETE_BUTTON.visible( false); + EDIT_BUTTON.visible( false); + CHANGE_BUTTON.visible( false); + }, + x: function(){ return consoleX;}, + y: function(){ return consoleY;}, + w: function(){ return consoleWidth;}, + h: function(){ return consoleHeight;}, + onMouseMove: function( _mouseX, _mouseY){ + if( consoleX > _mouseX || consoleY > _mouseY || consoleX +consoleWidth < _mouseX || consoleY +consoleHeight < _mouseY){ + buttonClickable === true && buttonBackOrForward( true); + return false; + } + buttonClickable === false && buttonBackOrForward( false); + return true; + }, + onMouseOut: function( _mouseX, _mouseY){ + buttonClickable === true && buttonBackOrForward( true); + } + } + })(); + +/* -------------------------------------------------------------------------------------------- + * TAIL_OPERATOR + * - comicElementOperator + */ + var TAIL_OPERATOR = ( function(){ + var MOUSE_CURSOR = updateMouseCursor, + ELM_MOVER = document.getElementById( 'balloon-tail-mover'), + SIZE = pettanr.util.getElementSize( ELM_MOVER).width, + SIN = Math.sin, + COS = Math.cos, + ATAN = Math.atan, + FLOOR = Math.floor, + DEG_TO_RAD = Math.PI / 180, + RAD_TO_DEG = 1 /DEG_TO_RAD, + currentText = null, + tailX, tailY, + x, y, w, h, + balloonW, balloonH, balloonA, radA, + visible = false, + startA; + + return { + update: function ( _w, _h, _a){ + balloonW = _w !== undefined ? _w : balloonW; + balloonH = _h !== undefined ? _h : balloonH; + balloonA = _a !== undefined ? _a : balloonA; + radA = balloonA *DEG_TO_RAD; + tailX = FLOOR( ( ( COS( radA) /2 +0.5) *( balloonW +SIZE)) -SIZE /2); + tailY = FLOOR( ( ( SIN( radA) /2 +0.5) *( balloonH +SIZE)) -SIZE /2); + ELM_MOVER.style.left = tailX +'px'; + ELM_MOVER.style.top = tailY +'px'; + //log.html( [ balloonW, balloonH, balloonA].join()); + }, + show: function( _currentText){ + /* + * visibilityのほうがいい, display:none だと ie で描画が狂う + */ + ELM_MOVER.style.visibility = ''; + this.update( _currentText.w, _currentText.h, _currentText.angle()); + currentText = _currentText; + }, + hitTest: function( _mouseX, _mouseY){ + var _x = tailX -SIZE /2, + _y = tailY -SIZE /2; + ret = _x <= _mouseX && _y <= _mouseY && _x +SIZE >= _mouseX && _y +SIZE >= _mouseY; + ret === true && MOUSE_CURSOR( 'move'); + return ret; + }, + hide: function(){ + ELM_MOVER.style.visibility = 'hidden'; + currentText = null; + }, + onStart: function( _currentText, _mouseX, _mouseY){ + if( _currentText.type !== PANEL_ELEMENT_TYPE_TEXT) return false; + x = _currentText.x; + y = _currentText.y; + if( this.hitTest( _mouseX -x, _mouseY -y) === true){ + w = _currentText.w; + h = _currentText.h; + currentText = _currentText; + startA = _currentText.angle(); + return true; + } + return false; + }, + onDrag: function( _mouseX, _mouseY){ + _mouseX = _mouseX -x -w /2; + _mouseY = _mouseY -y -h /2; //Balloonの中心を0,0とする座標系に変換 + + this.update( w, h, + _mouseX !== 0 ? + ATAN( _mouseY /_mouseX) *RAD_TO_DEG +( _mouseX < 0 ? 180 : 0) : + _mouseY > 0 ? 90 : -90 + ); + currentText && currentText.angle( balloonA); + INFOMATION_WINDOW.update( currentText); + }, + onFinish: function(){ + startA !== currentText.angle() && COMIC_ELEMENT_OPERATION_MANAGER.saveStatus( x, y, w, h, startA); + startA !== currentText.angle() && COMIC_ELEMENT_OPERATION_MANAGER.resize( x, y, w, h, currentText.angle()); + currentText = null; + }, + onCancel: function(){ + currentText.angle( startA); + COMIC_ELEMENT_OPERATION_MANAGER.resize( x, y, w, h, startA); + currentText = null; + } + } + })(); + +/* -------------------------------------------------------------------------------------------- + * RESIZE_OPERATOR + * - comicElementOperator + */ + var RESIZE_OPERATOR = ( function(){ + var MOUSE_CURSOR = updateMouseCursor, + GRID_ENABLED = GRID_CONTROL.enabled; + + var HIT_AREA = MOUSE_HIT_AREA, + POSITION_ARRAY = [], + FLOOR = Math.floor, + CURSOR_AND_FLIP = [ + { cursor: 'n-resize', v: 3}, + { cursor: 'e-resize', h: 2}, + { cursor: 'e-resize', h: 1}, + { cursor: 'n-resize', v: 0}, + { cursor: 'nw-resize', h: 5, v: 6, vh: 7}, + { cursor: 'ne-resize', h: 4, v: 7, vh: 6}, + { cursor: 'ne-resize', h: 7, v: 4, vh: 5}, + { cursor: 'nw-resize', h: 6, v: 5, vh: 4} + ], + elmResizerContainer = document.getElementById( 'comic-element-resizer-container'), + elmResizerContainerStyle = elmResizerContainer.style, + elmResizerTopStyle = document.getElementById( 'comic-element-resizer-top').style, + elmResizerLeftStyle = document.getElementById( 'comic-element-resizer-left').style, + elmResizerRightStyle = document.getElementById( 'comic-element-resizer-right').style, + elmResizerBottomStyle = document.getElementById( 'comic-element-resizer-bottom').style, + x, y, w, h, + currentIndex = -1, + currentElement, + currentIsTextElement = false; + + elmResizerContainerStyle.display = 'none'; + + var RESIZE_WORK_ARRAY = [ + { x: 0, w: 0, y: 1, h: -1}, //top + { x: 1, w: -1, y: 0, h: 0}, //left + { x: 0, w: 1, y: 0, h: 0}, //right + { x: 0, w: 0, y: 0, h: 1}, //bottom + { x: 1, w: -1, y: 1, h: -1}, //top-left + { x: 0, w: 1, y: 1, h: -1}, //top-right + { x: 1, w: -1, y: 0, h: 1}, //bottom-left + { x: 0, w: 1, y: 0, h: 1} //bottom-right + ], + startX, startY, startW, startH, startFilpV, startFilpH, startAspect, + baseX, baseY, baseW, baseH, + currentX, currentY, currentW, currentH, + offsetX, offsetY, + lock = false, + error = 0; + + function draw( _x, _y, _w, _h){ + x = _x !== undefined ? _x : x; + y = _y !== undefined ? _y : y; + w = _w !== undefined ? _w : w; + h = _h !== undefined ? _h : h; + try { + elmResizerContainerStyle.left = x +'px'; + elmResizerContainerStyle.top = y +'px'; + elmResizerContainerStyle.width = w +'px'; + elmResizerContainerStyle.height = h +'px'; + elmResizerTopStyle.left = FLOOR( w /2 -10 /2) +'px'; + elmResizerLeftStyle.top = FLOOR( h /2 -10 /2) +'px'; + elmResizerRightStyle.top = FLOOR( h /2 -10 /2) +'px'; + elmResizerBottomStyle.left = FLOOR( w /2 -10 /2) +'px'; + } catch(e){ + alert( [x, y, w, h].join( ',')); + return; + } + + + POSITION_ARRAY.splice( 0, POSITION_ARRAY.length); + POSITION_ARRAY.push( + {x: x +5, y: y -HIT_AREA, w: w -5 *2, h: HIT_AREA +5}, + {x: x -HIT_AREA, y: y +HIT_AREA +5, w: HIT_AREA +5, h: h -5 *2}, + {x: x +w -5, y: y +HIT_AREA +5, w: HIT_AREA +5, h: h -5 *2}, + {x: x +5, y: y +h -5, w: w -5 *2, h: HIT_AREA +5}, + {x: x -HIT_AREA, y: y -HIT_AREA, w: HIT_AREA +5, h: HIT_AREA +5}, + {x: x +w -HIT_AREA, y: y -HIT_AREA, w: HIT_AREA +5, h: HIT_AREA +5}, + {x: x -HIT_AREA, y: y +h -5, w: HIT_AREA +5, h: HIT_AREA +5}, + {x: x +w -5, y: y +h -5, w: HIT_AREA +5, h: HIT_AREA +5} + ); + } + + function update( _x, _y, _w, _h){ + x = _x !== undefined ? _x : currentX; + y = _y !== undefined ? _y : currentY; + w = _w !== undefined ? _w : currentW; + h = _h !== undefined ? _h : currentH; + + if( currentIsTextElement === false && currentIndex > 3 && pettanr.key.shiftEnabled() === true){ + if( startAspect >= 1){ + _w = w; + w = Math.floor( startAspect * h); + x = x +( currentIndex % 2 === 0 ? _w -w : 0); + } else { + _h = h; + h = Math.floor( w / startAspect); + y = y + ( currentIndex <= 5 ? _h -h : 0); + } + } + draw( x, y, w, h); + currentElement.resize( x, y, w, h); + currentIsTextElement === true && TAIL_OPERATOR.update( w, h); + CONSOLE_CONTROLER.show( currentElement, w, h); + INFOMATION_WINDOW.update( currentElement); + } + + function flip( _flipH, _flipV){ + var p = CURSOR_AND_FLIP[ currentIndex]; + currentIndex = _flipH === true || _flipV === true ? p[ + _flipH === true && _flipV === true ? 'vh' : ( _flipH === true ? 'h' : 'v') + ] : currentIndex; + MOUSE_CURSOR( CURSOR_AND_FLIP[ currentIndex].cursor); + elmResizerContainer.className = 'current-resizer-is-' +currentIndex; + currentElement.flip( _flipH, _flipV); + } + return { + update: draw, + index: function( _mouseX, _mouseY){ + var p, i; + for( i=4; i<8; i++){ + p = POSITION_ARRAY[ i]; + if( p.x <= _mouseX && p.y <= _mouseY && p.x + p.w >= _mouseX && p.y +p.h >= _mouseY){ + MOUSE_CURSOR( CURSOR_AND_FLIP[ i].cursor); + elmResizerContainer.className = 'current-resizer-is-' +i; + return currentIndex = i; + } + } + for( i=0; i<4; i++){ + p = POSITION_ARRAY[ i]; + if( p.x <= _mouseX && p.y <= _mouseY && p.x + p.w >= _mouseX && p.y +p.h >= _mouseY){ + MOUSE_CURSOR( CURSOR_AND_FLIP[ i].cursor); + elmResizerContainer.className = 'current-resizer-is-' +i; + return currentIndex = i; + } + } + MOUSE_CURSOR( ''); + elmResizerContainer.className = ''; + return -1; + }, + show: function( _currentElement){ + currentElement = _currentElement; + currentIsTextElement = _currentElement.type === PANEL_ELEMENT_TYPE_TEXT; + elmResizerContainerStyle.display = ''; + }, + hide: function(){ + currentElement = null; + elmResizerContainerStyle.display = 'none'; + }, + onStart: function( _currentElement, _mouseX, _mouseY){ + currentElement = _currentElement; + currentIsTextElement = _currentElement.type === PANEL_ELEMENT_TYPE_TEXT; + if( _currentElement.keepSize === true) return false; + currentIndex = this.index( _mouseX, _mouseY); + if( currentIndex === -1) return false; + offsetX = _mouseX; + offsetY = _mouseY; + startX = baseX = _currentElement.x; + startY = baseY = _currentElement.y; + startW = baseW = _currentElement.w; + startH = baseH = _currentElement.h; + if( _currentElement.type === PANEL_ELEMENT_TYPE_IMAGE){ + startFilpV = _currentElement.flipV(); + startFilpH = _currentElement.flipH(); + } + startAspect = startW /startH; + return true; + }, + onDrag: function( _mouseX, _mouseY){ + var com = RESIZE_WORK_ARRAY[ currentIndex], + moveX = _mouseX -offsetX, + moveY = _mouseY -offsetY, + _updated = moveX !== 0 || moveY !== 0, + _x, _y, _w, _h, + _thisError = 0; + + var _memoryX = 0, + _memoryY = 0, + _momoryW = 0, + _momoryH = 0; + /* + * Opera 11+ often forget values, why ?? + */ + while( _x === undefined || _y === undefined || _w === undefined || _h === undefined){ + _x = _x !== undefined ? _x : baseX +moveX *com.x; + _y = _y !== undefined ? _y : baseY +moveY *com.y; + _w = _w !== undefined ? _w : baseW +moveX *com.w; + _h = _h !== undefined ? _h : baseH +moveY *com.h; + error += _thisError === 0 ? 0 : 1; + ++_thisError; + if( _thisError > 9999){ + ++error + //alert( 'opera error' +error); + this.onCancel; + return; + } + } + + if( _w >= MIN_ELEMENT_SIZE && _h >= MIN_ELEMENT_SIZE){ + + } else + if( _w >= -MIN_ELEMENT_SIZE && _h >= -MIN_ELEMENT_SIZE){ + //return; + if( _w < MIN_ELEMENT_SIZE){ + //_x += Math.abs( MIN_ELEMENT_SIZE -_w); + _x = currentX; + _w = MIN_ELEMENT_SIZE; + } + if( _h < MIN_ELEMENT_SIZE){ + //_y += Math.abs( MIN_ELEMENT_SIZE -_h); + _y = currentY; + _h = MIN_ELEMENT_SIZE; + } + } else + if( currentElement.type === PANEL_ELEMENT_TYPE_TEXT){ + return; + } else + if( _w < -MIN_ELEMENT_SIZE || _h < -MIN_ELEMENT_SIZE){ + + if( _w < -MIN_ELEMENT_SIZE && _h > MIN_ELEMENT_SIZE){ + // flipH + _memoryX = _x; + baseX = _x = _x +_w; + baseY = _y; + baseW = _w = _memoryX -_x; + baseH = _h; + flip( true, false); + flipV = currentElement.flipV(); + } else + if( _w > MIN_ELEMENT_SIZE && _h < -MIN_ELEMENT_SIZE){ + // flipV + _memoryY = _y; + baseX = _x; + baseY = _y = _y +_h; + baseW = _w; + baseH = _h = _memoryY -_y; + flip( false, true); + flipH = currentElement.flipH(); + } else { + // flipVH + _memoryX = _x; + _memoryY = _y; + baseX = _x = _x +_w; + baseY = _y = _y +_h; + baseW = _w = _memoryX -_x; + baseH = _h = _memoryY -_y; + flip( true, true); + flipV = currentElement.flipV(); + flipH = currentElement.flipH(); + } + _updated = true; + offsetX = _mouseX; + offsetY = _mouseY; + } + currentX = _x; + currentY = _y; + currentW = _w; + currentH = _h; + _updated === true && update( _x, _y, _w, _h); + + log.html( [ + 'currentIndex:', currentIndex, + 'baseW', baseW, 'baseH', baseH,'
', + 'mouse', _mouseX, _mouseY,'
', + 'move', moveX, moveY,'
', + 'xy', _x, _y, 'wh',_w, _h,'
', + 'com.w', com.w, 'com.h', com.h,'
', + 'current',currentW, currentH,'
', + 'result', y, h, + 'err', error + ].join( ' , ')); + }, + onFinish: function(){ + MOUSE_CURSOR( ''); + if( w === startW && h === startH && x === startX && y === startY) return; + COMIC_ELEMENT_OPERATION_MANAGER.resize( x, y, w, h); + currentElement.resize( x, y, w, h); + COMIC_ELEMENT_OPERATION_MANAGER.saveStatus( startX, startY, startW, startH, undefined, startFilpV, startFilpH); + }, + onCancel: function(){ + MOUSE_CURSOR( ''); + COMIC_ELEMENT_OPERATION_MANAGER.resize( startX, startY, startW, startH); + currentElement.type === PANEL_ELEMENT_TYPE_IMAGE ? + currentElement.animate( startX, startY, startW, startH, startFilpV, startFilpH) : + currentElement.animate( startX, startY, startW, startH, angle); + }, + lock: function( _lock){ + if( _lock !== undefined){ + elmResizerContainerStyle.borderColor = _lock === true ? 'blue' : ''; + lock = _lock; + } + return lock; + }, + onShiftUpdate: update, + onCtrlUpdate: update + } + })(); + +/* -------------------------------------------------------------------------------------------- + * POSITION_OPERATOR + * - comicElementOperator + */ + var POSITION_OPERATOR = ( function(){ + var MOUSE_CURSOR = updateMouseCursor, + GRID_ENABLED = GRID_CONTROL.enabled; + + var currentElement, + startX, startY, + x, y, + offsetX, offsetY, + isCopy = false; + + function update( _x, _y){ + x = _x !== undefined ? _x : x; + y = _y !== undefined ? _y : y; + RESIZE_OPERATOR.update( x, y); + currentElement.resize( x, y); + INFOMATION_WINDOW.update( currentElement); + } + + return { + onStart: function( _currentElement, _mouseX, _mouseY){ + currentElement = _currentElement; + offsetX = _mouseX; + offsetY = _mouseY; + startX = x = _currentElement.x; + startY = y = _currentElement.y; + MOUSE_CURSOR( 'move'); + }, + onDrag: function( _mouseX, _mouseY){ + var moveX = _mouseX -offsetX, + moveY = _mouseY -offsetY, + _x = startX +moveX, + _y = startY +moveY; + if( GRID_ENABLED() === true){ + _x = Math.floor( _x / 10) * 10; + _y = Math.floor( _y / 10) * 10; + } + update( _x, _y); + }, + onFinish: function(){ + MOUSE_CURSOR( ''); + if( x === startX && y === startY) return; + COMIC_ELEMENT_OPERATION_MANAGER.resize( x, y); + currentElement.resize( x, y); + COMIC_ELEMENT_OPERATION_MANAGER.saveStatus( startX, startY); + }, + onCancel: function(){ + MOUSE_CURSOR( ''); + COMIC_ELEMENT_OPERATION_MANAGER.resize( startX, startY); + currentElement.animate( startX, startY); + }, + onShiftUpdate: update, + onCtrlUpdate: update + } + })(); + + +/* -------------------------------------------------------------------------------------------- + * COMIC_ELEMENT_OPERATION_MANAGER + */ + var COMIC_ELEMENT_OPERATION_MANAGER = ( function(){ + var MOUSE_CURSOR = updateMouseCursor, + SAVE = HISTORY_CONTROL.saveState, + GRID_ENABLED = GRID_CONTROL.enabled, + HIT_AREA = MOUSE_HIT_AREA, + currentIsTextElement = false, + currentOperator = null, + currentElement = null, + currentx, currenty, currentw, currenth, angle, flipV, flipH; + + function resize( _x, _y, _w, _h, _angle){ + currentx = _x !== undefined ? _x : currentx; + currenty = _y !== undefined ? _y : currenty; + currentw = _w !== undefined ? _w : currentw; + currenth = _h !== undefined ? _h : currenth; + angle = _angle !== undefined ? _angle : angle; + + RESIZE_OPERATOR.update( currentx, currenty, currentw, currenth); + currentIsTextElement === true && TAIL_OPERATOR.update( currentw, currenth, angle); + CONSOLE_CONTROLER.show( currentElement, currentw, currenth); + INFOMATION_WINDOW.update( currentElement); + } + function show( _currentElement){ + currentElement === null && RESIZE_OPERATOR.show( _currentElement); + if( currentElement !== _currentElement){ + currentElement = _currentElement; + + currentIsTextElement = ( _currentElement.type === PANEL_ELEMENT_TYPE_TEXT); + currentIsTextElement === true ? TAIL_OPERATOR.show( _currentElement) : TAIL_OPERATOR.hide(); + + flipV = currentIsTextElement === false ? _currentElement.flipV() : 0; + flipH = currentIsTextElement === false ? _currentElement.flipH() : 0; + + resize( + _currentElement.x, _currentElement.y, _currentElement.w, _currentElement.h, + currentIsTextElement === true ? _currentElement.angle() : 0 + ); + } + } + + pettanr.key.addKeyUpdateEvent( pettanr.view.EDITOR, 16, undefined, undefined, function( e){ + currentOperator !== null && currentOperator.onShiftUpdate && currentOperator.onShiftUpdate(); + }); + pettanr.key.addKeyUpdateEvent( pettanr.view.EDITOR, 17, undefined, undefined, function( e){ + currentOperator !== null && currentOperator.onCtrlUpdate && currentOperator.onCtrlUpdate(); + }); + pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 27, false, false, function( e){ + currentOperator !== null && currentOperator.onCancel && currentOperator.onCancel(); + currentOperator = null; + }); + return { + open: function(){ + this.hide(); + }, + close: function(){ + + }, + hide: function(){ + currentElement !== null && RESIZE_OPERATOR.hide(); + currentElement = null; + MOUSE_CURSOR( ''); + TAIL_OPERATOR.hide(); + CONSOLE_CONTROLER.hide(); + INFOMATION_WINDOW.update( null); + }, + resize: resize, + restoreState: function( arg){ + if( arg && arg.length !== 8) return; + var _currentElement = arg[ 0], + _x = arg[ 1], _y = arg[ 2], _w = arg[ 3], _h = arg[ 4], + _a = arg[ 5], + _flipV = arg[ 6], _flipH = arg[ 7]; + if( !_currentElement && !currentOperator) return; + _currentElement.type === PANEL_ELEMENT_TYPE_IMAGE ? + _currentElement.animate( _x, _y, _w, _h, _flipV, _flipH) : + _currentElement.animate( _x, _y, _w, _h, _a); + currentOperator !== null && currentOperator.onCancel && currentOperator.onCancel(); + currentOperator = null; + currentElement === _currentElement ? resize( _x, _y, _w, _h, _a) : show( _currentElement); + }, + saveStatus: function( startX, startY, startW, startH, startA, startFilpV, startFilpH){ + startX = startX !== undefined ? startX : currentx; + startY = startY !== undefined ? startY : currenty; + startW = startW !== undefined ? startW : currentw; + startH = startH !== undefined ? startH : currenth; + startA = startA !== undefined ? startA : angle; + startFilpV = startFilpV !== undefined ? startFilpV : flipV; + startFilpH = startFilpH !== undefined ? startFilpH : flipH; + currentElement && SAVE( COMIC_ELEMENT_OPERATION_MANAGER.restoreState, + [ currentElement, startX, startY, startW, startH, startA, startFilpV, startFilpH], + [ currentElement, currentx, currenty, currentw, currenth, angle, flipV, flipH] + ); + }, + busy: function(){ + return currentOperator !== null; + }, + hitTest: function( _mouseX, _mouseY, _comicElement ){ + var _x, _y, _w, _h; + if( _comicElement === currentElement){ + var _consoleX = CONSOLE_CONTROLER.x(); + _x = currentx +( _consoleX < 0 ? _consoleX : 0) -HIT_AREA; + _y = currenty -HIT_AREA; + var _consoleW = CONSOLE_CONTROLER.w(); + _w = ( _consoleW < currentw ? currentw : _consoleW) +HIT_AREA *2; + var _consoleY = CONSOLE_CONTROLER.y(); + _h = ( _consoleY < currenth ? currenth : _consoleY +CONSOLE_CONTROLER.h()) +HIT_AREA *2; + } else { + _x = _comicElement.x -HIT_AREA; + _y = _comicElement.y -HIT_AREA; + _w = _comicElement.w +HIT_AREA *2; + _h = _comicElement.h +HIT_AREA *2; + } + log.html( [ _x, _y, _w, _h ].join( ' ') ); + return _x <= _mouseX && _mouseX <= _x + _w && _y <= _mouseY && _mouseY <= _y + _h; + }, + onMouseDown: function( _currentElement, _mouseX, _mouseY){ + //show( _currentElement); + if( currentIsTextElement === true && TAIL_OPERATOR.onStart( _currentElement, _mouseX, _mouseY) === true){ + currentOperator = TAIL_OPERATOR; + } else + if( RESIZE_OPERATOR.onStart( _currentElement, _mouseX, _mouseY) === true){ + currentOperator = RESIZE_OPERATOR; + } else { + POSITION_OPERATOR.onStart( _currentElement, _mouseX, _mouseY) + currentOperator = POSITION_OPERATOR; + } + }, + onMouseMove: function( _currentElement, _mouseX, _mouseY){ + show( _currentElement); + if( currentOperator !== null){ + currentOperator.onDrag( _mouseX, _mouseY); + } else + if( currentElement !== null){ + CONSOLE_CONTROLER.onMouseMove( _mouseX -currentx, _mouseY -currenty); + if( currentIsTextElement === false || TAIL_OPERATOR.hitTest( _mouseX -currentx, _mouseY -currenty) === false){ + RESIZE_OPERATOR.index( _mouseX, _mouseY); + } + } + }, + onMouseUp: function( _currentElement, _mouseX, _mouseY){ + currentOperator !== null && currentOperator.onFinish(); + currentOperator = null; + } + } + })(); + /* + * // COMIC_ELEMENT_OPERATION_MANAGER + */ + + var AbstractComicElement = function( COMIC_ELM_TYPE ){ + this.type = COMIC_ELM_TYPE; + this.hitTest = function( _mouseX, _mouseY ){ + return COMIC_ELEMENT_OPERATION_MANAGER.hitTest( _mouseX, _mouseY, this ); + } + this.shift = function( _shiftX, _shiftY ){ + this.resize( this.x + _shiftX, this.y + _shiftY); + } + this.busy = function(){ + return COMIC_ELEMENT_OPERATION_MANAGER.busy(); + } + this.onMouseMove = function( _mouseX, _mouseY ){ + COMIC_ELEMENT_OPERATION_MANAGER.onMouseMove( this, _mouseX, _mouseY ); + } + this.onMouseUp = function( _mouseX, _mouseY ){ + COMIC_ELEMENT_OPERATION_MANAGER.onMouseUp( this, _mouseX, _mouseY ); + } + this.onMouseDown = function( _mouseX, _mouseY ){ + COMIC_ELEMENT_OPERATION_MANAGER.onMouseDown( this, _mouseX, _mouseY ); + } + }; + +/* -------------------------------------------------------------------------------------------- + * ImageElementClass + */ + var jqImageElementOrigin; + var ImageElementClass = function( data ){ + jqImageElementOrigin = jqImageElementOrigin || $( $( '#imgElementTemplete').remove().html()); + + var JQ_WRAPPER = jqImageElementOrigin.clone( true ), + SAVE = HISTORY_CONTROL.saveState, + HIT_AREA = MOUSE_HIT_AREA, + w = data.width, + h = data.height, + x, y, z, timing, + flipH = w < 0 ? -1 : 1, + flipV = h < 0 ? -1 : 1, + resourcePicture, + actualW, + actualH, + reversibleImage = null, + instance = this; + w = Math.floor( w ); + h = Math.floor( h ); + + function onAnimeComplete(){ + reversibleImage.resize( flipH * w, flipV * h ); + } + function updateResourcePicture( _resourcePicture ){ + resourcePicture = _resourcePicture; + + actualW = _resourcePicture.width; + actualH = _resourcePicture.height; + + var _reversibleImage = pettanr.image.createReversibleImage( + [ pettanr.CONST.RESOURCE_PICTURE_PATH, _resourcePicture.id, '.', _resourcePicture.ext ].join(''), + flipH * w, flipV * h + ); + if( reversibleImage !== null){ + JQ_WRAPPER.children( reversibleImage.elm ).replaceWith( _reversibleImage.elm ); + reversibleImage.destroy(); + } else { + JQ_WRAPPER.append( _reversibleImage.elm ); + } + reversibleImage = _reversibleImage; + } + /* global methods */ + this.$ = JQ_WRAPPER; + //this.x = x; + //this.y = y; + //this.w = w; + //this.h = h; + this.z = data.z; + this.timing = timing; + this.init = function(){ + updateResourcePicture( data.resource_picture ); + instance.resize( data.x, data.y, data.width, data.height ); + delete instance.init; + } + this.flip = function( _updateH, _updateV ){ + if( _updateH !== true && _updateV !== true ) return; + flipH = _updateH === true ? -flipH : flipH; + flipV = _updateV === true ? -flipV : flipV; + reversibleImage.resize( flipH * w, flipV * h ); + } + this.flipV = function(){ + return flipV; + } + this.flipH = function(){ + return flipH; + } + this.resourcePicture = function( _resourcePicture ){ + if( _resourcePicture && _resourcePicture !== resourcePicture ){ + SAVE( updateResourcePicture, resourcePicture, _resourcePicture ); + updateResourcePicture( _resourcePicture ); + } + return resourcePicture; + } + this.getArtistID = function(){ + return resourcePicture.artist_id || resourcePicture.artist.id || -1; + } + this.actualW = function(){ return actualW;} + this.actualH = function(){ return actualH;} + this.keepSize = false; + this.resize = function( _x, _y, _w, _h, animate ){ + instance.x = x = _x !== undefined ? _x : x; + instance.y = y = _y !== undefined ? _y : y; + instance.w = w = _w !== undefined ? _w : w; + instance.h = h = _h !== undefined ? _h : h; + JQ_WRAPPER[ animate === true ? 'animate' : 'css' ]( { + left: x, + top: y, + width: w, + height: h + }, 250, onAnimeComplete ); + animate !== true && onAnimeComplete(); + } + this.animate = function ( _x, _y, _w, _h, _flipH, _flipV ){ + flipH = _flipH !== undefined ? _flipH : flipH; + flipV = _flipV !== undefined ? _flipV : flipV; + instance.resize( _x, _y, _w, _h, true); + } + this.getAsHTML = function( isAbsoluteUrl, isXHTML ){ + return [ + '' : ' \/>' + ].join( ''); + } + this.getAsJsonString = function(){ + var cr = pettanr.LINE_FEED_CODE_TEXTAREA; + return [ + '"new', this.timing, '": {', cr, + '"resource_picture_id": 1,', cr, + '"x": ', x, ',', cr, + '"y": ', y, ',', cr, + '"z": ', this.z, ',', cr, + '"width": ', w, ',', cr, + '"height": ', h, ',', cr, + '"flipv": ', flipV === true ? 1 : 0, ',', cr, + '"fliph": ', flipH === true ? 1 : 0, ',', cr, + '"t": ', this.timing, cr, + '}' + ].join( ''); + } + this.destroy = function(){ + reversibleImage.destroy(); + JQ_WRAPPER.remove(); + JQ_WRAPPER = reversibleImage = resourcePicture = data = instance = SAVE = null; + delete this.destroy; + } + } + ImageElementClass.prototype = new AbstractComicElement( PANEL_ELEMENT_TYPE_IMAGE ); +/* + * / ImageElementClass + * -------------------------------------------------------------------------------------------- + */ + + +/* -------------------------------------------------------------------------------------------- + * TextElementClass + * + * type + * 0.none + * 1.speach balloon + * 2.think + * 3.bom + * 4.black-box( dq style) + * 5.blue-box( ff style) + * + */ + var jqTextElementOrigin; + var TextElementClass = function( data ){ + jqTextElementOrigin = jqTextElementOrigin || ( function(){ + var _OLD_IE = $( $( '#textElementTempleteForOldIE').remove().html()), + _MODERN = $( $( '#textElementTemplete').remove().html()); + return pettanr.ua.isIE === true && pettanr.ua.ieRenderingVersion < 8 ? _OLD_IE : _MODERN; + })(); + + var JQ_WRAPPER = jqTextElementOrigin.clone( true ), + TEXT_ELM = JQ_WRAPPER.find( 'td,.speach-inner').eq( 0), + HIT_AREA = MOUSE_HIT_AREA, + SAVE = HISTORY_CONTROL.saveState, + type = data.balloon_template_id, + text = ( function(){ + var _speachs = data.speaches_attributes; + for( var k in _speachs ){ + return _speachs[ k ].content || ''; + } + return ''; + }), + balloon = pettanr.balloon.createBalloon( data.width, data.height, data.tail, type ), + x, y, w, h, a, + instance = this; + + JQ_WRAPPER.find( 'img').eq( 0).replaceWith( balloon.elm ); + + function updateType( _type ){ + if( type !== _type ){ + type = _type || type; + balloon.type( type ); + } + } + function updateAngle( _a){ + if( _a !== undefined && a !== _a ){ + a = _a !== undefined ? _a : a; + balloon.angle( a ); + } + } + function updateText( _text){ + text = _text || text || ''; + TEXT_ELM.html( text ); + } + + /* global methods */ + this.$ = JQ_WRAPPER; + //this.x = x; + //this.y = y; + //this.w = w; + //this.h = h; + this.z = data.z; + this.timing = data.t; + this.init = function(){ + updateText(); + instance.resize( data.x, data.y, data.width, data.height, data.tail ); + delete instance.init; + } + this.angle = function( _a){ + _a !== undefined && instance.resize( undefined, undefined, undefined, undefined, _a); + return a; + } + this.text = function( _text){ + if( _text && text !== _text) { + SAVE( updateText, text || '', _text); + updateText( _text); + } + return text; + } + this.resize = function( _x, _y, _w, _h, _a, animate ){ + instance.x = x = _x !== undefined ? _x : x; + instance.y = y = _y !== undefined ? _y : y; + instance.w = w = _w !== undefined ? _w : w; + instance.h = h = _h !== undefined ? _h : h; + a = _a !== undefined ? _a : a; + + JQ_WRAPPER[ animate === true ? 'animate' : 'css']( { + left: x, + top: y, + width: w, + height: h + }, 250, + function(){ + balloon.resize( a, w, h); + } + ); + animate !== true && balloon.resize( a, w, h); + } + this.animate = function ( _x, _y, _w, _h, _a ){ + instance.resize( _x, _y, _w, _h, _a, true); + } + this.destroy = function(){ + JQ_WRAPPER.remove(); + balloon.destroy(); + balloon = null; + delete instance.destroy; + } + this.getAsJSON = function(){ + + } + this.getAsJsonString = function(){ + var cr = pettanr.LINE_FEED_CODE_TEXTAREA; + return [ + '"new', this.timing, '": {', cr, + '"balloon_template_id": ', 1, ',', cr, + '"system_picture_id": ', 1, ',', cr, + '"size": ', 1, ',', cr, + '"tail": ', a, ',', cr, + '"x": ', x, ',', cr, + '"y": ', y, ',', cr, + '"z": ', this.z, ',', cr, + '"t": ', this.timing, ',', cr, + '"width": ', w, ',', cr, + '"height": ', h, ',', cr, + '"speaches_attributes": {', cr, + '"newf', this.timing, '": {', cr, + '"content": "', text, '",', cr, + '"x": ', x, ',', cr, + '"y": ', y, ',', cr, + '"t": ', 0, ',', cr, + '"width": ', w, ',', cr, + '"height": ', h, cr, + '}', cr, + '}', cr, + '}' + ].join( ''); + } + this.getAsHTML = function( isAbsoluteUrl, isXHTML){ + var url = balloon.getURL(); + return [ + '' : ' \/>', + pettanr.LINE_FEED_CODE_TEXTAREA, + '
', text, '<\/span>', '<\/div>' + + ].join( ''); + } + this.getAsXML = function(){} + } + TextElementClass.prototype = new AbstractComicElement( PANEL_ELEMENT_TYPE_TEXT ); + +/* -------------------------------------------------------------------------------------------- + * COMIC_ELEMENT_CONTROL + * - mouseEventListener + */ + var COMIC_ELEMENT_CONTROL = ( function(){ + var SAVE = HISTORY_CONTROL.saveState, + ELM_CONTAINER = document.getElementById( 'comic-element-container'), + currentElement = null, + currentLockTest = false, + currentLock = false, + panelX, panelY, panelW, panelH, + startX, startY; + /* + * append, remove, replace + * + * comicElement には、z-position と dom-index がある。 + * z-position は 表示上の位置。大きいほど前に表示される( z-index) + * dom-index は 意味上の順番。htmlタグの登場順で、検索結果や音声読み上げブラウザで正しく意味が取れる順番。 + * + * editerでは、実際には z-index は使わず、htmlの順序で前後を表現する。 + * dom-index は、数値のみ保持して、投稿時にcomicElementを適宜に並び替える。 + * + * append comicElement + * 1. 新しい comicElement の z-position を得る + * 2. z の同じ comicElementを見つけ、その前に加える。または一番先頭へ。(COMIC_ELEMENT_ARRAY) + * zが大きいほど、COMIC_ELEMENT_ARRAYの先頭へ。 + * 3. dom位置は、COMIC_ELEMENT_ARRAY とは反対に、前のものほど後ろへ。 + * + * + * remove comicElement + * 1. remove + * 2. renumber z + */ + function appendComicElement( _comicElement ) { + var z = _comicElement.z, + l = COMIC_ELEMENT_ARRAY.length, + _jqElm = _comicElement.$.stop().css( { + filter: '', + opacity: '' + }); + if( typeof z !== 'number' || z < 0 || z >= l ){ + COMIC_ELEMENT_ARRAY.unshift( _comicElement ); + ELM_CONTAINER.appendChild( _jqElm.get( 0 )); + _jqElm.fadeIn(); + } else { + var insertIndex = 0; + for( var i = 0; i < l; ++i ){ + if( COMIC_ELEMENT_ARRAY[ i ].z <= z ){ + insertIndex = i; + break; + } + } + COMIC_ELEMENT_ARRAY[ insertIndex ].$.before( _jqElm.fadeIn() ); + COMIC_ELEMENT_ARRAY.splice( insertIndex, 0, _comicElement ); + } + renumber(); + } + function removeComicElement( _comicElement ) { + var l = COMIC_ELEMENT_ARRAY.length; + for( var i=0; i 0){ + _comicElm = COMIC_ELEMENT_ARRAY.shift(); + _comicElm.destroy && _comicElm.destroy(); + } + }, + remove: removeComicElement, + restore: restoreComicElement, + replace: replaceComicElement, + restoreReplace: restoreReplaceElement, + onPanelResize : function ( _panelX, _panelY, _panelW, _panelH, isResizerTopAction ){ + /* + * リサイズが、ResizerTopによって行われた場合、comicElementのyを動かして見かけ上動かないようにする。 + */ + if( isResizerTopAction === true){ + var _shiftX = _panelW -panelW, + _shiftY = _panelH -panelH, + l = COMIC_ELEMENT_ARRAY.length; + for( var i = 0; i < l; i++){ + COMIC_ELEMENT_ARRAY[ i].shift( _shiftX, _shiftY); + } + } + panelX = _panelX; + panelY = _panelY; + panelW = _panelW; + panelH = _panelH; + + ELM_CONTAINER.style.width = _panelW +'px'; + ELM_CONTAINER.style.height = _panelH +'px'; + ELM_CONTAINER.style.left = _panelX +'px'; + ELM_CONTAINER.style.top = _panelY +'px'; + }, + onMouseMove: function( _mouseX, _mouseY ){ + var l = COMIC_ELEMENT_ARRAY.length, + _x = _mouseX -panelX, + _y = _mouseY -panelY, + _elm = currentElement; + + if( _elm !== null){ + currentLockTest = currentLockTest === true && _x === 0 && _y === 0; + if( _elm.busy() === true ){ + _elm.onMouseMove( _x, _y); + return true; + } + if( _elm.hitTest( _x, _y) === true ){ + _elm.onMouseMove( _x, _y ); // cursor + return true; + } + if( currentLock === true){ + currentLockTest = true; + return true; + } + } + for( var i=0; i' + ].join( '') + ); + HTML_ARRAY.push( '
'); + + return HTML_ARRAY.join( pettanr.LINE_FEED_CODE_TEXTAREA); + }, + getAsJsonString: function(){ + var JSON_STRING_ARRAY = [], + IMAGE_ARRAY = [], + BALLOON_ARRAY = [], + l = COMIC_ELEMENT_ARRAY.length, + _timing = 0, + _comicElement, + cr = pettanr.LINE_FEED_CODE_TEXTAREA; + + while( IMAGE_ARRAY.length + BALLOON_ARRAY.length < l){ + _comicElement = getComicElementByTiming(); + if( _comicElement === null) break; + _comicElement.type === PANEL_ELEMENT_TYPE_IMAGE ? + IMAGE_ARRAY.push( _comicElement.getAsJsonString()) : + BALLOON_ARRAY.push( _comicElement.getAsJsonString()); + } + function getComicElementByTiming(){ + while( _timing < l *2){ + for(var i=0; i :resource_picture, :balloons => :speaches])# only: [:width, :height]) + @panel = Panel.find(params[:id], include: [:comic, :panel_pictures => :resource_picture, :balloons => :speeches])# only: [:width, :height]) respond_to do |format| format.html # show.html.erb diff --git a/app/controllers/speach_balloon_templates_controller.rb b/app/controllers/speach_balloon_templates_controller.rb deleted file mode 100644 index cb059917..00000000 --- a/app/controllers/speach_balloon_templates_controller.rb +++ /dev/null @@ -1,114 +0,0 @@ -class SpeachBalloonTemplatesController < ApplicationController - before_filter :authenticate_user!, :only => [:index, :show] - before_filter :authenticate_admin!, :only => [:list, :browse, :import, :destroy] - - private - - def validate_param(ft) - res = nil - bl = ft[:size_count].to_i - tl = ft[:tail_count].to_i - if bl * tl == ft[:balloon_templates_attributes].size - flag = [] - bl.times do |i| - flag[i] = [] - tl.times do |j| - flag[i][j] = true - end - end - ft[:balloon_templates_attributes].each do |k, t| - flag[t[:size].to_i - 1][t[:tail].to_i - 1] = nil - end - if flag.flatten.compact.size == 0 - else - res = "invalid variation" - end - else - res = "invalid template size" - end - res - end - - public - # GET /speach_balloon_templates - # GET /speach_balloon_templates.json - def index - @speach_balloon_templates = SpeachBalloon.all - - respond_to do |format| - format.html # index.html.erb - format.json { render json: @speach_balloon_templates } - end - end - - # GET /speach_balloon_templates/1 - # GET /speach_balloon_templates/1.json - def show - @speach_balloon_template = SpeachBalloon.find(params[:id], include: {:balloon_templates => :speach_templates}) - - respond_to do |format| - format.html # show.html.erb - format.json { - render :json => @speach_balloon_template.to_json(include: { - :balloon_templates => {:include => :speach_templates} - }) - } - format.jsonp { - render :json => "callback(" + @speach_balloon_template.to_json(include: { - :balloon_templates => {:include => :speach_templates} - }) + ")" - } - end - end - - def list - @speach_balloon_templates = SpeachBalloon.all - - respond_to do |format| - format.html { render layout: 'system' } - format.json { render json: @speach_balloon_templates } - end - end - - def browse - @speach_balloon_template = SpeachBalloon.find(params[:id]) - - respond_to do |format| - format.html { render layout: 'system' } - format.json { render json: @speach_balloon_template } - end - end - - # POST /speach_balloon_templates - # POST /speach_balloon_templates.json - def create - @speach_balloon_template = SpeachBalloon.new(params[:speach_balloon_template]) - if em = validate_param(params[:speach_balloon_template]) - respond_to do |format| - format.json { render json: em, status: :unprocessable_entity } - end - else - respond_to do |format| - if @speach_balloon_template.save - format.html { redirect_to @speach_balloon_template, notice: 'Speach balloon was successfully created.' } - format.json { render json: @speach_balloon_template, status: :created, location: @speach_balloon_template } - else - format.html { render action: "new" } - format.json { render json: @speach_balloon_template.errors, status: :unprocessable_entity } - end - end - end - end - - # DELETE /speach_balloon_templates/1 - # DELETE /speach_balloon_templates/1.json - def destroy - @speach_balloon_template = SpeachBalloon.find(params[:id]) - @speach_balloon_template.destroy - - respond_to do |format| - format.html { redirect_to speach_balloon_templates_url } - format.json { head :ok } - end - end -end diff --git a/app/controllers/speech_balloon_templates_controller.rb b/app/controllers/speech_balloon_templates_controller.rb new file mode 100644 index 00000000..d17ff326 --- /dev/null +++ b/app/controllers/speech_balloon_templates_controller.rb @@ -0,0 +1,114 @@ +class SpeechBalloonTemplatesController < ApplicationController + before_filter :authenticate_user!, :only => [:index, :show] + before_filter :authenticate_admin!, :only => [:list, :browse, :import, :destroy] + + private + + def validate_param(ft) + res = nil + bl = ft[:size_count].to_i + tl = ft[:tail_count].to_i + if bl * tl == ft[:balloon_templates_attributes].size + flag = [] + bl.times do |i| + flag[i] = [] + tl.times do |j| + flag[i][j] = true + end + end + ft[:balloon_templates_attributes].each do |k, t| + flag[t[:size].to_i - 1][t[:tail].to_i - 1] = nil + end + if flag.flatten.compact.size == 0 + else + res = "invalid variation" + end + else + res = "invalid template size" + end + res + end + + public + # GET /speech_balloon_templates + # GET /speech_balloon_templates.json + def index + @speech_balloon_templates = SpeechBalloon.all + + respond_to do |format| + format.html # index.html.erb + format.json { render json: @speech_balloon_templates } + end + end + + # GET /speech_balloon_templates/1 + # GET /speech_balloon_templates/1.json + def show + @speech_balloon_template = SpeechBalloon.find(params[:id], include: {:balloon_templates => :speech_templates}) + + respond_to do |format| + format.html # show.html.erb + format.json { + render :json => @speech_balloon_template.to_json(include: { + :balloon_templates => {:include => :speech_templates} + }) + } + format.jsonp { + render :json => "callback(" + @speech_balloon_template.to_json(include: { + :balloon_templates => {:include => :speech_templates} + }) + ")" + } + end + end + + def list + @speech_balloon_templates = SpeechBalloon.all + + respond_to do |format| + format.html { render layout: 'system' } + format.json { render json: @speech_balloon_templates } + end + end + + def browse + @speech_balloon_template = SpeechBalloon.find(params[:id]) + + respond_to do |format| + format.html { render layout: 'system' } + format.json { render json: @speech_balloon_template } + end + end + + # POST /speech_balloon_templates + # POST /speech_balloon_templates.json + def create + @speech_balloon_template = SpeechBalloon.new(params[:speech_balloon_template]) + if em = validate_param(params[:speech_balloon_template]) + respond_to do |format| + format.json { render json: em, status: :unprocessable_entity } + end + else + respond_to do |format| + if @speech_balloon_template.save + format.html { redirect_to @speech_balloon_template, notice: 'Speech balloon was successfully created.' } + format.json { render json: @speech_balloon_template, status: :created, location: @speech_balloon_template } + else + format.html { render action: "new" } + format.json { render json: @speech_balloon_template.errors, status: :unprocessable_entity } + end + end + end + end + + # DELETE /speech_balloon_templates/1 + # DELETE /speech_balloon_templates/1.json + def destroy + @speech_balloon_template = SpeechBalloon.find(params[:id]) + @speech_balloon_template.destroy + + respond_to do |format| + format.html { redirect_to speech_balloon_templates_url } + format.json { head :ok } + end + end +end diff --git a/app/controllers/speach_balloons_controller.rb b/app/controllers/speech_balloons_controller.rb similarity index 50% rename from app/controllers/speach_balloons_controller.rb rename to app/controllers/speech_balloons_controller.rb index c198b99c..36ab8392 100644 --- a/app/controllers/speach_balloons_controller.rb +++ b/app/controllers/speech_balloons_controller.rb @@ -1,4 +1,4 @@ -class SpeachBalloonsController < ApplicationController +class SpeechBalloonsController < ApplicationController before_filter :authenticate_user!, :only => [:index, :show] before_filter :authenticate_admin!, :only => [:list, :browse, :create, :update, :destroy] @@ -30,100 +30,100 @@ class SpeachBalloonsController < ApplicationController end public - # GET /speach_balloons - # GET /speach_balloons.json + # GET /speech_balloons + # GET /speech_balloons.json def index - @speach_balloons = SpeachBalloon.all + @speech_balloons = SpeechBalloon.all respond_to do |format| format.html # index.html.erb - format.json { render json: @speach_balloons } + format.json { render json: @speech_balloons } end end - # GET /speach_balloons/1 - # GET /speach_balloons/1.json + # GET /speech_balloons/1 + # GET /speech_balloons/1.json def show - @speach_balloon = SpeachBalloon.find(params[:id], include: {:balloon_templates => :speach_templates}) + @speech_balloon = SpeechBalloon.find(params[:id], include: {:balloon_templates => :speech_templates}) respond_to do |format| format.html # show.html.erb format.json { - render :json => @speach_balloon.to_json(include: { - :balloon_templates => {:include => :speach_templates} + render :json => @speech_balloon.to_json(include: { + :balloon_templates => {:include => :speech_templates} }) } format.jsonp { - render :json => "callback(" + @speach_balloon.to_json(include: { - :balloon_templates => {:include => :speach_templates} + render :json => "callback(" + @speech_balloon.to_json(include: { + :balloon_templates => {:include => :speech_templates} }) + ")" } end end def list - @speach_balloons = SpeachBalloon.all + @speech_balloons = SpeechBalloon.all respond_to do |format| format.html { render layout: 'system' } - format.json { render json: @speach_balloons } + format.json { render json: @speech_balloons } end end def browse - @speach_balloon = SpeachBalloon.find(params[:id]) + @speech_balloon = SpeechBalloon.find(params[:id]) respond_to do |format| format.html { render layout: 'system' } - format.json { render json: @speach_balloon } + format.json { render json: @speech_balloon } end end - # POST /speach_balloons - # POST /speach_balloons.json + # POST /speech_balloons + # POST /speech_balloons.json def create - @speach_balloon = SpeachBalloon.new(params[:speach_balloon]) - if em = validate_param(params[:speach_balloon]) + @speech_balloon = SpeechBalloon.new(params[:speech_balloon]) + if em = validate_param(params[:speech_balloon]) respond_to do |format| format.json { render json: em, status: :unprocessable_entity } end else respond_to do |format| - if @speach_balloon.save - format.html { redirect_to @speach_balloon, notice: 'Speach balloon was successfully created.' } - format.json { render json: @speach_balloon, status: :created, location: @speach_balloon } + if @speech_balloon.save + format.html { redirect_to @speech_balloon, notice: 'Speech balloon was successfully created.' } + format.json { render json: @speech_balloon, status: :created, location: @speech_balloon } else format.html { render action: "new" } - format.json { render json: @speach_balloon.errors, status: :unprocessable_entity } + format.json { render json: @speech_balloon.errors, status: :unprocessable_entity } end end end end - # PUT /speach_balloons/1 - # PUT /speach_balloons/1.json + # PUT /speech_balloons/1 + # PUT /speech_balloons/1.json def update - @speach_balloon = SpeachBalloon.find(params[:id]) + @speech_balloon = SpeechBalloon.find(params[:id]) respond_to do |format| - if @speach_balloon.update_attributes(params[:speach_balloon]) - format.html { redirect_to @speach_balloon, notice: 'Speach balloon was successfully updated.' } + if @speech_balloon.update_attributes(params[:speech_balloon]) + format.html { redirect_to @speech_balloon, notice: 'Speech balloon was successfully updated.' } format.json { head :ok } else format.html { render action: "edit" } - format.json { render json: @speach_balloon.errors, status: :unprocessable_entity } + format.json { render json: @speech_balloon.errors, status: :unprocessable_entity } end end end - # DELETE /speach_balloons/1 - # DELETE /speach_balloons/1.json + # DELETE /speech_balloons/1 + # DELETE /speech_balloons/1.json def destroy - @speach_balloon = SpeachBalloon.find(params[:id]) - @speach_balloon.destroy + @speech_balloon = SpeechBalloon.find(params[:id]) + @speech_balloon.destroy respond_to do |format| - format.html { redirect_to speach_balloons_url } + format.html { redirect_to speech_balloons_url } format.json { head :ok } end end diff --git a/app/controllers/speach_templates_controller.rb b/app/controllers/speech_templates_controller.rb similarity index 51% rename from app/controllers/speach_templates_controller.rb rename to app/controllers/speech_templates_controller.rb index df60b690..60ac6c4d 100644 --- a/app/controllers/speach_templates_controller.rb +++ b/app/controllers/speech_templates_controller.rb @@ -1,24 +1,24 @@ -class SpeachTemplatesController < ApplicationController +class SpeechTemplatesController < ApplicationController before_filter :authenticate_user!, :only => [:index, :show] before_filter :authenticate_admin!, :only => [:list, :browse] - # GET /speach_templates - # GET /speach_templates.json + # GET /speech_templates + # GET /speech_templates.json def index - @speach_templates = SpeachTemplate.all + @speech_templates = SpeechTemplate.all respond_to do |format| format.html # index.html.erb - format.json { render json: @speach_templates } + format.json { render json: @speech_templates } end end def list - @speach_templates = SpeachTemplate.all + @speech_templates = SpeechTemplate.all respond_to do |format| format.html { render layout: 'system' } - format.json { render json: @speach_templates } + format.json { render json: @speech_templates } end end diff --git a/app/controllers/speaches_controller.rb b/app/controllers/speeches_controller.rb similarity index 57% rename from app/controllers/speaches_controller.rb rename to app/controllers/speeches_controller.rb index 35a55950..7e53b73f 100644 --- a/app/controllers/speaches_controller.rb +++ b/app/controllers/speeches_controller.rb @@ -1,24 +1,24 @@ -class SpeachesController < ApplicationController +class SpeechesController < ApplicationController before_filter :authenticate_user!, :only => [:index, :show] before_filter :authenticate_admin!, :only => [:list, :browse] - # GET /speaches - # GET /speaches.json + # GET /speeches + # GET /speeches.json def index - @speaches = Speach.all + @speeches = Speech.all respond_to do |format| format.html # index.html.erb - format.json { render json: @speaches } + format.json { render json: @speeches } end end def list - @speaches = Speach.all + @speeches = Speech.all respond_to do |format| format.html { render layout: 'system' } - format.json { render json: @speaches } + format.json { render json: @speeches } end end end diff --git a/app/helpers/speach_balloon_templates_helper.rb b/app/helpers/speach_balloon_templates_helper.rb deleted file mode 100644 index 9ba05085..00000000 --- a/app/helpers/speach_balloon_templates_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module SpeachBalloonTemplatesHelper -end diff --git a/app/helpers/speach_balloons_helper.rb b/app/helpers/speach_balloons_helper.rb deleted file mode 100644 index ca421585..00000000 --- a/app/helpers/speach_balloons_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module SpeachBalloonsHelper -end diff --git a/app/helpers/speach_templates_helper.rb b/app/helpers/speach_templates_helper.rb deleted file mode 100644 index 51b45808..00000000 --- a/app/helpers/speach_templates_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module SpeachTemplatesHelper -end diff --git a/app/helpers/speaches_helper.rb b/app/helpers/speaches_helper.rb deleted file mode 100644 index c4b52bb4..00000000 --- a/app/helpers/speaches_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module SpeachesHelper -end diff --git a/app/helpers/speech_balloon_templates_helper.rb b/app/helpers/speech_balloon_templates_helper.rb new file mode 100644 index 00000000..992ab1e3 --- /dev/null +++ b/app/helpers/speech_balloon_templates_helper.rb @@ -0,0 +1,2 @@ +module SpeechBalloonTemplatesHelper +end diff --git a/app/helpers/speech_balloons_helper.rb b/app/helpers/speech_balloons_helper.rb new file mode 100644 index 00000000..03c3d677 --- /dev/null +++ b/app/helpers/speech_balloons_helper.rb @@ -0,0 +1,2 @@ +module SpeechBalloonsHelper +end diff --git a/app/helpers/speech_templates_helper.rb b/app/helpers/speech_templates_helper.rb new file mode 100644 index 00000000..3091a5da --- /dev/null +++ b/app/helpers/speech_templates_helper.rb @@ -0,0 +1,2 @@ +module SpeechTemplatesHelper +end diff --git a/app/helpers/speeches_helper.rb b/app/helpers/speeches_helper.rb new file mode 100644 index 00000000..0f79a3b4 --- /dev/null +++ b/app/helpers/speeches_helper.rb @@ -0,0 +1,2 @@ +module SpeechesHelper +end diff --git a/app/models/balloon.rb b/app/models/balloon.rb index ee183ccf..391b933f 100644 --- a/app/models/balloon.rb +++ b/app/models/balloon.rb @@ -1,8 +1,8 @@ class Balloon < ActiveRecord::Base - has_many :speaches + has_many :speeches belongs_to :panel belongs_to :system_picture - accepts_nested_attributes_for :speaches + accepts_nested_attributes_for :speeches def url '/system_pictures/' + self.system_picture.filename diff --git a/app/models/balloon_template.rb b/app/models/balloon_template.rb index 7f32278f..c050ed9d 100644 --- a/app/models/balloon_template.rb +++ b/app/models/balloon_template.rb @@ -1,6 +1,6 @@ class BalloonTemplate < ActiveRecord::Base - belongs_to :speach_balloon - has_many :speach_templates, :dependent => :destroy + belongs_to :speech_balloon + has_many :speech_templates, :dependent => :destroy belongs_to :system_picture - accepts_nested_attributes_for :speach_templates + accepts_nested_attributes_for :speech_templates end diff --git a/app/models/comic.rb b/app/models/comic.rb index 3dc6baef..6db937d2 100644 --- a/app/models/comic.rb +++ b/app/models/comic.rb @@ -113,9 +113,9 @@ class Comic < ActiveRecord::Base :author, :panels => [ :panel_pictures => :resource_picture, - :balloons => :speaches + :balloons => :speeches ] - ], order: 'panels.t, speaches.t') + ], order: 'panels.t, speeches.t') end def to_json_play diff --git a/app/models/panel.rb b/app/models/panel.rb index 2d7de5b8..45090eac 100644 --- a/app/models/panel.rb +++ b/app/models/panel.rb @@ -116,7 +116,7 @@ class Panel < ActiveRecord::Base :panel_pictures => { :resource_picture => {:artist => {}, :license => {}} }, - :balloons => {:speaches => {}}, + :balloons => {:speeches => {}}, :author => {} }} end @@ -127,7 +127,7 @@ class Panel < ActiveRecord::Base :panel_pictures => { :resource_picture => {:artist => {}, :license => {}} }, - :balloons => {:speaches => {}}, + :balloons => {:speeches => {}}, :author => {} }} end @@ -144,7 +144,7 @@ class Panel < ActiveRecord::Base :panel_pictures => { :resource_picture => {:artist => {}, :license => {}} }, - :balloons => {:speaches => {}}, + :balloons => {:speeches => {}}, :author => {} } res.merge!(opt[:include]) if opt[:include] @@ -157,7 +157,7 @@ class Panel < ActiveRecord::Base :panel_pictures => { :resource_picture => {:artist => {}, :license => {}} }, - :balloons => {:speaches => {}}, + :balloons => {:speeches => {}}, :author => {} }} end @@ -197,7 +197,7 @@ class Panel < ActiveRecord::Base res[elm.t] = elm.to_json({:include => :resource_picture}) end if elm.kind_of?(Balloon) - res[elm.t] = elm.to_json({:include => :speaches}) + res[elm.t] = elm.to_json({:include => :speeches}) end end res diff --git a/app/models/speach.rb b/app/models/speach.rb deleted file mode 100644 index 2346626e..00000000 --- a/app/models/speach.rb +++ /dev/null @@ -1,3 +0,0 @@ -class Speach < ActiveRecord::Base - belongs_to :balloon -end diff --git a/app/models/speach_balloon_template.rb b/app/models/speach_balloon_template.rb deleted file mode 100644 index 3af508ba..00000000 --- a/app/models/speach_balloon_template.rb +++ /dev/null @@ -1,12 +0,0 @@ -class SpeachBalloonTemplate < ActiveRecord::Base - has_many :balloon_templates, :dependent => :destroy - has_many :speach_templates, :dependent => :destroy - accepts_nested_attributes_for :balloon_templates - accepts_nested_attributes_for :speach_templates - before_create :supply_t - - def supply_t - self.t = SpeachBalloon.maximum(:t).to_i + 1 - end - -end diff --git a/app/models/speach_template.rb b/app/models/speach_template.rb deleted file mode 100644 index b44ebed6..00000000 --- a/app/models/speach_template.rb +++ /dev/null @@ -1,3 +0,0 @@ -class SpeachTemplate < ActiveRecord::Base - belongs_to :balloon_template -end diff --git a/app/models/speech.rb b/app/models/speech.rb new file mode 100644 index 00000000..fc1ff5b9 --- /dev/null +++ b/app/models/speech.rb @@ -0,0 +1,3 @@ +class Speech < ActiveRecord::Base + belongs_to :balloon +end diff --git a/app/models/speach_balloon.rb b/app/models/speech_balloon.rb similarity index 64% rename from app/models/speach_balloon.rb rename to app/models/speech_balloon.rb index 58585628..89e3454a 100644 --- a/app/models/speach_balloon.rb +++ b/app/models/speech_balloon.rb @@ -1,10 +1,10 @@ -class SpeachBalloon < ActiveRecord::Base +class SpeechBalloon < ActiveRecord::Base has_many :balloon_templates, :dependent => :destroy accepts_nested_attributes_for :balloon_templates before_create :supply_t def supply_t - self.t = SpeachBalloon.maximum(:t).to_i + 1 + self.t = SpeechBalloon.maximum(:t).to_i + 1 end end diff --git a/app/models/speech_balloon_template.rb b/app/models/speech_balloon_template.rb new file mode 100644 index 00000000..de6d053c --- /dev/null +++ b/app/models/speech_balloon_template.rb @@ -0,0 +1,12 @@ +class SpeechBalloonTemplate < ActiveRecord::Base + has_many :balloon_templates, :dependent => :destroy + has_many :speech_templates, :dependent => :destroy + accepts_nested_attributes_for :balloon_templates + accepts_nested_attributes_for :speech_templates + before_create :supply_t + + def supply_t + self.t = SpeechBalloon.maximum(:t).to_i + 1 + end + +end diff --git a/app/models/speech_template.rb b/app/models/speech_template.rb new file mode 100644 index 00000000..d0871b3e --- /dev/null +++ b/app/models/speech_template.rb @@ -0,0 +1,3 @@ +class SpeechTemplate < ActiveRecord::Base + belongs_to :balloon_template +end diff --git a/app/views/balloon_templates/index.html.erb b/app/views/balloon_templates/index.html.erb index 7e59e7d0..93b1b812 100644 --- a/app/views/balloon_templates/index.html.erb +++ b/app/views/balloon_templates/index.html.erb @@ -2,7 +2,7 @@ - + @@ -14,7 +14,7 @@ <% @balloon_templates.each do |balloon_template| %> - + diff --git a/app/views/balloon_templates/list.html.erb b/app/views/balloon_templates/list.html.erb index 20913519..7a836143 100644 --- a/app/views/balloon_templates/list.html.erb +++ b/app/views/balloon_templates/list.html.erb @@ -3,7 +3,7 @@
speach balloonspeech balloon system_picture Tail size
<%= balloon_template.speach_balloon_id %><%= balloon_template.speech_balloon_id %> <%= balloon_template.system_picture_id %> <%= balloon_template.tail %> <%= balloon_template.size %>
- + @@ -18,7 +18,7 @@ <% @balloon_templates.each do |balloon_template| %> - + diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index b78281b9..1b97e714 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -179,8 +179,8 @@ @@ -188,7 +188,7 @@
idspeach balloonspeech balloon system_picture Tail size
<%= link_to balloon_template.id, :action => :browse, :id => balloon_template.id %><%= link_to balloon_template.speach_balloon_id, :controller => 'speach_balloons', :action => :browse, :id => balloon_template.speach_balloon_id %><%= link_to balloon_template.speech_balloon_id, :controller => 'speech_balloons', :action => :browse, :id => balloon_template.speech_balloon_id %> <%= link_to balloon_template.system_picture_id, :controller => 'system_pictures', :action => :browse, :id => balloon_template.system_picture_id %> <%= balloon_template.tail %> <%= balloon_template.size %>