| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514 |
- /**
- * @fileoverview
- * - Trex.Toolbar
- */
- /**
- * Trex.Toolbar Class
- * @class
- * @param {Object} editor
- * @param {Object} config
- */
- Trex.Toolbar = Trex.Class.create(/** @lends Trex.Toolbar.prototype */{
- /** @ignore */
- $mixins: [
- Trex.I.JobObservable
- ],
- /**
- * Toolbar Dom Element
- */
- el: _NULL,
- /**
- * Tools List
- */
- tools: _NULL,
- initialize: function(editor, rootConfig) {
- this.canvas = editor.getCanvas();
-
- var _initializedId = rootConfig.initializedId || "";
- this.el = $must("tx_toolbar_basic" + _initializedId, "Trex.Toolbar");
- },
- /**
- * Toolbar의 tool을 비활성화 시킨다.
- * @function
- * @example
- * Editor.getToolbar().disableToolbar();
- */
- disableToolbar: function(){
- var _tools = this.tools;
- for (var _name in _tools) {
- if (_tools[_name].button) {
- _tools[_name].button.disable();
- }
- }
- },
- /**
- * 현재 toolbar의 상태를 serializing한다.
- * @function
- * @returns {object}
- */
- serializeToolValues : function(){
- var _tools = this.tools;
- var result = {};
- for(var name in _tools){
- var _tool = _tools[name];
- result[name] = _tool.button.lastValue;
- }
- return result;
- },
- widgetSeq:0,
- makeWidget: function(button, menu, handler) {
- var _toolbar = this;
- var _canvas = this.canvas;
- var _dummyToolClass = new (function() {
- this.identity = 'widget' + (++_toolbar.widgetSeq);
- this.wysiwygonly = _TRUE;
- this.menuFoldAuto = _TRUE;
- this.canvas = _canvas;
- this.toolbar = _toolbar;
- })();
-
- Trex.Tool.prototype.weave.bind(_dummyToolClass)(
- button,
- menu,
- handler
- );
-
- this.tools[_dummyToolClass.identity] = _dummyToolClass;
- return _dummyToolClass;
- }
- });
- Trex.install("editor.getTool",
- function(editor, toolbar) {
- var _tools = toolbar.tools = {};
-
- /**
- * memberOf Editor.prototype
- * @param {Object} name
- */
- editor.getTool = function(name) {
- if(_tools[name] != _NULL) {
- return _tools[name];
- } else if(arguments.length == 0){
- return _tools;
- }else{
- return _NULL;
- }
- };
- }
- );
- Trex.register("new tools",
- function(editor, toolbar, sidebar, canvas, config) {
- var _tools = toolbar.tools;
-
- var _initializedId = config.initializedId || "";
- for(var item in Trex.Tool) {
- var _name = Trex.Tool[item]['__Identity'];
- if(_name){
- var cfg = TrexConfig.getTool(_name, config);
- cfg.initializedId = _initializedId;
- if (Trex.available(cfg, _name + _initializedId)) {
- _tools[_name] = new Trex.Tool[item](editor, toolbar, cfg);
- }
- }
- }
- if(!!canvas.config.readonly) {
- toolbar.disableToolbar();
- }
- }
- );
- Trex.module("bind events with tools",
- function(editor, toolbar, sidebar, canvas) {
- var _tools = toolbar.tools;
-
- var disableToolOnMobile = function () {
- var isMobile, name, tool, btn;
- isMobile = $tx.ios || $tx.android;
- if (!isMobile) {
- return;
- }
- for (name in _tools) {
- tool = _tools[name];
- if (tool.disabledonmobile) {
- btn = tool.button;
- btn.disable();
- }
- }
- };
- disableToolOnMobile();
-
- var _changeMode = function(from, to){
- if (from == to) {
- return;
- }
- for (var _name in _tools) {
- var _tool = _tools[_name];
- var _btn = _tool.button;
- if (Trex.Canvas.__WYSIWYG_MODE == to) {
- _btn.enable();
- } else if (Trex.Canvas.__WYSIWYG_MODE == from) {
- if (_tool.wysiwygonly) {
- _btn.disable();
- } else {
- _btn.enable();
- }
- }
- }
- disableToolOnMobile();
- };
- canvas.observeJob(Trex.Ev.__CANVAS_MODE_CHANGE, _changeMode);
- canvas.observeJob(Trex.Ev.__CANVAS_MODE_INITIALIZE, _changeMode);
-
- var _releaseTools = function(identity) {
- for(var _name in _tools) {
- var _tool = _tools[_name];
- if(identity != _tool.identity) {
- if (_tool.button) {
- _tool.button.release();
- _tool.button.decreaseZindex();
- }
- if(_tool.menu && _tool.menuFoldAuto) {
- _tool.menu.release();
- }
- }
- }
- };
- canvas.observeJob(Trex.Ev.__CANVAS_PANEL_CLICK, _releaseTools);
- canvas.observeJob(Trex.Ev.__CANVAS_SOURCE_PANEL_CLICK, _releaseTools);
- canvas.observeJob(Trex.Ev.__CANVAS_TEXT_PANEL_CLICK, _releaseTools);
-
- toolbar.observeJob(Trex.Ev.__TOOL_CLICK, _releaseTools);
- canvas.observeKey({ // Esc
- ctrlKey: _FALSE,
- altKey: _FALSE,
- shiftKey: _FALSE,
- keyCode: 27
- }, _releaseTools);
- editor.observeKey({ // Esc
- ctrlKey: _FALSE,
- altKey: _FALSE,
- shiftKey: _FALSE,
- keyCode: 27
- }, _releaseTools);
-
- $tx.observe(_DOC, 'click',
- function(e){
- var _el = $tx.element(e);
- var _class = [ 'tx-sidebar', 'tx-toolbar-basic' ,'tx-toolbar-advanced',
- 'tx-sidebar-boundary', 'tx-toolbar-boundary', 'tx-toolbar-boundary'];
- if (Trex.Util.getMatchedClassName(_el, _class)) {
- _releaseTools("-");
- }
- }
- , _FALSE);
- var _shouldCloseMenus = function () {
- editor.fireJobs(Trex.Ev.__SHOULD_CLOSE_MENUS);
- };
- toolbar.observeJob(Trex.Ev.__TOOL_CLICK, _shouldCloseMenus);
- }
- );
- /**
- * Tool 클래스의 추상 부모클래스로 각각의 tool들은 이 클래스를 상속받아야 하고,
- * 'oninitialized' 함수를 구현해야한다.
- *
- * @abstract
- * @class
- * @param {Object} editor
- * @param {Object} toolbar
- * @param {Object} config
- *
- * @example
- * Trex.Tool.Example = Trex.Class.create({
- * $const: {
- * __Identity: 'example'
- * },
- * $extend: Trex.Tool,
- * oninitialized: function(config) {
- * var _tool = this;
- *
- * this.weave.bind(this)(
- * new Trex.Button(this.buttonCfg),
- * new Trex.Menu(this.menuCfg),
- * function(data) {
- * //TODO
- * }
- * );
- * }
- * });
- */
- Trex.Tool = Trex.Class.draft(/** @lends Trex.Tool.prototype */{
- /**
- * tool identifier. 유일해야한다.
- * @private
- */
- identity: _NULL,
- /**
- * button 객체
- */
- button: _NULL,
- /**
- * menu 객체
- */
- menu: _NULL,
- initialize: function(editor, toolbar, config) {
- if(!this.constructor.__Identity) {
- throw new Error("[Exception]Trex.Tool : not implement const(__Identity)");
- }
- this.identity = this.constructor.__Identity;
- if(!editor) {
- throw new Error("[Exception]Trex.Tool : not exist argument(editor)");
- }
- /**
- * editor 객체
- * @private
- */
- this.editor = editor;
- /**
- * toolbar 객체
- * @private
- */
- this.toolbar = toolbar;
- /**
- * canvas 객체
- * @private
- */
- this.canvas = editor.getCanvas();
- /**
- * 해당 tool 설정값
- * @private
- */
- this.config = config;
- this.wysiwygonly = ((config.wysiwygonly != _NULL)? config.wysiwygonly: _TRUE);
- this.menuFoldAuto = ((config.menuFoldAuto != _NULL)? config.menuFoldAuto: _TRUE);
- if (config.disabledonmobile != _NULL) {
- this.disabledonmobile = config.disabledonmobile;
- }
-
- /**
- * 버튼을 생성할 때 필요한 설정값
- * @private
- */
- this.buttonCfg = TrexConfig.merge({
- id: "tx_" + this.identity
- }, config);
-
- /**
- * 메뉴를 생성할 때 필요한 설정값
- * @private
- */
- this.menuCfg = TrexConfig.merge({
- id: "tx_" + this.identity + "_menu"
- }, config);
-
- this.oninitialized.bind(this)(config);
- },
- /**
- * tool 객체를 초기화하는 마지막 단계에서 호출되는 함수로,
- * tool 클래스를 상속받는 tool에서 반드시 구현해야 한다.
- *
- * @abstract
- * @private
- * @function
- */
- oninitialized: function() {
- throw new Error("[Exception]Trex.Tool : not implements function(oninitialized)");
- },
- /**
- * 보통 tool은 버튼과 메뉴로 구성되는데, 이 함수에서 그 둘 사이의 연결을 해준다.<br/>
- * menu가 없으면 버튼을 클릭할 때 execHandler가 실행되고,
- * menu가 있으면 버튼을 클릭할 때 menu가 보이며,
- * menu에서 특정 값을 선택하면 그 값을 가지고 execHandler가 실행된다.
- *
- * @function
- * @private
- * @param {Object} button - 버튼 객체
- * @param {Object} menu - 메뉴 객체 optional
- * @param {Function} execHandler
- * @param {Function} initHandler - optional
- *
- * @example
- * this.weave.bind(this)(
- * new Trex.Button(this.buttonCfg),
- * new Trex.Menu(this.menuCfg),
- * function(data) {
- * //TODO
- * });
- * }
- */
- weave: function(button, menu, execHandler, initHandler) {
- var _tool = this;
- var _identity = this.identity;
- var _toolbar = this.toolbar;
- var _canvas = this.canvas;
-
- this.button = button;
- button.tool = this;
- var cmd = _NULL;
- if(!menu){
- button.setCommand(
- cmd = function(){
- _toolbar.fireJobs(Trex.Ev.__TOOL_CLICK, _identity);
- return execHandler.apply(_tool, arguments);
- }
- );
- }else{
- this.menu = menu;
- menu.tool = this;
-
- menu.initHandler = initHandler || function(){};
- menu.cancelHandler = function(){ button.setState(_FALSE); };
-
- menu.setCommand(
- cmd = function() {
- var args = arguments;
- var success = execHandler.apply(_tool, args);
- //handler에서 $stop 을 반환하면 버튼 값을 메뉴에서 선택한 값으로 안바꿈..
- if (success === $stop) {
- button.normalState.apply(button, args);
- } else {
- button.updateAfterCommand.apply(button, args);
- }
- return success;
- }
- );
- button.setCommand(
- function(ev) {
- _toolbar.fireJobs(Trex.Ev.__TOOL_CLICK, _identity, ev);
- if(!button.isPushed()) {
- var _lastvalue = button.getValue();
- button.increaseZindex();
- menu.show(_lastvalue);
- } else {
- menu.hide();
- if ($tx.msie) {
- var _processor = _canvas.getProcessor();
- if (_processor.restoreRange) {
- setTimeout(function () {
- _processor.restoreRange();
- }, 0);
- }
- }
- }
- return _TRUE;
- }
- );
- menu.observeJob(Trex.Ev.__MENU_LAYER_SHOW, function(ev){
- _toolbar.fireJobs(Trex.Ev.__MENU_LAYER_SHOW, ev);
- });
- menu.observeJob(Trex.Ev.__MENU_LAYER_HIDE, function(ev){
- _toolbar.fireJobs(Trex.Ev.__MENU_LAYER_HIDE, ev);
- });
- menu.observeJob(Trex.Ev.__MENU_LAYER_CHANGE_SIZE, function(ev){
- _toolbar.fireJobs(Trex.Ev.__MENU_LAYER_CHANGE_SIZE, ev);
- });
- }
- this.execute = cmd;
- },
- /**
- * 연결된 버튼과 메뉴 레이어와의 관계를 모두 해제한다.
- * 일반적은 경우에는 필요하지 않고 async를 위한 tool에만 weave 구문 상위에 추가한다.
- * @function
- */
- resetWeave: function(){
- this.button.removeHandler();
- this.button.normalState();
- this.button = _NULL;
- this.menu = _NULL;
- this.execute = _NULL;
- },
- /**
- * 활성화 상태를 강제한다.
- * async tool 에서 클릭후 자동 활성화를 위함.
- * @function
- */
- forceActivate: function(){
- if( this.button && this.menu ){
- this.button.pushedState();
- this.button.increaseZindex();
- this.menu.show();
- }
- },
- bindKeyboard: function(keys, execHandler) {
- var toolbar = this.toolbar;
- var identity = this.identity;
- this.canvas.observeKey(keys, function(ev) {
- execHandler(ev);
- toolbar.fireJobs(Trex.Ev.__TOOL_SHORTCUT_KEY, identity);
- });
- }
- });
- Trex.AsyncTool = Trex.Class.draft(/** @lends Trex.Tool.prototype */{
- $extend: Trex.Tool,
- oninitialized: function() {
- this.loaded = false;
- throw new Error("[Exception]Trex.AsyncTool : not implements function(oninitialized)");
- },
- onLoadModule: function() {
- var self = this;
- var url = this.config.asyncUrl;
- if (/^(?:\/\/)|(?:\w+:\/\/)/.test(url) === false) {
- url = this.getJSBasePath() + url;
- }
- if (EditorJSLoader.getOption('environment') == 'development') {
- var d = (new Date()).getTime();
- if (url.indexOf('?') === -1) {
- url += '?dummy=' + d;
- } else {
- url += '&dummy=' + d;
- }
- }
- Editor.editorForAsyncLoad = this.editor;
- EditorJSLoader.asyncLoadModule({
- url: TrexConfig.getUrl(url),
- callback: function(){
- self.loaded = true;
- }
- });
- },
- getJSBasePath: function() {
- var basePath;
- try {
- basePath = EditorJSLoader.getJSBasePath("editor.js");
- } catch (e) {
- basePath = EditorJSLoader.getJSBasePath();
- }
- return basePath;
- }
- });
- Trex.I.Tool = {};
- Trex.I.Tool.QueryStyle = {};
- Trex.I.Tool.QueryStyle.Standard = Trex.Mixin.create({
- queryNodeStyle: function(currentNode, cssPropertyName, queryCommandName, matchTagName) {
- return $tx.getStyle(currentNode, cssPropertyName).include(queryCommandName);
- }
- });
- Trex.I.Tool.QueryStyle.Gecko = Trex.Mixin.create({
- queryNodeStyle: function(currentNode, cssPropertyName, queryCommandName, matchTagName) {
- var tempNode = currentNode;
- var isInclude = _FALSE;
- while(tempNode && !$tom.isBody(tempNode) && !isInclude) {
- if ($tom.isTagName(tempNode, matchTagName)) {
- isInclude = _TRUE;
- } else {
- isInclude = $tx.getStyle(currentNode, cssPropertyName).include(queryCommandName);
- }
- // move to parent
- tempNode = tempNode.parentNode;
- }
- return isInclude;
- }
- });
|